# OpenGL Moving light with camera

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

## Recommended Posts

Hello,

Question 1.

I am implementing a ray-tracer where I am moving my camera in a circle around an object using the following:

camera_x = rs * sin(angle);    camera_y= 0.0;    camera_z = rs * cos(angle);

The light that illuminates the scene is specified by an azimuth angle and elevation angle. I want to move the light with the camera so that the light direction does not change with the camera movement. How can I do that?

I don't want to use OpenGL lighting, so it will be helpful if you can suggest the transformation I need to do so.

Question 2.

I know the camera position in world coordinate as I am calculating those using the equations shown above. How can I calculate the camera rotation matrix?

To solve the problem in question 1, I am thinking about transforming the light position from world coordinate to camera coordinate for each new position of the camera. However, for that I need both camera position (known) and orientation (how to calculate it?).

##### Share on other sites

Here the matrix functions to set a 4x4 matrix for the rotation on X, Y and Z using an angle in radian :

void Matrix4::SetRotationX( const float Angle )
{
const float Cos = Math::Cos( Angle );
const float Sin = Math::Sin( Angle );
m44[ 0 ][ 0 ] = 1.0f; m44[ 0 ][ 1 ] = 0.0f; m44[ 0 ][ 2 ] = 0.0f; m44[ 0 ][ 3 ] = 0.0f;
m44[ 1 ][ 0 ] = 0.0f; m44[ 1 ][ 1 ] = Cos;  m44[ 1 ][ 2 ] = -Sin; m44[ 1 ][ 3 ] = 0.0f;
m44[ 2 ][ 0 ] = 0.0f; m44[ 2 ][ 1 ] = Sin;  m44[ 2 ][ 2 ] = Cos;  m44[ 2 ][ 3 ] = 0.0f;
m44[ 3 ][ 0 ] = 0.0f; m44[ 3 ][ 1 ] = 0.0f; m44[ 3 ][ 2 ] = 0.0f; m44[ 3 ][ 3 ] = 1.0f;
}

void Matrix4::SetRotationY( const float Angle )
{
const float Cos = Math::Cos( Angle );
const float Sin = Math::Sin( Angle );
m44[ 0 ][ 0 ] = Cos;  m44[ 0 ][ 1 ] = 0.0f; m44[ 0 ][ 2 ] = Sin;  m44[ 0 ][ 3 ] = 0.0f;
m44[ 1 ][ 0 ] = 0.0f; m44[ 1 ][ 1 ] = 1.0f; m44[ 1 ][ 2 ] = 0.0f; m44[ 1 ][ 3 ] = 0.0f;
m44[ 2 ][ 0 ] = -Sin; m44[ 2 ][ 1 ] = 0.0f; m44[ 2 ][ 2 ] = Cos;  m44[ 2 ][ 3 ] = 0.0f;
m44[ 3 ][ 0 ] = 0.0f; m44[ 3 ][ 1 ] = 0.0f; m44[ 3 ][ 2 ] = 0.0f; m44[ 3 ][ 3 ] = 1.0f;
}

