Sign in to follow this  
sipickles

Using D3DXMatrixShadow

Recommended Posts

Hello, I am having trouble implementing a shadow correctly. Here's my code:
void SceneObject::RenderShadow( D3DXPLANE* plane, D3DXVECTOR4* lightDirection, D3DXMATRIX *world )
{
	// Ignore the object if it has no mesh.
	if( m_mesh == NULL )
		return;
/*
	g_device->SetRenderState(D3DRS_STENCILENABLE,    true);
    g_device->SetRenderState(D3DRS_STENCILFUNC,      D3DCMP_EQUAL);
    g_device->SetRenderState(D3DRS_STENCILREF,       0x0);
    g_device->SetRenderState(D3DRS_STENCILMASK,      0xffffffff);
    g_device->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff);
    g_device->SetRenderState(D3DRS_STENCILZFAIL,     D3DSTENCILOP_KEEP);
    g_device->SetRenderState(D3DRS_STENCILFAIL,      D3DSTENCILOP_KEEP);
    g_device->SetRenderState(D3DRS_STENCILPASS,      D3DSTENCILOP_INCR); // increment to 1
*/
	D3DXMATRIX S;
	D3DXMatrixShadow( &S, lightDirection, plane);
/*
	// Check if the object's world tranformation matrix has been overridden.
	if( world == NULL )
		g_device->SetTransform( D3DTS_WORLD, &m_worldMatrix );
	else
		g_device->SetTransform( D3DTS_WORLD, world );
*/
	D3DXMATRIX* T = GetTranslationMatrix();
	D3DXMATRIX W = *T * S;

	g_device->SetTransform( D3DTS_WORLD, &W );

	//g_device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
	g_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
	g_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

	D3DMATERIAL9 mtrl;
	mtrl.Ambient  = BLACK;
	mtrl.Diffuse  = BLACK;
	mtrl.Specular = BLACK;
	mtrl.Emissive = BLACK;
	mtrl.Power    = BLACK;
	mtrl.Diffuse.a = 1.0f;

	g_device->SetMaterial( &mtrl );
	g_device->SetTexture( 0, NULL );

//	g_device->SetRenderState(D3DRS_ZENABLE, false);
	
	m_mesh->Render( false );

//	g_device->SetRenderState(D3DRS_ZENABLE, true);
	g_device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
	g_device->SetRenderState(D3DRS_STENCILENABLE,    false);

	
If I comment out the stencilling, as above, I see the shadow by my object, pancaked correctly, but it flickers like a bugger! If I turn on the stencilling I can only make out the outline of the shadow.... The code above is taken from chapter 8, of luna's book, introduction to DX9. Seems to work well for him! This line: m_mesh->Render( false ); Simply renders the mesh without changing any materials. Is this a problem with my stencilling? I'm not sure how Frank Lunas code works, because when I've used stencilling before, I've rendered to the stencil buffer, to create a mask , then render the masked object. Yet luna renders only once. Please Help! Simon

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
There's not enough information to diagnose this but it sounds kind of like a Z fight. Try enabling Z-bias on it or project it upwards along the plane's normal a smidgeon. Unless of course you're not even rendering anything on the plane in which case it'd have nothing to z-fight with.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Is culling enabled? If not that could cause the triangles of one side to zfight with triangles on the other. Just a thought. Does it happen when you render the shadow without the object? I see you've messed with disabling the zbuffer. Have you also tried it with ZWRITEENABLE disabled too?

Share this post


Link to post
Share on other sites
Hi there sipickles,
How are you doing?

The Problem
Depth/Stencil Format and ZFighting.

The Solution
I think you are having an issue with your z buffer.For the purpose of your exercise I would set an AutoDepthStencilFormat of D3DFMT_D24S8, this will give you 24 bits for the depth buffer (zbuffer) and 8 bits for the stencil buffer.
i.e.
presentParams.EnableAutoDepthStencil = true;
presentParams.AutoDepthStencilFormat = D3DFMT_D24S8;
and then create your device as per normal.

Should suffice for your purposes. When you are rendering objects like a shadow very close to another plane you might see the flickering as the 2 objects are fighting for z dominance. What you can do to reduce this or remove this is to turn of the z testing.
i.e.
d3dDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);

This might reduce your problem.

PS: remember to switch it back on after you have rendered your shadow.

I hope this helps.
Take care buddy.

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