Shadow Mapping Problem

Dear All,

I’m having some problems with shadow mapping and I hope someone can help me out.

I have a scene which can be viewed here.

Plain Image

I have a correct depth map which can be seen here

Depth Map

However, after this everything starts going wrong.

Here is my image after using code I have taken from the OpenGL Superbible.

Weird

I am completely and utterly at a loss as to what i’m doing wrong. The sphere is now completely black, there is no shadowing, and the lamppost has some very very strange banding on it.

Here is the code I’m using. If someone can please help I’d really appreciate it.

The problems seem to be in the glEnable(GL_TEXTURE_GEN_xxx) methods at the end. If i remove them, the image is of course normal. If i allow just the GEN_S method the ground texture i’m using doesn’t appear. If i allow just the GEN_T I get the banding on the lamppost and a lit sphere. GEN_R gets me a normal lamppost and a black sphere. GEN_Q is the normal image with normal texturing. Any ideas? PLEASE? :slight_smile:

 //in init method
        GLuint shadowTextureID;

	glGenTextures(1, &shadowTextureID);
	glBindTexture(GL_TEXTURE_2D, shadowTextureID);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB, 0.1f);
	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
	glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
	glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
	glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);

	GetShadowMap();


//Get ShadowMap method listed here
void GetShadowMap(void)
{
	GLfloat lightToSceneDistance, nearPlane, fieldOfView;
	GLfloat lightModelview[16], lightProjection[16];

	lightToSceneDistance = sqrt(scene.light.x * scene.light.x + scene.light.y * scene.light.y + scene.light.z * scene.light.z);
	nearPlane = 10.0f;

	fieldOfView = 17000.0f;

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(fieldOfView, 1.0f, nearPlane, nearPlane + 300.0f);
	glGetFloatv(GL_PROJECTION_MATRIX, lightProjection);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(scene.light.x, scene.light.y, scene.light.z, scene.light.x, 0.0f, scene.light.z, 0.0f, 0.0f, 1.0f);
	glGetFloatv(GL_MODELVIEW_MATRIX, lightModelview);

	glViewport(0, 0, 512, 512);

	glClear(GL_DEPTH_BUFFER_BIT);

	glShadeModel(GL_FLAT);
	glDisable(GL_LIGHTING);
	glDisable(GL_COLOR_MATERIAL);
	glDisable(GL_NORMALIZE);
	glColorMask(0,0,0,0);

	glEnable(GL_POLYGON_OFFSET_FILL);
	glPolygonOffset(1.1f, 4.0f);

	scene.DrawScene();

	glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 0, 0, 512, 512, 0);

	glShadeModel(GL_SMOOTH);
	glEnable(GL_LIGHTING);
	glEnable(GL_COLOR_MATERIAL);
	glEnable(GL_NORMALIZE);
	glColorMask(1,1,1,1);
	glDisable(GL_POLYGON_OFFSET_FILL);

	glMatrixMode(GL_TEXTURE);
	glLoadIdentity();
	glTranslatef(0.5f, 0.5f, 0.5f);
	glScalef(0.5f, 0.5f, 0.5f);
	glMultMatrixf(lightProjection);
	glMultMatrixf(lightModelview);
}

//And lastly the code in the render method

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);				
	glLoadIdentity();												
	glTranslatef(0.0f, 0.0f, -1.0f);

	
	glDisable(GL_LIGHTING);
	glRasterPos2f(cnt1, cnt2);
	font.glPrint("FPS: %d", (int)fps);
	glEnable(GL_LIGHTING);

	glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glMultMatrixf(&camera.projMatrix[0][0]);
	
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glMultMatrixf(&camera.viewMatrix[0][0]);	

	
    scene.cgOff = true;
	
    glViewport(0,0, WIDTH, HEIGHT);
    GLfloat lightPos[] = {scene.light.x, scene.light.y, scene.light.z};

		GLfloat sPlane[4] = {1.0f, 0.0f, 0.0f, 0.0f};
		GLfloat tPlane[4] = {0.0f, 1.0f, 0.0f, 0.0f};
		GLfloat rPlane[4] = {0.0f, 0.0f, 1.0f, 0.0f};
		GLfloat qPlane[4] = {0.0f, 0.0f, 0.0f, 1.0f};
	
		GLfloat ambientLight[] = {0.2f, 0.2f,0.2f, 1.0f};
		GLfloat diffuseLight[] = {0.7f, 0.7f, 0.7f, 1.0f};

		glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
		glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);

		glEnable(GL_TEXTURE_2D);
		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

		

		glTexGenfv(GL_S, GL_EYE_PLANE, sPlane);
		glTexGenfv(GL_T, GL_EYE_PLANE, tPlane);
		glTexGenfv(GL_R, GL_EYE_PLANE, rPlane);
		glTexGenfv(GL_Q, GL_EYE_PLANE, qPlane);

		glEnable(GL_TEXTURE_GEN_S);
		glEnable(GL_TEXTURE_GEN_T);
		glEnable(GL_TEXTURE_GEN_R);
		glEnable(GL_TEXTURE_GEN_Q);

		scene.DrawScene();

		glDisable(GL_ALPHA_TEST);
		glDisable(GL_TEXTURE_2D);
		glDisable(GL_TEXTURE_GEN_S);
		glDisable(GL_TEXTURE_GEN_T);
		glDisable(GL_TEXTURE_GEN_R);
		glDisable(GL_TEXTURE_GEN_Q);

 

For starters it looks like you’ve only got a 3 component light position (need 4), and you fail to call glLightf with that position.

I don’t know by maybe this can help:
http://www.paulsprojects.net/tutorials/smt/smt.html

Cheers

Unfortunately adding the fourth light position didnt work. And i’m curious as to why you say its needed when the paulsprojects page uses 3 component light positions?

I just can’t get it working :frowning:

I am not quite sure (I am implementing it myself right now) but I think this line is wrong:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB, 0.1f);

it should be:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL );

being the first one the most important line of shadowmapping (it compares the depth texture values projected to create alpha values of 1 or 0’s that can then be discarted with alpha test).

I hope this fixes it!

Cheers!
Rod

Oh! Also beware that if you are using textures for your objects you must do lightmapping on another channel using
glActiveTextureARB

Just to give you an example (you’ll have to use this on some more parts of your code where you switch between using the shadowmap texture and common textures):

glActiveTextureARB(GL_TEXTURE1)
		glEnable(GL_TEXTURE_GEN_S);
		glEnable(GL_TEXTURE_GEN_T);
		glEnable(GL_TEXTURE_GEN_R);
		glEnable(GL_TEXTURE_GEN_Q);
glActiveTextureARB(GL_TEXTURE0)
		scene.DrawScene();
glActiveTextureARB(GL_TEXTURE1)
		glDisable(GL_ALPHA_TEST);
		glDisable(GL_TEXTURE_2D);
		glDisable(GL_TEXTURE_GEN_S);
		glDisable(GL_TEXTURE_GEN_T);
		glDisable(GL_TEXTURE_GEN_R);
		glDisable(GL_TEXTURE_GEN_Q);
glActiveTextureARB(GL_TEXTURE0)

…given that you are using only one texture channel for you objects (if not use GL_TEXTURE2 for your shadowmap, and reserver GL_TEXTURE0 and GL_TEXTURE1 for your objects)

Cheers!
Rod