0

Below is listed the shader code for normal mapping. Nevertheless there is something wrong with the code since the resulting image is incorrect. The normals seem to be off. Other features seem to work fine so I believe the problem is with the shaders. Any ideas what could be wrong?

Vertex shader

#version 150

in vec3 position;
in vec2 texcoord;
in vec3 normal;
in vec3 tangent;
in vec3 bitangent;

out vec2 Texcoord;
out vec3 VertexPos_World;
out vec3 LightDir_Tan;

uniform vec3 lightPos0_World;
uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;

void main() 
{
    gl_Position = proj * view * model * vec4(position, 1.0);
    Texcoord = texcoord;    
    VertexPos_World = (model * vec4(position, 1.0)).xyz;

    vec3 normal_Cam = (view * model * vec4(normal, 1.0)).xyz;
    vec3 tangent_Cam = (view * model * vec4(tangent, 1.0)).xyz;
    vec3 bitangent_Cam = (view * model * vec4(bitangent, 1.0)).xyz; 

    mat3 TBN = transpose(mat3(tangent_Cam, bitangent_Cam, normal_Cam));

    vec3 lightDir_Cam = lightPos_Cam - vertexPos_Cam;
    LightDir_Tan = TBN * lightDir_Cam;
}

Fragment Shader

#version 150

in vec2 Texcoord;
in vec3 VertexPos_World;
in vec3 LightDir_Tan;

out vec4 outColor;

uniform vec3 lightPos0_World;
uniform vec3 lightColor0;
uniform float lightPower0;

uniform vec3 ambientColor;
uniform vec3 diffuseColor;
uniform sampler2D tex0;
uniform sampler2D tex0normal;

void main() 
{
    float lightDistance = length(lightPos0_World - VertexPos_World);

    vec3 materialDiffuseColor = texture(tex0, Texcoord).xyz * diffuseColor;
    vec3 materialAmbientColor = ambientColor * materialDiffuseColor;

    vec3 n = normalize(texture(tex0normal, Texcoord).rgb * 2.0 - 1.0);
    vec3 l = normalize(LightDir_Tan);
    float diff = clamp(dot(n,l), 0, 1);

    outColor.rgb = 
            materialAmbientColor +
            materialDiffuseColor * lightColor0 * lightPower0 * diff / (lightDistance * lightDistance);
}
4

2 回答 2

3

这可能不是唯一的问题,但在您的着色器中,您有:

vec3 normal_Cam = (view * model * vec4(normal, 1.0)).xyz;
vec3 tangent_Cam = (view * model * vec4(tangent, 1.0)).xyz;
vec3 bitangent_Cam = (view * model * vec4(bitangent, 1.0)).xyz; 

这应该是:

vec3 normal_Cam = (view * model * vec4(normal, 0.0)).xyz;
vec3 tangent_Cam = (view * model * vec4(tangent, 0.0)).xyz;
vec3 bitangent_Cam = (view * model * vec4(bitangent, 0.0)).xyz; 

使用0.0而不是1.0因为这些是方向向量,而不是位置,所以你想忽略矩阵中的平移。

此外,您应该在应用程序中将这些矩阵相乘,并在着色器中使用统一的 view_model(否则您将按顶点而不是按模型进行这项工作)。

于 2013-07-17T11:11:56.223 回答
1

您的法线很可能非常偏离。确保提交一个每个面有 4 个顶点的立方体,而不是提交一个具有 8 个顶点的立方体,以便您可以为每个面发送正确的法线。否则,插值器将仅使用索引相邻三角形的法线,这就是导致该问题的原因。

于 2013-07-16T20:59:25.643 回答