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

## Recommended Posts

I have a bizarre problem with my shadow mapping code. The shadows work fine, but a little test sphere seems to lose its color. Screenshots: With shadows off (note how the sphere is white). And with shadows on. It's probably something really stupid, maybe even having nothing to do with the shader, but I'm stumped. Here's the vertex shader (GLSL):
varying vec4 diffuse;
varying vec3 normal, lightDir;

void main()
{
normal = normalize(gl_NormalMatrix * gl_Normal);
lightDir = vec3(gl_LightSource[0].position - gl_ModelViewMatrix * gl_Vertex);
diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;

gl_FrontColor = gl_Color;
gl_Position = ftransform();
}


varying vec4 diffuse;
varying vec3 normal, lightDir;

{
vec3 n = normalize(normal);
vec3 dir = normalize(lightDir);
return max(dot(n, dir), 0.0);
}

void main()
{
vec4 color = gl_Color * diffuse;
}


Transforming the texture matrix:
glMatrixMode(GL_TEXTURE);
glTranslatef(.5, .5, .5);
glScalef(.5, .5, .5);
glMultMatrixd(lightProjectionMatrix);
glMultMatrixd(lightModelViewMatrix);
glMatrixMode(GL_MODELVIEW);


and before we render the scene with shadows:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);


and finally, I guess, if it's relevant, drawing the damn (white!) ball:
GLUquadric *pQuad = gluNewQuadric();

glColor3f(1, 1, 1);
glTranslatef(bpos[0], bpos[1], bpos[2]);
glTranslatef(-bpos[0], -bpos[1], -bpos[2]);


Any help would be great!

##### Share on other sites
Have you disabled texture when drawing the sphere?

I'll leave shader comments to other posters, as I'm only recently migrating to shaders after many many years. Btw: yours inspires me more so!

##### Share on other sites
Actually, nothing's textured.

As a followup:

