Problem: projective texture matrix with shadow mapping.

Hi all.

I’m trying to implement Shadow Mapping with this tutorial ,
but I’m now at a loss because the projective texture breaks when I move the camera view.
And here’s some codes…

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glPushAttrib(GL_ALL_ATTRIB_BITS);
glPushMatrix();

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
UpdateViewMatrix();

glUseProgramObjectARB(g_ProgObj);
{
	/* Some codes are omitted. */

	ComputeProjectiveMatrix();

	RenderScene();
}
glUseProgramObjectARB(NULL);

glPopMatrix();
glPopAttrib();

This is the second pass which renders the scene from the camera view.
And the UpdateViewMatrix() is the camera view routine which calls glMultMatrixf(g_CamViewMatrix).

Do you have any hints or ideas?
Thanks. :slight_smile:

Hi,
I’m the author of this tutorial !
Where do you store your projective matrix?
And can you post the code of the g_ProgObj program? I think the problem can be here.

Oh, it’s a small world. :smiley:

Well, to be honest, I’m not really understanding the projective matrix algorithm.
So I just take your codes in my program:

glMatrixMode(GL_TEXTURE);
glLoadIdentity();
gluLookAt(g_CameraPos.x, g_CameraPos.y, g_CameraPos.z, g_LookAt.x, g_LookAt.y, g_LookAt.z, 0.0, 1.0, 0.0);
glGetFloatv(GL_TEXTURE_MATRIX, g_InvViewMatrix);
glMatrixMode(GL_MODELVIEW);
Quaternion invert(g_InvViwMatrix);
invert.invert();
invert.getMatrix(g_InvViewMatrix);
g_InvVMatrix[12] = g_CameraPos.x;
g_InvVMatrix[13] = g_CameraPos.y;
g_InvVMatrix[14] = g_CameraPos.z;

And also, the g_ProgObj is the same program as your shadow.fp.

In fact, I think my algo for computing the invCamViewMatrix only works when (g_LookAt.x, g_LookAt.y, g_LookAt.z) is the null vector : (0.0, 0.0, 0.0), just because I only invert the 3x3 upper-part of the camViewMatrix and I set the last column myself, assuming that this is a null vector !
You must write a little inverting function for doing this when this vector is non-null, and I think this should do the trick.

nice tutorial,
though I wonder if I can implement it with GL 1.3 ie no shaders…

while it looks like one can do everything manually, is it possible to generate the shadowmap tex coordinates for display lists ?

from my experience one cannot change tex coords outside of a display list, only using texGen, which likely couldnt do the job
or could one create a proper texcoord using eye_linear ??

edit: hmm kinda overlooked what the fragment program does, guess there is no real non shader workaround for that

CrazyButcher, check out this tutorial . It implements shadow mapping using only ARB_depth_texture and ARB_shadow extensions : ARB_depth_texture for storing the depth map texture and ARB_shadow for performing per-fragment comparison.
For computing projective coordinates, it uses glTexGen.

Hope this helps.

Im not sure but it can help… Using following part of GL code:

  
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glTranslatef(0.5, 0.5, 0.5);
glScalef(0.5, 0.5, 0.5);
gluPerspective(l->m_fovy, 1, l->m_near, l->m_far);
gluLookAt(l->m_pos.v.x,	l->m_pos.v.y, l->m_pos.v.z,
l->m_target.v.x, l->m_target.v.y, l->m_target.v.z,
l->m_up.v.x, l->m_up.v.y, l->m_up.v.z));

you can remove line:
projectiveBiased = (projectiveBiased + 1.0) * 0.5;
from fragment shader.

thx a lot grek

Looks like there’s no way I can solve this problem without any matrix knowledge…

personaly, im having problems with computeProjectiveMatrix();.
Gotta keep working on that.

@ S&W : I was wrong, my code also works for any non-null (g_LookAt.x, g_LookAt.y, g_LookAt.z)! So the problem is not here. Just to be sure : have you modified this part of code ??? :

void computeProjectiveMatrix()
{
  glMatrixMode(GL_TEXTURE);
  glLoadMatrixf(light->getProjMatrix());
  glMultMatrixf(light->getViewMatrix());
  glMultMatrixf(cam->getInvViewMatrix());
  
  glMatrixMode(GL_MODELVIEW);
}

