when i use the model's normal , the result is fine ( there are dark areas and lit areas , as i would expect from a simple lambert diffuse shader )
but when i use a normal map , the dark areas gets lit!
i want to use a normal map and still get correct diffuse lighting like these examples
here is the code with and without normal mapping
and here is the code that uses the normal map
Vertex Shader
varying vec3 normal,lightDir;
attribute vec3 vertex,normalVec,tangent;
attribute vec2 UV;
void main(){
gl_TexCoord[0] = gl_TextureMatrix[0] * vec4(UV,0.0,0.0);
normal = normalize (gl_NormalMatrix * normalVec);
vec3 t = normalize (gl_NormalMatrix * tangent);
vec3 b = cross (normal, t);
vec3 vertexPosition = normalize(vec3(gl_ModelViewMatrix * vec4(vertex,1.0)));
vec3 v;
v.x = dot (lightDir, t);
v.y = dot (lightDir, b);
v.z = dot (lightDir, normal);
lightDir = normalize (v);
lightDir = normalize(vec3(1.0,0.5,1.0) - vertexPosition);
gl_Position = gl_ModelViewProjectionMatrix*vec4(vertex,1.0);
}
Fragment Shader
vec4 computeDiffuseLight (const in vec3 direction, const in vec4 lightcolor, const in vec3 normal, const in vec4 mydiffuse){
float nDotL = dot(normal, direction);
vec4 lambert = mydiffuse * lightcolor * max (nDotL, 0.0);
return lambert;
}
varying vec3 normal,lightDir;
uniform sampler2D textures[8];
void main(){
vec3 normalVector = normalize( 2 * texture2D(textures[0],gl_TexCoord[0].st).rgb - 1 );
vec4 diffuse = computeDiffuseLight (lightDir, vec4(1,1,1,1) , normalVector, vec4(0.7,0.7,0.7,0));
gl_FragColor = diffuse ;
}
Note: the actual normal mapping works correctly as seen in the specular highlights
i used Assimp to load the model ( md5mesh ) and calculated the tangents using Assimp too , then sent it to the shaders as an attribute
here is a link to the code and screenshots of the problem
https://dl.dropboxusercontent.com/u/32670019/code%20and%20screenshots.zip
is that a problem in the code or am i having a misconception ?
Updated code and screenshots
https://dl.dropboxusercontent.com/u/32670019/updated%20code%20and%20screenshots.zip
now the normal map works with the diffuse , but the diffuse alone is not correct
For Answer, see below.
Quick (possibly wrong) observation: The line
vec3 normalVector = normalize( 2 * texture2D(textures[0],gl_TexCoord[0].st).rgb - 1 );
in your fragment shader correctly rescales your normal to allow for negative values. If your normal map is incorrect, negative values might occur where you do not want them (your Y axis I presume). Negative values in a normal can result in reversed lighting.
My question to you: Is your normal map correct?
ANSWER: After a bit of discussion we found the problem, I've edited this post to keep the thread clean, the solution to Darko's problems are in the comments here. It came down to uninitialized varying called lightDir.
Original comment:
lightDir = normalize (v); lightDir = normalize(vec3(1.0,0.5,1.0) - vertexPosition); This is strange, you overwrite it instantly, is this wrong? you dont seem to keep the correctly translated lightDir... Or am I crazy... Also this lightDir is a varying, but you don't set it at all. So you calculate a v vector from nothing?