Game Development Reference
In-Depth Information
write to it again. Hence, we avoid overwriting a pixel and thus avoid
double blending.
void RenderShadow()
{
Device->SetRenderState(D3DRS_STENCILENABLE, true);
Device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL);
Device->SetRenderState(D3DRS_STENCILREF, 0x0);
Device->SetRenderState(D3DRS_STENCILMASK, 0xffffffff);
Device->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff);
Device->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
Device->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
Device->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR);
Next, we compute the shadow transformation and translate the shadow
into the appropriate place in the scene.
// compute the transformation to flatten the teapot into
// a shadow.
D3DXVECTOR4 lightDirection(0.707f, -0.707f, 0.707f, 0.0f);
D3DXPLANE groundPlane(0.0f, -1.0f, 0.0f, 0.0f);
D3DXMATRIX S;
D3DXMatrixShadow(&S, &lightDirection, &groundPlane);
D3DXMATRIX T;
D3DXMatrixTranslation(&T, TeapotPosition.x, TeapotPosition.y,
TeapotPosition.z);
D3DXMATRIXW=T*S;
Device->SetTransform(D3DTS_WORLD, &W);
Lastly, we set a black material at 50% transparency, disable depth test-
ing, render the shadow, and then clean up by re-enabling the depth
buffer and disabling alpha blending and stencil testing. We disable the
depth buffer to prevent z-fighting , which is a visual artifact that occurs
when two different surfaces have the same depth values in the depth
buffer; the depth buffer doesn't know which should be in front of the
other, and an annoying flicker occurs. Because the shadow and floor lie
on the same plane, z-fighting between them will most likely occur. By
rendering the floor first and the shadow after with depth testing dis-
abled, we guarantee our shadow will be drawn over the floor.
Note: An alternative method for preventing z-fighting is to use the
Direct3D depth bias mechanism. See the D3DRS_DEPTHBIAS and
D3DRS_SLOPESCALEDEPTHBIAS render states in the SDK documenta-
tion for details.
Device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
Search WWH ::




Custom Search