Normal mapping problem.

Hi, I’ve been following a tutorial in order to implement a normal mapping using GLSL, there is something wrong in my code, because when I set a light with a negative Z coordinate, the illumination of the model ( normal factor ) change when I move the camera.

I think that tangents and bitangents are well computed because are generated by Assimp library.

Can anybody please, check for errors in my code?

Here my code:

// VERTEX SHADER
struct Light
{
vec4 position;
vec3 color;
};

uniform Light sceneLight[8];

attribute vec3 tangent;
attribute vec3 bitangent;

varying vec3 lightDirTanSpace;

void main()
{
vec3 normal = normalize( gl_NormalMatrix * gl_Normal );
vec3 vertexPos = vec3( gl_ModelViewMatrix * gl_Vertex );

mat3 mTBN = transpose(mat3(tangent, bitangent, normal));

lightDirTanSpace = normalize( mTBN * ( sceneLight[0].position.xyz - vertexPos ) );

gl_TexCoord[0] = gl_MultiTexCoord0;


gl_Position = ftransform();

}

// FRAGMENT SHADER

uniform sampler2D layers[8];
varying vec3 lightDirTanSpace;

void main( void )
{

vec3 normalMap = 2.0 * ( texture2D( layers[1], gl_TexCoord[0].st).rgb - 0.5 );
normalMap = normalize (normalMap);

float normalFactor =  max(dot(normalMap, lightDirTanSpace), 0.0);


vec4 diffuse = texture2D( layers[0], gl_TexCoord[0].st );

gl_FragColor  = diffuse * normalFactor;

Thanks in advance.

Your coordinate systems are confused.

mat3(tangent, bitangent, normal) transforms from tangent space to either eye space or object space, depending upon the coordinate system of the three vectors. mTBN performs the inverse transformation.

  1. The tangent and bitangent vectors will presumably be in object space, but the normal is being transformed to eye space. Either gl_Normal should be used directly, or the tangent and bitangent vectors need to be transformed to eye space using gl_ModelViewMatrix.

  2. Is sceneLight[0].position in object space or eye space? The calculation

sceneLight[0].position.xyz - vertexPos

only makes sense if it’s in eye space (as vertexPos is in eye space). If it’s in object space, you need to use gl_Vertex rather than vertexPos. Either way, this needs to match the space of the vectors used to generate mTBN.

If you want to operate in eye space (this is probably easiest if you plan to extend it to support specular reflection or environment mapping), and assuming that the light position is in eye space, you just need to transform the tangent and bitangent vectors to eye space.