2

目前,我正在在 Blender 中创建并通过 assimp 加载的 3D 场景中设置一些照明,并设置了以下选项:

aiProcess_GenSmoothNormals | aiProcess_Triangulate | aiProcess_CalcTangentSpace | aiProcess_FlipUVs

目前,我在程序中遇到了一个非常奇怪的故障。我正在片段着色器上实现Phong 着色以用于具有以下属性的照明:

  1. 每个模型都设置了纹理。
  2. 每个模型都有从模型加载的法线向量(对它们进行了一些预先计算,可能是因为 aiProcess_GenSmoothNormals 标志)
  3. 镜面光作用于所有物体。
  4. 漫反射颜色可以正常工作。

但是,管道对象是不同的:漫反射颜色始终位于应该被照亮的管道的另一侧,而镜面反射光位于正确的一侧。这让事情变得很奇怪,因为镜面反射光正常工作,而漫反射分量总是在错误的一侧。当我在搅拌机中将 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 错误地加载了法线?

4

0 回答 0