Sign in to follow this  
Xrystal

[DX9] Slight problem with Shadow Rendering

Recommended Posts

I have successfully, if not fully, created a stencil class to handle reflections and shadows. However, as the image below shows the shadow is not positioned in the place I was expecting it. Instead of being drawn on the floor it is being drawn in the middle of the object it is shadowing. I am sure that it has something to do with my code somewhere but when comparing it to the example project that came with the book (substituting my stencil class functionality as appropriate) I cannot see where the problem is. The relevant Stencil functions are as follows:
void CDXStencil::Start(void)
{
	if (m_enType == enStencilType::Nothing) return;
	m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,	true);
    m_pDevice->SetRenderState(D3DRS_STENCILENABLE,		true);
	m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE,		false);
	m_pDevice->SetRenderState(D3DRS_ZENABLE,			false );
    m_pDevice->SetRenderState(D3DRS_STENCILMASK,		0xFFFFFFFF);
    m_pDevice->SetRenderState(D3DRS_STENCILWRITEMASK,	0xFFFFFFFF);
    m_pDevice->SetRenderState(D3DRS_STENCILZFAIL,		D3DSTENCILOP_KEEP);
    m_pDevice->SetRenderState(D3DRS_STENCILFAIL,		D3DSTENCILOP_KEEP);
	if (m_enType == enStencilType::Reflection)
	{
		m_pDevice->SetRenderState(D3DRS_STENCILFUNC,	D3DCMP_ALWAYS);
		m_pDevice->SetRenderState(D3DRS_STENCILREF,		0x1);
	    m_pDevice->SetRenderState(D3DRS_STENCILPASS,	D3DSTENCILOP_REPLACE);
		m_pDevice->SetRenderState(D3DRS_SRCBLEND,		D3DBLEND_ZERO);
		m_pDevice->SetRenderState(D3DRS_DESTBLEND,		D3DBLEND_ONE);
	}
	if (m_enType == enStencilType::Shadow)
	{
		m_pDevice->SetRenderState(D3DRS_STENCILFUNC,	D3DCMP_EQUAL);
		m_pDevice->SetRenderState(D3DRS_STENCILREF,		0x0);
	    m_pDevice->SetRenderState(D3DRS_STENCILPASS,	D3DSTENCILOP_INCR);
		m_pDevice->SetRenderState(D3DRS_SRCBLEND,		D3DBLEND_SRCALPHA);
		m_pDevice->SetRenderState(D3DRS_DESTBLEND,		D3DBLEND_INVSRCALPHA);
	}
}

void CDXStencil::End(void)
{
	// Restore render states.
	m_pDevice->SetRenderState(D3DRS_STENCILENABLE, false);
	m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
	m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
}

D3DXMATRIX CDXStencil::GetShadowMatrix(float ax, float by, float cz, float dw, D3DXVECTOR3 lDirection, float lType)
{
	D3DXMATRIX matShadow;
	D3DXVECTOR4 lightDirection;
	lightDirection.x = lDirection.x;
	lightDirection.y = lDirection.y;
	lightDirection.z = lDirection.z;
	lightDirection.w = lType;
	D3DXPLANE plane(ax,by,cz,dw);
	D3DXPlaneNormalize(&plane,&plane);
	D3DXMatrixShadow(&matShadow,&lightDirection,&plane);
	return matShadow;
}

The RenderScene code does the following:
// Normal
DrawTeapot(false,false);
DrawMirror();
DrawFloor();
// Shadow
gpShadow->Start();
DrawTeapot(false,true);
gpShadow->End();
// Reflect
gpReflection->Start();
DrawMirror();
gpReflection->SetReflectionStates();
DrawTeapot(true,false);
gpReflection->End();

The DrawTeapot code where the special functionality is :
// draw teapot
gpTeapotWorld->Initialise();
gpTeapotWorld->Position(TeapotPosition);
gpTeapotWorld->Scale(D3DXVECTOR3(1.0f,1.0f,1.0f));
gpMaterial->SetColor(true,true,true,true,1.0f,1.0f,1.0f,0.0f);
if (bReflection) 
{
	gpMaterial->SetColor(true,true,true,true,0.8f,0.8f,0.8f,0.0f);
	gpTeapotWorld->Reflection(gpReflection->GetReflectiveMatrix(0.0f,0.0f,1.0f,0.0f));
}
if (bShadow) 
{
	gpMaterial->SetColor(true,true,true,true,0.2f,0.2f,0.2f,0.0f);
	gpTeapotWorld->Shadow(gpShadow->GetShadowMatrix(0.0f,-1.0f,0.0f,0.0f,D3DXVECTOR3(0.0f,-1.0f,-1.0f),0.0f));
}
gpTeapotWorld->UpdateWorld();
gpMaterial->Use();
gpTexture->StopUsing(0);
gpTeapot->DrawSubset(0);

I've tried different angles of lighting direction to see the effect but the one set is the only one that shows the shadow at all. If someone can point out an area to investigate it would be appreciated. Thanks for taking the time to read through this.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this