The problem is definitely somewhere in the shadow business: for some reason, it views the ball as being in shadow (but I don't know why.)

##### Share on other sites
Bump, with new info:

Here's a screenshot showing:

Upper left: final render
Lower right: The distance from each point to the light
Upper right: The corresponding point on the shadow map (i.e., the depth of the nearest occluder)

Look at the lower right - the ball is farther away from the light than the box, but it's darker (i.e., it's computed as closer). This seems to the main problem (but I'm not sure). Is there any reason it would do this? Is there an orientation bit that I may be flipping, or something?

Although I'm not sure it's relevant, here's the entire scene drawing code:

// draw floorfloat size = 10;glColor3f(0, 0, 1);glBegin(GL_QUADS);	glNormal3f(0, 0, 1);	glVertex3f(-size, -size, 0);	glVertex3f(-size, size, 0);	glVertex3f(size, size, 0);	glVertex3f(size, -size, 0);glEnd();// draw ballGLUquadric *pQuad = gluNewQuadric();gluQuadricNormals(pQuad, GLU_SMOOTH);glColor3f(1, 1, 1);float bpos[3] = { bdist * cos(bangle), bdist * sin(bangle), bheight };glTranslatef(bpos[0], bpos[1], bpos[2]);gluSphere(pQuad, .5, 20, 20);glTranslatef(-bpos[0], -bpos[1], -bpos[2]);gluDeleteQuadric(pQuad);// draw air boxfloat box = 2;glColor3f(0, 1, 0);glTranslatef(-bpos[0], -bpos[1], bpos[2]);glBegin(GL_QUADS);	glNormal3f(0, 0, 1);	glVertex3f(-box / 2, -box / 2, box);	glVertex3f(box / 2, -box / 2, box);	glVertex3f(box / 2, box / 2, box);	glVertex3f(-box / 2, box / 2, box);	glNormal3f(1, 0, 0);	glVertex3f(box / 2, -box / 2, 0);	glVertex3f(box / 2, box / 2, 0);	glVertex3f(box / 2, box / 2, box);	glVertex3f(box / 2, -box / 2, box);	glNormal3f(0, 1, 0);	glVertex3f(box / 2, box / 2, 0);	glVertex3f(-box / 2, box / 2, 0);	glVertex3f(-box / 2, box / 2, box);	glVertex3f(box / 2, box / 2, box);	glNormal3f(-1, 0, 0);	glVertex3f(-box / 2, box / 2, 0);	glVertex3f(-box / 2, -box / 2, 0);	glVertex3f(-box / 2, -box / 2, box);	glVertex3f(-box / 2, box / 2, box);	glNormal3f(0, -1, 0);	glVertex3f(-box / 2, -box / 2, 0);	glVertex3f(box / 2, -box / 2, 0);	glVertex3f(box / 2, -box / 2, box);	glVertex3f(-box / 2, -box / 2, box);glEnd();glTranslatef(bpos[0], bpos[1], -bpos[2]);// draw boxglColor3f(1, 0, 0);glBegin(GL_QUADS);	glNormal3f(0, 0, 1);	glVertex3f(-box / 2, -box / 2, box);	glVertex3f(box / 2, -box / 2, box);	glVertex3f(box / 2, box / 2, box);	glVertex3f(-box / 2, box / 2, box);	glNormal3f(1, 0, 0);	glVertex3f(box / 2, -box / 2, 0);	glVertex3f(box / 2, box / 2, 0);	glVertex3f(box / 2, box / 2, box);	glVertex3f(box / 2, -box / 2, box);	glNormal3f(0, 1, 0);	glVertex3f(box / 2, box / 2, 0);	glVertex3f(-box / 2, box / 2, 0);	glVertex3f(-box / 2, box / 2, box);	glVertex3f(box / 2, box / 2, box);	glNormal3f(-1, 0, 0);	glVertex3f(-box / 2, box / 2, 0);	glVertex3f(-box / 2, -box / 2, 0);	glVertex3f(-box / 2, -box / 2, box);	glVertex3f(-box / 2, box / 2, box);	glNormal3f(0, -1, 0);	glVertex3f(-box / 2, -box / 2, 0);	glVertex3f(box / 2, -box / 2, 0);	glVertex3f(box / 2, -box / 2, box);	glVertex3f(-box / 2, -box / 2, box);glEnd();

##### Share on other sites

Have you still got the active texture to be a FBO or PBuffer?

If your not needing texturing at the moment but a glDisable(GL_TEXTURE_2D) before your drawing code for your second pass and see it improves anything.

Jamie

##### Share on other sites
Quote:

By "first draw" do you mean the first pass? If so, then the shadow shader *only* runs on the second pass. But if you mean the right-hand images (drawing depth), then yes, I'm using different shaders for those.

Quote:
 Have you still got the active texture to be a FBO or PBuffer?

I'm actually using glCopyTexSubImage2D, not FBOs or pBuffers.

Quote:
 If your not needing texturing at the moment but a glDisable(GL_TEXTURE_2D) before your drawing code for your second pass and see it improves anything.

I'm not sure if I understand - I'm pretty sure I need the shadow map texture applied during the second pass, so that I can read from it in the fragment shader.

Thanks for the reply! Any other thoughts?

##### Share on other sites
OK, I think I got it working. For those interested, there were two problems:

1. gluSphere seems to render its triangles with clockwise orientation, whereas everything else (it seems) is counterclockwise. For me, this didn't really matter much, since I probably won't be using this kind of sphere (it was just for testing).

2. I forgot/didn't realize that glTranslatef doesn't actually change the vertex coordinates, it just multiplies the modelview matrix. So in the vertex shader, gl_Vertex is *always* the coordinates given with glVertex*.

This is kinda frustrating, because I like using gluLookAt once, followed by glTranslatef to place my objects. So here's the workaround I developed (I'd be interested to hear other people's solutions):

Immediately after the gluLookAt call, we grab the modelview matrix, and compute the inverse:

float view[16];float eye[4];glGetFloatv(GL_MODELVIEW_MATRIX, view);// the inverse of the 3x3 rotation part is just the transposefor(int i=0;i<3;i++)	for(int j=0;j<i;j++)		std::swap(view[4 * i + j], view[4 * j + i]);// the inverse of the translation part is just the negativefor(int i=0;i<3;i++)	eye = -view[12 + i];eye[3] = 0;// and clear the translation part so that view is just a rotation matrixfor(int i=0;i<3;i++) {	view[4 * i + 3] = 0;	view[12 + i] = 0;}

Next, when we're setting up the texture matrix to send to the shader, we apply the above guys:

glMatrixMode(GL_TEXTURE);glLoadIdentity();glTranslatef(.5, .5, .5);glScalef(.5, .5, .5);glMultMatrixf(lightProjectionMatrix);glMultMatrixf(lightModelViewMatrix);glMultMatrixf(view);glTranslatef(eye[0], eye[1], eye[2]);

Finally, in the vertex shader, we need to temporarily move into eyespace

shadowTexCoord = gl_TextureMatrix[0] * gl_ModelViewMatrix * gl_Vertex;

Note what's happening here: since we don't know what sorts of translation/rotations we've done since the gluLookAt call, we can only be assured that gl_ModelViewMatrix * gl_Vertex is in eye-space. We then apply the inverse transformation of the *original* modelview matrix from that gluLookAt call; this gets us world-space coordinates. Finally, we can move to light-space and project like we'd expect.

• 40
• 12
• 10
• 10
• 9
• ### Forum Statistics

• Total Topics
631371
• Total Posts
2999605
×