Jump to content
  • Advertisement
Sign in to follow this  

Using D3DXMatrixShadow

This topic is 4791 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

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 )
	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
	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 );
		g_device->SetTransform( D3DTS_WORLD, world );
	D3DXMATRIX* T = GetTranslationMatrix();

	g_device->SetTransform( D3DTS_WORLD, &W );

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

	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
I'm afraid I have nothing to zfight. Even when I strip the scene down to the lone object and its shadow, it still flickers.

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
Unfortunately, turning off ztesting and writing still has no effect!

I am using D3DFMT24_S8, (off the top of my head) - Is that okay?


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.
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.
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
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!