目前,我正在在 Blender 中创建并通过 assimp 加载的 3D 场景中设置一些照明,并设置了以下选项:
aiProcess_GenSmoothNormals | aiProcess_Triangulate | aiProcess_CalcTangentSpace | aiProcess_FlipUVs
目前,我在程序中遇到了一个非常奇怪的故障。我正在片段着色器上实现Phong 着色以用于具有以下属性的照明:
- 每个模型都设置了纹理。
- 每个模型都有从模型加载的法线向量(对它们进行了一些预先计算,可能是因为 aiProcess_GenSmoothNormals 标志)
- 镜面光作用于所有物体。
- 漫反射颜色可以正常工作。
但是,管道对象是不同的:漫反射颜色始终位于应该被照亮的管道的另一侧,而镜面反射光位于正确的一侧。这让事情变得很奇怪,因为镜面反射光正常工作,而漫反射分量总是在错误的一侧。当我在搅拌机中将 cilinder 对象缩放到某个点之外时,我注意到了这种效果(较小的缩放 cilinder 仍然可以正常工作),因此将 cilinder 对象缩放到某个阈值之外可能与此有关。
在我的场景中,管状物体具有有效的镜面反射分量,但漫反射颜色位于光源的另一侧。
在搅拌机中看到的法线
我的第一个猜测是它与法线缩放有关,但我已经在顶点着色器中为此目的使用了法线矩阵,并且场景中的其他对象工作得很好。
顶点着色器:
#version 330
layout (location = 0) in vec3 vertex;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec3 tangent;
layout(location = 3) in vec3 color;
layout(location = 4) in vec2 texCoord;
uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
uniform vec3 lightPos;
out vec3 Position;
out vec3 Normal;
out vec3 LightPos;
out vec2 TexCoord;
void main()
{
gl_Position = projection * view * model * vec4(vertex, 1.0);
// Position
Position = vec3(view * model * vec4(vertex, 1.0));
// Normal
mat3 normalMat = transpose(inverse(mat3(view * model)));
Normal = normalMat * normal;
// Lighting
LightPos = vec3(view * vec4(lightPos, 1.0));
// Texture
TexCoord = texCoord;
}
片段着色器:
#version 330
in vec3 Position;
in vec3 Normal;
in vec3 LightPos;
in vec2 TexCoord;
uniform sampler2D texture0;
out vec4 outColor;
void main()
{
// defaults
vec4 ambient = vec4(0.2);
vec4 diffuse = vec4(0.4);
vec4 specular = vec4(0.5);
vec4 texColor = texture(texture0, TexCoord);
// Phong shading
vec3 LightDir = normalize(LightPos - Position);
vec3 Norm = normalize(Normal);
vec3 ViewDir = normalize(-Position);
vec3 ReflectDir = reflect(-LightDir,Norm);
float specularContribution = pow(max(dot(ViewDir, ReflectDir), 0.0), 32);
// Calculate diffuse component
vec4 I = diffuse * max(dot(Norm, LightDir), 0.0);
diffuse = clamp(I, 0.0, 1.0);
// Calculate specular component
specular = specular * specularContribution;
outColor = texColor * (diffuse + ambient + specular);
}
编辑
我添加了一个几何着色器,该着色器在第二个绘图通道中显示所有顶点法线以进行调试。但是,当显示法线时,它们会随着相机的移动而轻微移动,这是不应该的。我猜这可能是我之前提到的问题的原因。
我制作了一个小视频来说明正常运动:显示正常运动问题的 Youtube 视频。
视频显示随着相机移动,粉红色法线会改变方向。这不应该是这种情况,我不知道为什么。它是不正确的法线矩阵还是 assimp 错误地加载了法线?