Search code examples
matrixglslshaderprojectionlighting

Compute normals in shader issue


I have the following vertex shader to rotate normals. Before I implemented that, I passed also the rotation matrix of the mesh to calculate the normals. That time lighting was just fine.

#version 150

uniform mat4 projection;
uniform mat4 modelview;

in vec3 position;
in vec3 normal;
in vec2 texcoord;

out vec3 fposition;
out vec3 fnormal;
out vec2 ftexcoord;

void main()
{
    mat4 mvp = projection * modelview;

    fposition   = vec3(mvp * vec4(position, 1.0));
    fnormal     = normalize(mat3(transpose(inverse(modelview))) * normal);
    ftexcoord   = texcoord;
    gl_Position = mvp * vec4(position, 1.0);
}

But with this shader, the lighting computed in the fragment shader turns with the camera. I haven't changed the fragment shader, so the issue should be in the code above.

What am I doing wrong in computing the normals?


Solution

  • The steps you use to create the normal Matrix might be out of order.

    Try:

    fnormal = normalize(transpose(inverse(mat3(modelview))) * normal)
    

    Edit:

    Since you are inverting the mat4, the translation values (which get truncated when a mat4 is converted to a mat3) are probably affecting the calculation of the inverse matrix.