I've been following
this tutorial for creating per-pixel spot lights, and both shading files seem to work fine if the camera is static. However, when I rotate the camera, the shadowing changes, which shouldn't be happening (I think). Camera rotation is done via the mouse (changing cameraRotate).
Here's the basic pseudocode of what I am doing:
render function:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslated(0.0, 0.0, -10.0);
glRotated(cameraRotate[0], 1.0, 0.0, 0.0);
glRotated(cameraRotate[1], 0.0, 1.0, 0.0);
glLightfv(GL_LIGHT0, GL_POSITION, lpos);
drawLight();
glutSolidTeapot(1);
glFlush();
glutSwapBuffers();
Here are the vertex and fragment shader functions (copied directly from the tutorial).
vertex shader:
varying vec4 diffuse,ambientGlobal, ambient;
varying vec3 normal,lightDir,halfVector;
varying float dist;
void main() {
vec4 ecPos;
vec3 aux;
/* first transform the normal into eye space and normalize the result */
normal = normalize(gl_NormalMatrix * gl_Normal);
/* now normalize the light's direction. Note that according to the
OpenGL specification, the light is stored in eye space.*/
ecPos = gl_ModelViewMatrix * gl_Vertex;
aux = vec3(gl_LightSource[0].position-ecPos);
lightDir = normalize(aux);
/* compute the distance to the light source to a varying variable*/
dist = length(aux);
/* Normalize the halfVector to pass it to the fragment shader */
halfVector = normalize(gl_LightSource[0].halfVector.xyz);
/* Compute the diffuse, ambient and globalAmbient terms */
diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
ambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient;
ambientGlobal = gl_LightModel.ambient * gl_FrontMaterial.ambient;
gl_Position = ftransform();
}
fragment shader:
varying vec4 diffuse,ambientGlobal, ambient;
varying vec3 normal,lightDir,halfVector;
varying float dist;
void main()
{
vec3 n,halfV;
float NdotL,NdotHV;
vec4 color = ambientGlobal;
float att,spotEffect;
/* a fragment shader can't write a verying variable, hence we need
a new variable to store the normalized interpolated normal */
n = normalize(normal);
/* compute the dot product between normal and ldir */
NdotL = max(dot(n,normalize(lightDir)),0.0);
if (NdotL > 0.0) {
spotEffect = dot(normalize(gl_LightSource[0].spotDirection), normalize(-lightDir));
if (spotEffect > gl_LightSource[0].spotCosCutoff) {
spotEffect = pow(spotEffect, gl_LightSource[0].spotExponent);
att = spotEffect / (gl_LightSource[0].constantAttenuation + gl_LightSource[0].linearAttenuation * dist + gl_LightSource[0].quadraticAttenuation * dist * dist);
color += att * (diffuse * NdotL + ambient);
halfV = normalize(halfVector);
NdotHV = max(dot(n,halfV),0.0);
color += att * gl_FrontMaterial.specular * gl_LightSource[0].specular * pow(NdotHV,gl_FrontMaterial.shininess);
}
}
gl_FragColor = color;
}
Any help would be greatly appreciated!