Shadow Mapping Problem

Dear All,
I’m trying to figure out how to generate the shadow map projection matrix. However, all the examples I’ve seen use glTexgen, which as I understand it, is suspended when I enable cg. Can someone point out to me a shadow mapping example that doesn’t use glTexgen? Or even better, simply tell me what the equations for the matrix is without using glTexgen? A document on nVidia.com lead me to believe it was InverseCameraLightPOVInverseLightProjection*InvScale, but this doesn’t look anything like correct, and the texture swims when I move the camera. Is this matrix wrong, or am I doing something else incorretly.
Regards,
Jesse

As some NVidia paper stated, the texgen-planes could be thought of as a 4x4 matrix and the object coordinates, or eye coordinates depending on what texgen mode you activated, gets transformed by these into texcoords. I usually prefer the object-mode and I set it up like this:

glTexGenf(GL_S, GL_OBJECT_PLANE, 1st row in final light-space matrix);
glTexGenf(GL_T, GL_OBJECT_PLANE, 2nd row in final light-space matrix);
… R & Q here too.

In the VP, I do this:

DP4 res.texcrd[0].x, texgen[0].obj.s, vtx.pos;
DP4 res.texcrd[0].y, texgen[0].obj.t, vtx.pos;
… for z and w :slight_smile:

So all you need to do is to supply your light-space matrix to a VP and do the matrix-mul in there from obj-coords to tex-coords.

EDIT: Sorry, forgot the matrix. I’ll skip the explanation and go right onto it:
transf = model * invlight * lightproj * scale;
I’ve never really got matrix-order down to business properly, but I think you get the idea :smiley:

Or even better, simply tell me what the equations for the matrix is without using glTexgen?
All you need is a matrix that projects the scene into light-space. The only additional steps needed are the scale and translate transformations.

To project a vertex in light-space

V’ = LightProj LightMV Vworld

Where LightProj is the usual glFrustum() or gluPerspective(), and LightMV is from the usual viewing transformations or gluLookAt(). This should ultimately give you a vertex V’ in [-1,1].

To use the resulting coordinate for clamped texture mapping, we need to get it into [0,1]. To do this, we scale and translate by 1/2. The entire transformation looks like this:

V’ = Translate Scale LightProj LightMV Vworld

The whole thing in GL:

...
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glTranslatef(.5,.5,.5);
glScalef(.5,.5,.5);
glMultMatrixf(LightProj);
glMultMatrixf(LightMV);
...

This setup expects vertex postitions in world space. For a program, it’s trivial to get this position.

For the fixed function pipe, you could load an identity into the object linear planes for coords already in world space. Or, load the matrix that transforms your object into world-space for coords that are not, as Coelurus pointed out.

There are other ways to do all this. You could do all this in eye-space too.

edit:
stuff and yet more stuff