Hello everybody.
I'm trying to get to work a normal maping glsl shader. It seems to be complete, but the result looks weird. When light is placed somwhere low and relatively far from object for example (0.0,0.0,100.0) it looks fine. ( On my scene 1.0 stands for 1cm) Otherwise when for eg. i point light above object or just somwhere high to have a "normal sun light" it looks strange. there are black stains on object and it seems not natural at all. I can't even say where is the light coming from looking on the object.
I suppose there is something wrong with some vector. Maybe someone could tell where is mistake.
Here's the procedure:
First i set camera:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0f, (float)_screenWidth/(float)_screenHeight, 1.0f, 5000.0f);
// eye is camera position and dir is direction it looks
gluLookAt(eye.x, eye.y, eye.z, eye.x+dir.x, eye.y+dir.y, eye.z+dir.z, 0.0f, 1.0f, 0.0f)
Then setup scene and light:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_LIGHTING);
_lightPosition[0] = 0.0f;
_lightPosition[1] = 0.0f;
_lightPosition[2] = 100.0f;
_lightPosition[3] = 0.0f;
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, _lightPosition);
Then objects on scene are rendered with use of:
glPushMatrix();
// mat is object's position matrix
glMultMatrixf(mat);
//below function render() will be listed
object.render();
glPopMatrix();
Here is simplified render funcion. All wertices of object are given in local space.
glUseProgram(shader);
glUniform1i(shader, "diffuseMap", 0);
glUniform1i(shader, "normalMap", 1);
/* ... binding textures here ... */
/* And draw mesh procedure*/
/* for all faces->vertices... as usual */
glBegin(GL_TRIANGLES);
glNormal3f(normal.x, normal.y, normal.z);
// Below i send tangent via color to shader
// because i didn't manage yet to do it with attribute
glColor3f(tangent.x, tangent.y, tangent.z);
glMultiTexCoord2f(GL_TEXTURE0, txcord.u, txcord.v);
glMultiTexCoord2f(GL_TEXTURE1, txcord.u, txcord.v);
glVertex3f(vertex.x,vertex.y,vertex.z);
glEnd();
glUseProgram(0);
Ok here is shader code.
Vertex shader:
varying vec3 L;
void main()
{
// normal map computing
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_TexCoord[1] = gl_MultiTexCoord1;
L = vec3(gl_LightSource[0].position - gl_ModelViewMatrix * gl_Vertex);
L = normalize(L);
vec3 N = normalize(gl_NormalMatrix * gl_Normal);
vec3 T = gl_Color.xyz;
vec3 B = cross(T,N);
mat3 TBN = mat3(T,B,N);
L = TBN * L;
// vertex transform
gl_Position = ftransform();
}
Framgent shader:
varying vec3 L;
uniform sampler2D diffuseMap;
uniform sampler2D normalMap;
void main()
{
vec3 rgb = texture2D(diffuseMap, gl_TexCoord[0]).rgb;
vec3 normal = texture2D(normalMap, gl_TexCoord[1]).xyz;
normal = (normal - 0.5) * 2;
L = normalize(L);
vec3 NdotL = dot(normal,L);
gl_FragColor.rgb = rgb * NdotL;
}
I've spent a couple of days trying figure out what is wrong bot can't find anything.
I would really apreciate if someone look at this code. I think it may be something with global and local vectors. I'm not quite sure if it's right way to get light vector.
Here's screen when light is positioned at (0.0,1000.0,500.0) and character is at (0,0,0).
http://img15.imageshack.us/img15/9638/normale.png