PDA

View Full Version : Spotlight Problems



heyufool1
11-04-2010, 01:36 PM
Hi! I tried figuring this out without asking for help but I just can't do it :mad: The problem is that my spotlight rotates with the camera. It's in the correct position but when the camera rotates so does the light. What I'm doing is I have a LightMatrix translated to the light's position - the camera's position. Then I rotate it by the camera's Y angle and the opposite of the camera's X angle. Then I send the LightMatrix to the shader, and I send the light's rotation:

float LightMatrix[16] = IDENTITY_MATRIX4;
//The false argument is just to check if it's relative or not
TranslateMatrix(LightMatrix, Position.m_x - CameraPosition.m_x, Position.m_y - CameraPosition.m_y, Position.m_z - CameraPosition.m_z, false);
RotateMatrix(LightMatrix, CameraRotation.m_y, Y_AXIS);
RotateMatrix(LightMatrix, -CameraRotation.m_x, X_AXIS);
glUniformMatrix4fv(glGetUniformLocation(MainShader , "LightMatrix"), 1, false, LightMatrix);
float LightRot[] = {RotationCounter.m_x, RotationCounter.m_y, RotationCounter.m_z};
SendUniform3f("SpotDirection", LightRot, MainShader);
Then in the shader I use this line:

float spotEffect = dot(normalize(SpotDirection * mat3(LightMatrix)), normalize(-lightDir));
I read in glLight specification that GL_SPOT_DIRECTION is transformed by the upper 3x3 of the modelview matrix. However no matter what try the light rotates with the camera. Any help is greatly appreciated!!!

heyufool1
11-05-2010, 04:26 PM
Well after a long time of working on this I finally got the rotation of the light to not rotate with the camera. However now the positioning isn't working.

Here's how I'm making the LightMatrix now:

float LightMatrix[16] = IDENTITY_MATRIX4;
TranslateMatrix(LightMatrix, Position.m_x, Position.m_y, Position.m_z, false);
RotateMatrix(LightMatrix, RotationCounter.m_y, Y_AXIS);
RotateMatrix(LightMatrix, RotationCounter.m_x, X_AXIS);
RotateMatrix(LightMatrix, RotationCounter.m_z, Z_AXIS);

float ViewMatrix[16] = IDENTITY_MATRIX4;
TranslateMatrix(ViewMatrix, CameraPosition.m_x, CameraPosition.m_y, CameraPosition.m_z, false);
RotateMatrix(ViewMatrix, CameraRotation.m_y, Y_AXIS);
RotateMatrix(ViewMatrix, -CameraRotation.m_x, X_AXIS);
RotateMatrix(ViewMatrix, CameraRotation.m_z, Z_AXIS);

Multiply4x4(LightMatrix, ViewMatrix);
glUniformMatrix4fv(glGetUniformLocation(MainShader , "LightMatrix"), 1, false, LightMatrix)
;
//Light Position
float LightPos[] = {Position.m_x - CameraPosition.m_x, Position.m_y - CameraPosition.m_y, Position.m_z - CameraPosition.m_z, Position.m_w - CameraPosition.m_w};
SendUniform4f("LightPos", LightPos, MainShader);

Here's how I'm doing the light calculation:

float spotEffect = dot(normalize(vec3(LightMatrix * LightPos)), normalize(-lightDir));
if ( spotEffect > SpotCutoff )
{
//Light computation...
}
With that code the light moves with the camera instead of rotates with it. So I guess the new question is how do I combine all the code into one to account for position and rotation?

heyufool1
11-06-2010, 02:13 PM
Well! After a long time I think I finally fixed it. The rotation itself is a bit weird, like the light seems to orbit around the position of the light. Oh well...

Dark Photon
11-07-2010, 01:45 PM
Here's how I'm doing the light calculation:

float spotEffect = dot(normalize(vec3(LightMatrix * LightPos)), normalize(-lightDir));
if ( spotEffect > SpotCutoff )
{
//Light computation...
}
With that code the light moves with the camera instead of rotates with it. So I guess the new question is how do I combine all the code into one to account for position and rotation?

Not enough to really tell what's going on here, but your "LightMatrix" concerns me.

Re the dot() above, the standard spotlight computation uses:

dot( (objpos-LightPosition).normalize(), LightConeAxisVector.normalize() )

See this: http://glprogramming.com/red/chapter05.html. (http://glprogramming.com/red/chapter05.html) In particular, search down to Spotlight Effect and see max(v*d,0)^GL_SPOT_EXPONENT. The above is the v*d part. Here's another good reference: http://www.lighthouse3d.com/opengl/glsl/index.php?spotlight

Put these 3 quantitites (objpos, LightPosition, and LightConeAxisVector) in the same space, and you're home free. Often eye-space is used for lighting calculations.

LightPosition and LightConeAxisVector are usually passed in via uniforms already in eye-space. Then objpos just comes from your normal gl_ModelViewMatrix * gl_Vertex computation. As you can see, no LightMatrix here...

heyufool1
11-07-2010, 07:19 PM
Thanks for the help! I successfully got the location of the light into eye-space, but I'm running into trouble with the rotation.

After reading this article (http://www.programmersheaven.com/2/world-view), I came to this process of calculating the rotation in eye-space:

1. Transform matrix 1 by the light's rotation then by the light's position.
2. Transform matrix 2 by the inverse camera position and then by the inverse camera rotation.
3. Multiply matrix 1 and matrix 2 to get the Model-View Matrix.
4. Multiply the Model-View matrix by the light's rotation, to get the light's rotation in eye-space.

This is not working, so where is the error?