# GLSL NormalMap problems

This topic is 4399 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Alright, I've been having a bit of problems with my normal mapping. As far as I can tell, Im doing everything correctly, however, the display is... Less than correct. I've got a fairly simple vertex/fragment shader, the vertex shader simply converts from object space to tangent space in the typical way, I pass in the tangent and the crossfactor to the vertex shader that way I can reassemble the bitangent on the graphics card. I pass the tangent and cross factor in through a multitexture coordinate. My actual application uses vertex/texture/polygon coord arrays as well as multi texturing. Everything there is set up perfectly, to my knowledge anyway. The thing is, everything is displayed correctly until if I use the interpolated per vertex normals. It looks just fine, exactly as it should. But when I attempt to use the normal map, it appears as though the light is moving around the rendered object at a fairly high speed, and it has some other graphical oddities to say the least. Anyway, I think my code will explain a lot more than I can. I really appreciate any help anyone can give. I realize that my methods are a little strange, they're something of a modification of another peice of code. Vertex Program:
const vec4 AMBIENT = vec4( 0.1, 0.1, 0.1, 1.0 );
const vec4 SPECULAR = vec4( 1.0, 1.0, 1.0, 1.0 );

varying vec4 Ca;
varying vec4 Cd;
varying vec4 Cs;

varying vec4 V_eye;
varying vec4 L_eye;
varying vec4 N_eye;

void main(void)
{
vec3 bitangent = cross(gl_MultiTexCoord1.xyz,gl_Normal)*gl_MultiTexCoord1.w;

vec4 V = gl_ModelViewMatrix * gl_Vertex;
vec4 L = (gl_ModelViewMatrix * gl_LightSource[0].position) - V;
vec4 N = vec4(gl_NormalMatrix * gl_Normal, 0.0);

gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
V = -V;

V = V * gl_ModelViewMatrixInverse;
L = L * gl_ModelViewMatrixInverse;
N = N * gl_ModelViewMatrixInverse;

N_eye.x = dot(N.xyz,gl_MultiTexCoord1.xyz);
N_eye.y = dot(N.xyz,bitangent);
N_eye.z = dot(N.xyz,gl_Normal);

V_eye.x = dot(V.xyz,gl_MultiTexCoord1.xyz);
V_eye.y = dot(V.xyz,bitangent);
V_eye.z = dot(V.xyz,gl_Normal);

L_eye.x = dot(L.xyz,gl_MultiTexCoord1.xyz);
L_eye.y = dot(L.xyz,bitangent);
L_eye.z = dot(L.xyz,gl_Normal);

Ca = AMBIENT;
Cd = 0.5;
Cs = SPECULAR;

gl_TexCoord[0] = gl_MultiTexCoord0;
}


Fragment Program:
uniform sampler2D Base;
uniform sampler2D Gloss;
uniform sampler2D Normal;

varying vec4 Ca;
varying vec4 Cd;
varying vec4 Cs;

varying vec4 V_eye;
varying vec4 L_eye;
varying vec4 N_eye;

void main(void)
{
vec3 V = normalize(vec3(V_eye));
vec3 L = normalize(vec3(L_eye));
vec3 N = normalize(vec3(N_eye));

vec3 base = texture2D(Base,gl_TexCoord[0].st);
vec3 bump = texture2D(Normal,gl_TexCoord[0].st).xyz * 2.0 - 1.0;
float gloss = texture2D(Gloss,gl_TexCoord[0].st);

bump = normalize(bump);

float diffuse = clamp(dot(L, bump), 0.0, 1.0);

vec3 H = normalize(L + V);
float specular = clamp(pow(dot(bump, H), 32.0), 0.0, 1.0);

gl_FragColor.rgb = Ca + ((base*Cd)*diffuse) + (Cs*specular);
}


And, just incase, a bit of my rendering code:
glVertexPointer(3, GL_FLOAT, 0, &meshVertices[0][0]);
glNormalPointer(GL_FLOAT, 0, &meshNormals[0][0]);

if((textureCoordinateCount > 0))
{
glClientActiveTexture(GL_TEXTURE0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,e->m_Texture.m_TextureID);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, &meshTextureCoordinates[0][0]);

glClientActiveTexture(GL_TEXTURE1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D,e->m_Texture.m_GlossID);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(4, GL_FLOAT, 0, meshtangent);

glClientActiveTexture(GL_TEXTURE2);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D,e->m_Texture.m_NormalID);
};

if(sizeof(CalIndex)==2)
glDrawElements(GL_TRIANGLES, faceCount * 3, GL_UNSIGNED_SHORT, &meshFaces[0][0]);
else
glDrawElements(GL_TRIANGLES, faceCount * 3, GL_UNSIGNED_INT, &meshFaces[0][0]);



##### Share on other sites
Here's a hint: Is your normal map in eye space?
Here's a second hint: Why are you passing in the "N" value, when you're not using it?
Here's a third hint (OK, this probably gives it away :-): Normal maps are typically generated in tangent space, and require a transform to take them to object (or eye) space.