У меня возникли проблемы с алгоритмом затенения Фонга.Кажется, что нормали выключены, и я всегда получаю плоскую заштрихованную поверхность.
Я реализую отложенный рендеринг, поэтому в моем проходе геометрии я сохраняю положение вершины и нормали в текстурах.На этапе освещения я выводил нормали в виде цвета, чтобы проверить их «значения».
РЕДАКТИРОВАТЬ 1 Мой Gbuffer использует две текстуры для хранения позиций и нормалей.Обе текстуры используют формат GL_RGB16F.
РЕДАКТИРОВАТЬ 5 Как вы можете видеть на этом изображении
Я не получаю элегантного цветового перехода.Голова слева - результат моего двигателя, справа вы можете увидеть ту же модель в Blender.В Blender нормали (синим цветом) выглядят корректно (без дубликатов и т. Д.), Но в моем движке они ведут себя как нормаль лица (каждые 4 показывают в одном направлении).Я использую Assimp для загрузки моделей и при импорте их включаю флаг aiProcess_GenSmoothNormals
.
Вершинный шейдер с геометрическим проходом:
#version 440 core
layout (location = 0) in vec4 positionOS;
layout (location = 1) in vec3 normalOS;
layout (location = 2) in vec2 uv;
out VertexData
{
vec3 PositionVS;
vec3 NormalVS;
vec2 UV;
} vs_out;
uniform mat3 normalViewMatrix;
uniform mat4 modelViewMatrix;
struct Camera
{
mat4 viewMatrix;
mat4 projMatrix;
};
layout(std140, binding = 0) uniform CameraBlock
{
Camera cam;
};
void main()
{
vec4 positionVS = modelViewMatrix * positionOS;
vs_out.PositionVS = positionVS.xyz;
vs_out.NormalVS = normalViewMatrix * normalOS;
vs_out.UV = uv;
gl_Position = cam.projMatrix * positionVS;
}
Фрагментный шейдер с геометрическим проходом:
#version 440 core
layout (location = 0) out vec3 PositionVS;
layout (location = 1) out vec3 NormalVS;
in VertexData
{
vec3 PositionVS;
vec3 NormalVS;
vec2 UV;
} vs_in;
void main()
{
PositionVS = vs_in.PositionVS;
NormalVS = normalize(vs_in.NormalVS);
}
РЕДАКТИРОВАТЬ 4 Чтение значений вершин из Assimp (aiMesh)
void MeshLoader::prepareMesh(const aiMesh & mesh)
{
{ // vertices
for (int i = 0; i < mesh.mNumVertices; i++) {
if (mesh.HasPositions()) {
glm::vec3 position = glm::vec3(mesh.mVertices[i].x, mesh.mVertices[i].y, mesh.mVertices[i].z);
positions.emplace_back(position.x, position.y, position.z, 1);
}
if (mesh.HasNormals()) {
normals.emplace_back(mesh.mNormals[i].x, mesh.mNormals[i].y, mesh.mNormals[i].z);
}
if (mesh.HasTangentsAndBitangents()) {
tangents.emplace_back(mesh.mTangents[i].x, mesh.mTangents[i].y, mesh.mTangents[i].z);
bitangents.emplace_back(mesh.mBitangents[i].x, mesh.mBitangents[i].y, mesh.mBitangents[i].z);
}
if (mesh.HasTextureCoords(0)) {
uvs.emplace_back(mesh.mTextureCoords[0][i].x, mesh.mTextureCoords[0][i].y);
}
}
}
{ // polygons
numFaces = mesh.mNumFaces;
for (int i = 0; i < numFaces; i++) {
indices.push_back(mesh.mFaces[i].mIndices[0]);
indices.push_back(mesh.mFaces[i].mIndices[1]);
indices.push_back(mesh.mFaces[i].mIndices[2]);
}
}
}
Я хотел бы найти решение для этого беспорядка.Я знаю, что нормали - это проблема, но я не могу понять, почему.
РЕДАКТИРОВАТЬ 2 По виду сферы это похоже на проблему интерполяции, отсюда и код шейдера выше.Если шейдеры верны, то, возможно, проблема связана с классом импорта?
РЕДАКТИРОВАТЬ 3 Я также реализовал версию рендеринга вперед и отображаю нормали в цвете, но я получаю тот же результат, что и вотложенная версия.