# Easier method for lights in vertex program?

When dealing with a single, static model, lights are no problem. The light vector is calculated as the difference between the untransformed light position and the untransformed vertex position. Nothing complicated at all, eh?

However, trouble begins when one is dealing with multiple models. Since each model has its own transformation matrix to move it into position in the scene, one has to make sure to transform the position of the light to be correct relative to the model. Somehow, I’ve been having an extremely difficult time with this.

My solution was to use a program matrix that contains the position and orientation of the mesh itself, ignoring the perspective and the camera’s position and orientation. I take the inverse of that matrix in the vertex program and multiply it with the light position to get the light’s relative position. Here’s some code:

When I’m rendering each model:

``````float afMatrix = {1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
m_afPosition, m_afPosition, m_afPosition, 1.0f};

glMatrixMode (GL_MATRIX10_ARB);

glMatrixMode (GL_MODELVIEW);
``````

And a snippit from the vertex program:

``````DP4 tLightPos.x, iIPM0, iLightPos;
DP4 tLightPos.y, iIPM0, iLightPos;
DP4 tLightPos.z, iIPM0, iLightPos;
DP4 tLightPos.w, iIPM0, iLightPos;

SUB tLightPos, tLightPos, iPos;
``````

Where iIPM0 is the inverse of program matrix 0, iLightPos is the untransformed light position, and iPos is the untransformed vertex position.

Is there a way to do this where I don’t have to create a whole new matrix just so I can reliably transform the light position?

More code available upon specific request. . .

Why not just using the inverse model matrix,
which you can use at no cost in a vertex
program?

You are making this more difficult than it is.

Just convert your light positions and directions into model space before submitting them to the vertex program. (Saves calculating the same data for every vertex)

Something like the following (assuming light data is in world space):

``````//Setup variables
Matrix4 worldToModel;
Matrix3 worldToModel3x3;

worldToModel=modelView-&gt;GetInverse() * view-&gt;GetCamera()-&gt;GetViewTransform();
worldToModel.GetMatrix3(worldToModel3x3);

Switch(...)
{

case(RP_ModelSpace_LightDirection):
vector3 = worldToModel3x3 * light.ldirection;
break;

case(RP_ModelSpace_LightPosition):
vector3 = worldToModel * light.lposition;
break;
case(RP_ModelSpace_CameraPosition):
vector3 = worldToModel * view-&gt;GetCamera()-&gt;GetPosition();
Indeed, I don’t understand my problem either. 