Advertisement

Shadows volumes: what's wrong ??!

Started by November 09, 2004 08:33 AM
25 comments, last by RipTorn 20 years ago
i'm playng a bit with shadows volumes. i've wrote a small class for an object, with faces and vertexes and i've created the relative shadow volume. in my render function i clear all the biffers, then render my scene (it's a simple high tessellated floor with a quad on it that should cast the shadow, nothing special) with a wireframe version of the casted volume this is perfect) , then i set the opengl states for the stencil, render the shadow and flush. Are these the correct passes or should i do some other things? the real problem is that except the floor , the quad and the wireframe volume, nothing more is rendered. The shadows doesn't appear. It's like if the stencil buffer is not filled. This is my render function:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glLoadIdentity();	
gluLookAt(0,3,10, 0,0,0, 0,1,0);
Point3 lpos(LightPosition[0],LightPosition[1],LightPosition[2]);
glLightfv( GL_LIGHT1, GL_POSITION, LightPosition );

RenderScene();	// the floor and the shadow caster quad
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
Quad.DrawShadowVolume(lpos);	
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );


glPushAttrib( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT | GL_STENCIL_BUFFER_BIT );
glDisable( GL_LIGHTING );	// Turn Off Lighting
glDepthMask( GL_FALSE );	// Turn Off Writing To The Depth-Buffer
glDepthFunc( GL_LEQUAL );
glEnable( GL_STENCIL_TEST );	// Turn On Stencil Buffer Testing
glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );	// Don't Draw Into The Colour Buffer
glStencilFunc( GL_ALWAYS, 1, 0xFFFFFFFFL );

glFrontFace(GL_CCW);
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
Quad.DrawShadowVolume(lpos);

glFrontFace(GL_CW);
glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
Quad.DrawShadowVolume(lpos);

glFrontFace( GL_CCW );
glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );	

//draw a shadowing rectangle covering the entire screen
glColor4f( 0.0f, 0.0f, 0.0f, 0.4f );
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glStencilFunc( GL_NOTEQUAL, 0, 0xFFFFFFFFL );
glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
glPushMatrix();
glLoadIdentity();
glBegin( GL_TRIANGLE_STRIP );
	glVertex3f(-0.1f, 0.1f,-0.10f);
	glVertex3f(-0.1f,-0.1f,-0.10f);
	glVertex3f( 0.1f, 0.1f,-0.10f);
	glVertex3f( 0.1f,-0.1f,-0.10f);
glEnd();
glPopMatrix();
glPopAttrib();


glColor4f(0.7f, 0.4f, 0.0f, 1.0f);	// Set Color To An Orange
glDisable(GL_LIGHTING);		        // Disable Lighting
glDepthMask(GL_FALSE);			// Disable Depth Mask
glColor4f(0.75f, 0.0f, 0.0f, 1.0f);
glPushMatrix();
glTranslatef(LightPosition[0],LightPosition[1],LightPosition[2]);
gluSphere(sphere, 0.1f, 30, 30);        //draw a sphere with the light position
glPopMatrix();
glEnable(GL_LIGHTING);			// Enable Lighting
glDepthMask(GL_TRUE);		

glFlush();	



this is the code from the tutorial #27 on NeHe. Any advices?
Is backface culling enabled ?
Do you set the stencil mask somewhere ?

