سؤال

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?

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top