0
votes

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);
}
2
Can you post what you're sending to the GPU?Joseph Pla

2 Answers

3
votes

This might not be the only issue, but in your shader you have:

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; 

This should be:

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; 

Using 0.0 instead of 1.0 because these are direction vectors, not positions, so you want to ignore the translations in the matrices.

Also, you should multiply those matrices in your application and use a uniform view_model in your shader (otherwise you do this work per-vertex instead of per-model).

1
votes

Your normals are most likely very off. Make sure that instead of submitting a cube with 8 vertices, you submit a cube with 4 vertices per face so that you can send the correct normals per face. Otherwise, the interpolator will simply use the normals from indexed neighbour triangles and that is what causes that issue.