BTW, instead of drawing a shadow quad, you should first render the scene with only ambient light draw shadow volumes, and then redraw the scene with diffuse and specular light (and this for all point lights). This will look much better.
SaM3d!, a cross-platform API for 3d based on SDL and OpenGL.The trouble is that things never get better, they just stay the same, only more so. -- (Terry Pratchett, Eric)
Advertisement
this is my InitGl function:
bool InitGL(void){	glShadeModel(GL_SMOOTH);							// Enable Smooth Shading	glClearColor(0.0f, 0.0f, 0.0f, 0.5f);				// Black Background	glClearDepth(1.0f);									// Depth Buffer Setup	glClearStencil(0);									// Stencil Buffer Setup	glEnable(GL_DEPTH_TEST);							// Enables Depth Testing	glDepthFunc(GL_LEQUAL);								// The Type Of Depth Testing To Do//	glCullFace(GL_BACK);								// Set Culling Face To Back Face//	glEnable(GL_CULL_FACE);								// Enable Culling	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	// Really Nice Perspective Calculations	float LightAmb[] = { 0.2f, 0.2f, 0.2f, 1.0f};				float LightDif[] = { 0.6f, 0.6f, 0.6f, 1.0f};	glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmb);			// Set Light1 Ambience	glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDif);			// Set Light1 Diffuse	glEnable(GL_LIGHTING);	glEnable(GL_LIGHT1);	glEnable(GL_BLEND);	glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);		glClearColor(0.1f, 1.0f, 0.5f, 1.0f);				// Set Clear Color (Greenish Color)	return true;}


if i enable backface culling nothing is rendered o_O

i don't know if your using z-fail or not(you should). so here is the code for that

glFrontFace(GL_CCW);
glStencilOp(GL_KEEP, GL_DECR, GL_KEEP);
Quad.DrawShadowVolume(lpos);

glFrontFace(GL_CW);
glStencilOp(GL_KEEP, GL_INCR, GL_KEEP);
Quad.DrawShadowVolume(lpos);


other than that, have you tried fiddeling with this line
glStencilFunc( GL_NOTEQUAL, 0, 0xFFFFFFFFL );

try
glStencilFunc( GL_EQUAL, 0, 0xFFFFFFFFL );
IF the entire screen isn't shadowed with this, then it's a problem with the rendering of the black shadow polygon

allso i see that the shadow polygon is renderd at z=-0.10f
what is your z near?
try to put glDisable(GL_DEPTH_TEST);
right before glBegin( GL_TRIANGLE_STRIP );

it's happening something really wierd: instead of drawing the shadow rectangle, appears its CONTOUR o_O
but i've noticed that if i comment these lines:
/*glFrontFace(GL_CCW);
glStencilOp(GL_KEEP, GL_DECR, GL_KEEP);
Quad.DrawShadow(LightPos);*/
and do only this rendering pass:
glFrontFace(GL_CW);
glStencilOp(GL_KEEP, GL_INCR, GL_KEEP);
Quad.DrawShadow(LightPos);
nothing changes. but if i do the inverse, the shadow isn't rendered..
Advertisement
Quote: Original post by b3rs3rk
it's happening something really wierd: instead of drawing the shadow rectangle, appears its CONTOUR o_O


Could be because you're drawing the shadow volume in line mode with depth write enabled.
Hmmm did you try the z-fail way (the z-pass way can give bad results when the camera is inside the shadow volume) ?
SaM3d!, a cross-platform API for 3d based on SDL and OpenGL.The trouble is that things never get better, they just stay the same, only more so. -- (Terry Pratchett, Eric)
with z-fail the results are the same :/
Hmmm could you try you shadows step by step ?
- actually draw the shadow volume without the stencil stuff (and with blending) and see if its orientation is OK (draw front and back sides with different colors if necessary) ;
- test the incrementing pass alone for the shadow volume ;
- test the decrementing pass alone (initialize the stencil to 1).

This should help you figure what's wrong.
SaM3d!, a cross-platform API for 3d based on SDL and OpenGL.The trouble is that things never get better, they just stay the same, only more so. -- (Terry Pratchett, Eric)
the incrementing pass draws the contour of the shadow.

the decrementing pass instead, draws nothing:

glStencilFunc( GL_ALWAYS, 1, 0xFFFFFFFFL );
glFrontFace(GL_CCW);
glStencilOp(GL_KEEP, GL_DECR , GL_KEEP);
Quad.DrawShadow(LightPos);

i'm slightly becoming mad...

This topic is closed to new replies.

Advertisement