Jump to content
  • Advertisement
Sign in to follow this  
Xrystal

[DX9] Slight problem with Shadow Rendering

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

If you intended to correct an error in the post then please contact us.

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
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!