void Matrix4::SetRotationZ( const float Angle )
{
const float Cos = Math::Cos( Angle );
const float Sin = Math::Sin( Angle );
m44[ 0 ][ 0 ] = Cos;  m44[ 0 ][ 1 ] = -Sin; m44[ 0 ][ 2 ] = 0.0f; m44[ 0 ][ 3 ] = 0.0f;
m44[ 1 ][ 0 ] = Sin;  m44[ 1 ][ 1 ] = Cos;  m44[ 1 ][ 2 ] = 0.0f; m44[ 1 ][ 3 ] = 0.0f;
m44[ 2 ][ 0 ] = 0.0f; m44[ 2 ][ 1 ] = 0.0f; m44[ 2 ][ 2 ] = 1.0f; m44[ 2 ][ 3 ] = 0.0f;
m44[ 3 ][ 0 ] = 0.0f; m44[ 3 ][ 1 ] = 0.0f; m44[ 3 ][ 2 ] = 0.0f; m44[ 3 ][ 3 ] = 1.0f;
}
You then have to multiply the matrix in this order to have the combined rotation matrix : Z * X * Y
For the first part, you don't give much information about how you compute the lighting, do you have an issues because you are computing the lighting in view space ?
If it's the case, indeed you have to convert the light direction into view space doing : CameraViewMatrix.TransformVector(LightDirectionWorldSpace)
Here the function to transform one vector using a matrix :
Vector3 Matrix4::TransformVector( const Vector3& v ) const
{
return Vector3( v.x * m44[ 0 ][ 0 ] + v.y * m44[ 0 ][ 1 ] + v.z * m44[ 0 ][ 2 ],
v.x * m44[ 1 ][ 0 ] + v.y * m44[ 1 ][ 1 ] + v.z * m44[ 1 ][ 2 ],
v.x * m44[ 2 ][ 0 ] + v.y * m44[ 2 ][ 1 ] + v.z * m44[ 2 ][ 2 ] );
}
Edited by Alundra

##### Share on other sites

Hi Alundra,

Thanks for your reply. I just know the camera position in world coordinate. I don't know the angle of rotation for X, Y, Z axis. So my question in the second part was how can I get that. If I know the angle, I can compute the rotation matrix.

For question 1, I am computing light position in global coordinate. Say, initially my camera coordinate is aligned with the global coordinate system. camera is at (0,0,1) position. I compute the light position using elevation and azimuth angle.

light.x=R*sin(slant)*cos(tilt);

light.y=R*sin(slant)*sin(tilt);

light.z=R*cos(slant);

now, if the position of my camera changes, say new position is (1,0,0). How can compute the new light position?

##### Share on other sites

I believe you are over thinking the problem. If the light is at the camera, then you have most of the calculations done for you as all the objects you want lighted will be oriented in relation to the camera's position and facing direction. Are you using a point light, directional light, or a spot light? Each has its own way of calculating lighting, but the idea is the same as far as position (except directional). You would only need the direction for directional and spots.

##### Share on other sites

If it's the case, indeed you have to convert the light direction into view space doing : CameraViewMatrix.TransformVector(LightDirectionWorldSpace)

How can compute the CameraviewMatrix?

##### Share on other sites

You can set a look-at matrix :

void Matrix4::LookAt( const Vector3& From, const Vector3& To, const Vector3& Up )
{
const Vector3 ZAxis = ( To - From ).Normalized();
const Vector3 XAxis = VectorCross( Up, ZAxis ).Normalized();
const Vector3 YAxis = VectorCross( ZAxis, XAxis ).Normalized();
m44[ 0 ][ 0 ] = XAxis.x; m44[ 0 ][ 1 ] = XAxis.y; m44[ 0 ][ 2 ] = XAxis.z; m44[ 0 ][ 3 ] = -VectorDot( XAxis, From );
m44[ 1 ][ 0 ] = YAxis.x; m44[ 1 ][ 1 ] = YAxis.y; m44[ 1 ][ 2 ] = YAxis.z; m44[ 1 ][ 3 ] = -VectorDot( YAxis, From );
m44[ 2 ][ 0 ] = ZAxis.x; m44[ 2 ][ 1 ] = ZAxis.y; m44[ 2 ][ 2 ] = ZAxis.z; m44[ 2 ][ 3 ] = -VectorDot( ZAxis, From );
m44[ 3 ][ 0 ] = 0.0f;    m44[ 3 ][ 1 ] = 0.0f;    m44[ 3 ][ 2 ] = 0.0f;    m44[ 3 ][ 3 ] = 1.0f;
}

Another way to have a view matrix is to invert a world space matrix.

Edited by Alundra

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 14
• 14
• 45
• 22
• 27
• ### Forum Statistics

• Total Topics
634044
• Total Posts
3015213
×