Advertisement

Shadow Cap Craziness

Started by August 06, 2004 05:52 PM
5 comments, last by RipTorn 20 years, 4 months ago
Hey, I seem to have run into a little problem with my stencil shadow implementation - namely that the ZFail capping seems to have gone a bit wonky of late. Basically, the problem is this: I can see the dark cap's silhouette through my shadow. a bit like this [Apologies for the poor screengrab, its late, i'm tired, and i've been trying to fix this for a good few hours] Any ideas? The code i'm using to calculate my caps is as follows:

for(unsigned int i=0; i<m_uiNumTriangles; ++i)
{
	for(int j=0; j<3; ++j)
	{
		vertex = pModel->m_KeyFrames[m_uiFrame].Vertices[pModel->m_Indices[i*3+j]];
		if(m_bIsFacingLight==true)
		{
			//Draw Light Cap
			_destLight->AddSingle(vec4f(vertex.x,vertex.y,vertex.z,1.0f)*modelview);
		}
		else
		{
			//Draw End Cap
			_destDark->AddSingle(vec4f(	vertex.x-m_RelPoint.x,vertex.y-m_RelPoint.y,vertex.z-m_RelPoint.z, 0.0f)*modelview);
		}
	}
}



that m_RelPos position is being calculated earlier as follows:

//convert position into object vertex space
//Reverse Object Rotations!
mat4f inverseMatrix;
inverseMatrix = m_Rotation.Inverse();

//Calc Relative Local Position!
m_RelPoint	= inverseMatrix*_Point;		
m_RelPoint	= m_RelPoint-_Position;		

that cap draw function adds the vertices it calculates into a couple of buffers elsewhere, which are later rendererd via VB's. The rendering happens as follows:

glPushAttrib(GL_ALL_ATTRIB_BITS);

//Disable Useless Stuff
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);

//Set Shade Model
glPolygonMode(GL_BACK,GL_FILL);
glShadeModel(GL_FLAT);

//Disable Writing to Colour Buffers, and set no Depth buffer mask
glColorMask(0, 0, 0, 0);
glDepthMask(GL_FALSE);

//Enable Culling, and set Counter-Clockwise as Front Faces
glEnable(GL_CULL_FACE);
glFrontFace(GL_CW);	

//stencil clear value
glClearStencil(1);
//Stencil test always passes, for all mask bits
glStencilFunc(GL_ALWAYS, 1, 0xffffffff);
//Clear Buffer
glClear(GL_STENCIL_BUFFER_BIT);
//Enable Stencil
glEnable(GL_STENCIL_TEST);

//setup culling
glCullFace( GL_FRONT );
glStencilOp(GL_KEEP,GL_INCR,GL_KEEP);

g_Renderer->DrawBufferVec4f( &m_Shadows, GL_QUADS );
g_Renderer->DrawBufferVec4f( &m_ShadowLightCaps, GL_TRIANGLES );
g_Renderer->DrawBufferVec4f( &m_ShadowDarkCaps, GL_TRIANGLES );

glCullFace( GL_BACK );
glStencilOp(GL_KEEP,GL_DECR,GL_KEEP);

g_Renderer->DrawBufferVec4f( &m_Shadows, GL_QUADS );
g_Renderer->DrawBufferVec4f( &m_ShadowLightCaps, GL_TRIANGLES );
g_Renderer->DrawBufferVec4f( &m_ShadowDarkCaps, GL_TRIANGLES );

g_Renderer->ShadowZFailEnd();

that final function just takes care of drawing a blended shadowing quad over the viewport and resets states etc. So, any ideas? This has been bugging me all day, and i just can't seem to get my head around it. As always, any help and suggestions would be greatly appreciated. Cheers, Ben
the winding of the triangles used in the rear cap of the shadow volume should be reversed...
that may be part of the problem...
Advertisement
I just tried reversing the draw order [by reversing the face culling in GL] for the dark-caps, with no success.

Any more ideas?

Cheers,
Ben
reversing the draw order is not the same as by reversing the face culling in GL.
there could allso be a zfar problem.
Good point on the face culling, i just didn't think about that. However, even after truely reversing the draw order (this time by reversing the order that the vertices are processed) the same problem persists.

Could you clarify exactly what you mean by a possible ZFar problem? [excuse my ignorance if that seems like a really stupid question].

Cheers,
Ben
Well basicly opengl culls any pixel that is written beyond the zfar value, this means that the stencil volume endcap might not even be rendered.

It might just simply be to far away.
The solution is either to increase the z-far value or/and making the shadow extrude less.
Advertisement
it may be due to the way you are rendering the extruded shilouette, that you need to reverse the winding of the near cap (or light cap as you call it) of the volume..

eg:

for(unsigned int i=0; i<m_uiNumTriangles; ++i){	if(m_bIsFacingLight==true)	{		for(int j=0; j<3; ++j)		{			vertex = pModel->m_KeyFrames[m_uiFrame].Vertices[pModel->m_Indices[i*3+j]];					//Draw Light Cap				_destLight->AddSingle(vec4f(vertex.x,vertex.y,vertex.z,1.0f)*modelview);		}	}	else	{		for(int j=2; j>=0; j--)		{		vertex = pModel->m_KeyFrames[m_uiFrame].Vertices[pModel->m_Indices[i*3+j]];					//Draw End Cap			_destDark->AddSingle(vec4f(	vertex.x-m_RelPoint.x,vertex.y-m_RelPoint.y,vertex.z-m_RelPoint.z, 0.0f)*modelview);		}	}}


are you absolutly sure that the extruded rear cap geometry lines up perfectly with the extruded shilouette geometry?

*btw*

you should probably use GL_INCR_WRAP not GL_INCR, (and GL_DECR_WRAP) since your using a small inital stencil clear value (1) - either that or use a higher value - 128 being optimal with an 8bit stencil.

This topic is closed to new replies.

Advertisement