Incorrect specular while using normal map

Hello
I’m wondering why I get incorrect specular for the floor while I use normal map ( The model has loaded from a Collada DAE file ).
Note that in the following photos, I have used a point light which is in the middle of the room( Above all the chairs )
Here’s a correct specular with my per pixel lighting shader:

But I can not see specular map from the same view while I use normal map:

And here’s another comparison:

And with normal map:

In the above picture, when I rotate the camera to the left, the specular goes to the right!

Here’s my shader which implements normal map:


<vertex>

#version 110

varying vec3 lightDir;
varying vec3 viewDir;
varying vec4 diffuse, ambientGlobal, ambient, specular;
varying float dist;

void main()
{
    gl_TexCoord[0] = gl_MultiTexCoord0;

    vec3 vertexPos = vec3(gl_ModelViewMatrix * gl_Vertex);
    vec3 lightPos =  vec3(gl_ModelViewMatrix * gl_LightSource[0].position);
    vec3 n = normalize(gl_NormalMatrix * gl_Normal);
    vec3 t = normalize(gl_NormalMatrix * gl_MultiTexCoord1.xyz);
    vec3 b = normalize(gl_NormalMatrix * gl_MultiTexCoord2.xyz);
    vec3 tempVec = (gl_LightSource[0].position.xyz - vertexPos);
    lightDir.x = dot( tempVec, t );
    lightDir.y = dot( tempVec, b );
    lightDir.z = dot( tempVec, n );

 
   dist = length(tempVec );
     
    //lightDir = normalize( lightDir );

    viewDir = -vertexPos;
    viewDir.x = dot( viewDir, t ) ;
    viewDir.y = dot( viewDir, b ) ;
    viewDir.z = dot( viewDir, n ) ;
    //viewDir = normalize( viewDir );

    diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
    ambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient;
    specular = gl_FrontMaterial.specular * gl_LightSource[0].specular;
    ambientGlobal = gl_LightModel.ambient * gl_FrontMaterial.ambient;
  
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
 
}

<fragment>

#version 110
varying vec3 lightDir;
varying vec3 viewDir;
varying vec4 diffuse, ambientGlobal, ambient, specular;
varying float dist;


uniform sampler2D colorMap;
uniform sampler2D normalMap;

void main()
{
	vec3 halfV,viewV,ldir;
	float NdotL,NdotHV;

	vec4 color = ambientGlobal;
	float att;

	ldir = normalize(lightDir); 
	viewV = normalize( viewDir );
        vec3 n = normalize(texture2D(normalMap, gl_TexCoord[0].st).rgb * 2.0 - 1.0);
  	
	vec4 textureColor = texture2D(colorMap,gl_TexCoord[0].st);

	NdotL = max(dot(n,ldir),0.0);
	
	if (NdotL > 0.0) {
	
		att = 1.0 / (gl_LightSource[0].constantAttenuation +
				gl_LightSource[0].linearAttenuation * dist +
				gl_LightSource[0].quadraticAttenuation * dist * dist);
		color += att * (diffuse * NdotL + ambient);
		color *= textureColor;
                halfV  = normalize(ldir  + viewV);
 		NdotHV = max(dot(n,halfV),0.0);
		color += att * specular * pow(NdotHV,gl_FrontMaterial.shininess);
	}
	gl_FragColor = color;
}


t and b are tangent and binormal vectors and loaded from the Collada dae file.

Note that I see the same specular with and without using the normal map for other models such as teapot:

With normal map:

And without normal map:

So I’m confused why the specular is incorrect for the floor!
Any Idea?
Thanks

I asked this question at gamedev.net and someone suggested me to use the transpose of the tangent matrix:

mat3 tbnMat( t.x, b.x, n.x,
t.y, b.y, n.y,
t.z, b.z, n.z );

vec3 tempVec = (gl_LightSource[0].position.xyz - vertexPos);
lightDir = tbnMat * tempVec;

viewDir = -vertexPos;
viewDir  = tbnMat * viewDir;

It solved my problem, but I couldn’t get the same results with vectors and dot products !

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.