Finally, which card have you ?

@ lc_overlord :
Can you describe your problems, and which card have you too ??

Well, I’ve ported the code from C++ to C,
so maybe something went wrong with my code:

void SetupProjectiveMatrix(void)
{
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();
	gluPerspective(60.0, 1.0, 1.0, 10.0);
	glGetFloatv(GL_MODELVIEW_MATRIX, g_ProjMatrix);
	glPopMatrix();
}
 
void SetupViewMatrix(void)
{
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();
	gluLookAt(g_LightPos[0], g_LightPos[1], g_LightPos[2],
		0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
	glGetFloatv(GL_MODELVIEW_MATRIX, g_ViewMatrix);
	glPopMatrix();
}
 
void SetupInvViewMatrix(void)
{
	glMatrixMode(GL_TEXTURE);
	glLoadIdentity();
	gluLookAt(g_EyePos.x, g_EyePos.y, g_EyePos.z,
		g_LookAt.x, g_LookAt.y, g_LookAt.z, g_UpwardVec.x, g_UpwardVec.y, g_UpwardVec.z);
	glGetFloatv(GL_TEXTURE_MATRIX, g_InvVMatrix);
	glMatrixMode(GL_MODELVIEW);

	Quaternion invert(g_InvVMatrix);
	invert.invert();
	invert.getMatrix(g_InvVMatrix);

	g_InvVMatrix[12] = g_EyePos.x;
	g_InvVMatrix[13] = g_EyePos.y;
	g_InvVMatrix[14] = g_EyePos.z;
}
 
void ComputeProjectiveMatrix(void)
{
	SetupProjectiveMatrix();
	SetupViewMatrix();
	SetupInvViewMatrix();

	glMatrixMode(GL_TEXTURE);
	glLoadMatrixf(g_ProjMatrix);
	glMultMatrixf(g_ViewMatrix);
	glMultMatrixf(g_InvVMatrix);
	glMatrixMode(GL_MODELVIEW);
}

And I’m using the Radeon 9800 Pro.

I can’t found any error in your code : all seems ok !!!
Are you using Catalyst 4.4 ? My demo doesn’t work with any older drivers.
Oh… and you must call :

glLightfv(GL_LIGHT0, GL_POSITION, pos);

with the GL_MODELVIEW_MATRIX set to the camViewMatrix.

GreK: FX5600.
The problem i have is that the lightsource seams to folow the camera around, i might be able to fix it myself but the code is a mess since i had to attach it to my own engine with a viritual staplegun. :slight_smile:

Edit: silly me i forgot that i moved the getinverseviewmatrix fuction to my lightclass and i used the lightsource cordinates instead of the camera position coords, it sortof works now.

Well, I’ve succeeded in implementing with this tutorial .
But these are fixed functions,
so is it possible to use a texture matrix which generated by glEnable(GL_TEXTURE_GEN_S/T/R/Q) in GLSL shaders?

glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_S, GL_EYE_PLANE, textureMatrix.GetRow(0));
glEnable(GL_TEXTURE_GEN_S);
 
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_T, GL_EYE_PLANE, textureMatrix.GetRow(1));
glEnable(GL_TEXTURE_GEN_T);
 
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_R, GL_EYE_PLANE, textureMatrix.GetRow(2));
glEnable(GL_TEXTURE_GEN_R);
 
glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGenfv(GL_Q, GL_EYE_PLANE, textureMatrix.GetRow(3));
glEnable(GL_TEXTURE_GEN_Q);

I’m convinced that the problem is the texture matrix generation.

I think you can use the generated texture coordinates in a pure GLSL fragment program (i.e. a GLSL program without vertex shaders), but I never try to do so, so I can’t guarantee it.

The standard math library should define M_PI when you include <math.h>, but some versions of MSVC require that you #define _USE_MATH_DEFINES before including <math.h> for them to be defined. Typically, you’d set this in your precompiled header for the project.

A better value for M_PI is 3.14159265358979, which is as far as I’ve memorized – but the web will come through should you need more precision :slight_smile:

That was my stupid question…
And thanks, jwatte.