   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 110varying 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 110varying 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 -Ehsan-[Edited by - ehsan2004 on April 7, 2010 1:40:14 AM]
  I'm no way near as familiar with gl as with dx, but usually when this sort of thing happens there are a couple of possible causes.1) Your normals are facing the wrong way - negate the zor2) Your tangent matrix needs transposing.Give both of those a fiddle and see if anything starts working?   ;  Thank you :)I transposed the tangent matrix and now everything is OK. I'm really surprised :)   ;  Actually I could solve this problem with constructing a mat3 matrix://vec3 tVector = vec3( t.x, b.x, n.x );    //vec3 bVector = vec3( t.y, b.y, n.y );    //vec3 nVector = vec3( t.z, b.z, n.z );   mat3 tbnMatrix = mat3(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);    if( enableNormalMap )    {//lightDir.x = dot( tVector, tempVec  );//lightDir.y = dot( bVector, tempVec );//lightDir.z = dot( nVector, tempVec );lightDir = tbnMatrix * tempVec;    }    elselightDir = tempVec;    dist = length(tempVec );    viewDir = -vertexPos;    if( enableNormalMap )    {//viewDir.x = dot( tVector, tempVec ) ;//viewDir.y = dot( bVector, tempVec ) ;//viewDir.z = dot( nVector, tempVec ) ;viewDir = tbnMatrix * viewDir;    }Now I have another question:Why I can't get the same result with dot products? :( Even with//vec3 tVector = vec3( t.x, t.y, t.z );//vec3 bVector = vec3( b.x, b.y, b.z );//vec3 nVector = vec3( n.x, n.y, n.z );Why?   ;  Which vectors are you using?These:vec3 tVector = vec3( t.x, t.y, t.z );vec3 bVector = vec3( b.x, b.y, b.z );vec3 nVector = vec3( n.x, n.y, n.z );Are transposed compared to tbnMatrix.BTW, at the end of the shader, you are passing tempVec as the 2nd argument to dot(), but you probably meant to pass viewDir.   ;  OK, I tried your suggestions:    vec3 n, t, b;    if( enableNormalMap )    {n = normalize(gl_NormalMatrix * gl_Normal);t = normalize(gl_NormalMatrix * gl_MultiTexCoord1.xyz);b = normalize(gl_NormalMatrix * gl_MultiTexCoord2.xyz);    }    vec3 tVector = vec3( t.x, t.y, t.z );    vec3 bVector = vec3( b.x, b.y, b.z );    vec3 nVector = vec3( n.x, n.y, n.z );   mat3 tbnMatrix = mat3(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);    if( enableNormalMap )    {lightDir.x = dot( tVector, tempVec  );lightDir.y = dot( bVector, tempVec );lightDir.z = dot( nVector, tempVec );//lightDir = tbnMatrix * tempVec;    }    elselightDir = tempVec;    dist = length(tempVec );    //lightDir = normalize( lightDir );    viewDir = -vertexPos;    if( enableNormalMap )    {viewDir.x = dot( tVector, viewDir ) ;viewDir.y = dot( bVector, viewDir ) ;viewDir.z = dot( nVector, viewDir ) ;//viewDir = tbnMatrix * viewDir;    }  With this code, I get the error mentioned at the beginnig of this topic . Also with these vector:    vec3 tVector = vec3( t.x, b.x, n.x );    vec3 bVector = vec3( t.y, b.y, n.y );    vec3 nVector = vec3( t.z, b.z, n.z );I don't get correct results: 