View Full Version : Odd per pixel lighting effects

02-05-2011, 11:57 AM
I recently wrote a shader for a terrain. When that worked, i wanted to move on to lighting, so i calculated normals, drew them to make sure they were ok, and proceeded to follow the lighthouse3d tutorial on per-pixel lighting (http://www.lighthouse3d.com/opengl/glsl/index.php?ogldir1). This was the resulting shader:


// Send the height and texture coordinates //
height = gl_Vertex.y;
gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;

// Calculate the eye-space normal //
normal = normalize(gl_NormalMatrix * gl_Normal);

// Calculate the direction of the light //
lightDir = normalize(vec3( gl_LightSource[0].position));

// Compute the diffuse and ambient terms //
diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
ambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient;
ambient += gl_LightModel.ambient * gl_FrontMaterial.ambient;

// Set the position of the current vertex //
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;


// Compute lighting //
vec3 n;
float NdotL;

// The ambient term will always be present //
vec4 lightColor = ambient;

// Normalize the normal of the pixel //
n = normalize(normal);

// Compute the dot product between normal and ldir //
NdotL = max(dot(n,lightDir),0.0f);

// If the angle is not 0, the diffuse term must be calculated //
if (NdotL > 0.0f)
lightColor += diffuse * NdotL;

gl_FragColor = lightColor;

that didnt work. The intensity of the light changed when i moved the camera, which is just wrong. Then i realized i had been setting my light position before my modelview transforms, so then i did this:




Cam.Look(); // Transforms happened here //

GLfloat position[] = { 1.0f, 0.0f, 0.0f, 1.0f };
glLightfv(GL_LIGHT0, GL_POSITION, position);

//DrawGrid(&verts[0], 257, waterShader);

that didnt work either. Same sort of problem, light intensity change based on the cameras distance. So then i tried putting the glLightfv call BEFORE the modelview transform, and got rid of the gl_NormalMatrix call in my vertex shader:



// Calculate the eye-space normal //
normal = normalize(gl_Normal);

// Calculate the direction of the light //
lightDir = normalize(vec3( gl_LightSource[0].position));


That worked perfectly.

My question is simply why? It seems rather odd and if i dont understand it now it will come back to haunt me.

Thanks :D