Sign in to follow this  
themadme

DirectX Shadow Example

Recommended Posts

themadme    122
Hi everyone, I have a curious question which is, when creating a shadow map in a scene, do you need to build a shadow map containing every object including a float floor plane? Reason for this questions is that i have been messing around with the frank luna shadow map example as well as the directx sdk one. For both scenes, I remove the code that renders the "floor" when building a shadow map. By doing this, it causes the shadows of the objects in the scene not be rendered. Why does this happen? Has anyone done this before and knows the answer? Kind regards, Lee

Share this post


Link to post
Share on other sites
Erik Rufelt    5901
Post a screenshot how it looks with the floor, and another how it looks without the floor, and if it's not immediately apparent explain how you expect it to look without the floor.

Share this post


Link to post
Share on other sites
themadme    122
This is before:

http://smg.photobucket.com/albums/v317/the_mad_me/?action=view¤t=Before.jpg

and this is after:

http://smg.photobucket.com/albums/v317/the_mad_me/?action=view¤t=After.jpg

I have the same situation with my directx application, it only renders the shadows if the floor is casting a shdaow?

In my XNA applcaiton i did not need to have the floor or rooms to cast a shadow, as you can see:

http://www.youtube.com/watch?v=cKy--FULN7s

So why in directx do i need to have the floor to cast a shadow to work but not in xna?

I thought XNA is basically directx?

Share this post


Link to post
Share on other sites
themadme    122
Hmm pix ... do you need like visual studio 2003 to get that to work? Cause i dont have it.

I tried to use PerfHud by nvidia but dont really get the results i would like to know example the depth values :(

Share this post


Link to post
Share on other sites
redllar    134
Have you tried the soft-edge shadow map demo from GD here at http://www.gamedev.net/reference/articles/article2193.asp ? It's a DX9 project. Commenting out the first g_pScene->DrawSubset(0) call in the cpp should get you another one to test with.

Also, PIX is a utility that comes with the DX SDK. You should be able to get to it via the Samples Browser.

Share this post


Link to post
Share on other sites
Erik Rufelt    5901
How is the floor drawn, and do you only remove the actual draw-call (like DrawPrimitives)?
Perhaps some render-states are set up when drawing the floor that are also accidentally removed when you stop drawing it. If the same thing works in XNA, then it seems very likely that you either remove some render-state or don't set the correct vertex buffers or similar, causing the shadow-casters to also not be drawn correctly when you remove the floor. Or if the floor is drawn last it could be the other way around, that the shadow map isn't used correctly when drawing the shadow pass, for similar reasons.

Share this post


Link to post
Share on other sites
themadme    122
Thanks for the replies everyone

Ill try out that soft shadow example and everytime i use PIX to debug a frame of my app, it always crash :(

The floor is drawn like any other mesh, mSceneMesh->DrawSubset(j), and thats what i comment out when building the shadow:

Frank Lunar example


void ShadowMapDemo::drawScene()
{
drawShadowMap();

gd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 100, 149, 237 ), 1.0f, 0L );
HR(gd3dDevice->BeginScene());

mSky->draw();

HR(mFX->SetTechnique(mhTech));

HR(mFX->SetValue(mhLight, &mLight, sizeof(SpotLight)));
HR(mFX->SetValue(mhEyePosW, &gCamera->pos(), sizeof(D3DXVECTOR3)));
HR(mFX->SetTexture(mhShadowMap, mShadowMap->d3dTex()));

UINT numPasses = 0;
HR(mFX->Begin(&numPasses, 0));
HR(mFX->BeginPass(0));

// Draw Scene mesh.
HR(mFX->SetMatrix(mhLightWVP, &(mSceneWorld*mLightVP)));
HR(mFX->SetMatrix(mhWVP, &(mSceneWorld*gCamera->viewProj())));
HR(mFX->SetMatrix(mhWorld, &mSceneWorld));
for(UINT j = 0; j < mSceneMtrls.size(); ++j)
{
HR(mFX->SetValue(mhMtrl, &mSceneMtrls[j], sizeof(Mtrl)));

if(mSceneTextures[j] != 0)
{
HR(mFX->SetTexture(mhTex, mSceneTextures[j]));
}
else
{
HR(mFX->SetTexture(mhTex, mWhiteTex));
}

HR(mFX->CommitChanges());
HR(mSceneMesh->DrawSubset(j));
}

// Draw car mesh.
HR(mFX->SetMatrix(mhLightWVP, &(mCarWorld*mLightVP)));
HR(mFX->SetMatrix(mhWVP, &(mCarWorld*gCamera->viewProj())));
HR(mFX->SetMatrix(mhWorld, &mCarWorld));
for(UINT j = 0; j < mCarMtrls.size(); ++j)
{
HR(mFX->SetValue(mhMtrl, &mCarMtrls[j], sizeof(Mtrl)));

if(mCarTextures[j] != 0)
{
HR(mFX->SetTexture(mhTex, mCarTextures[j]));
}
else
{
HR(mFX->SetTexture(mhTex, mWhiteTex));
}

HR(mFX->CommitChanges());
HR(mCarMesh->DrawSubset(j));
}

HR(mFX->EndPass());
HR(mFX->End());

mGfxStats->display();

HR(gd3dDevice->EndScene());

D3DXMATRIX mat;

D3DXVECTOR2 scaling(0.25f,0.25f);

D3DXMatrixTransformation2D(&mat,NULL,0.0,&scaling, NULL, 0.0f, NULL);

D3DXVECTOR3 pos = D3DXVECTOR3(10.0f, 10.0f, 0.0f);

pSprite->SetTransform(&mat);

pSprite->Begin(D3DXSPRITE_ALPHABLEND);
pSprite->Draw(mShadowMap->d3dTex(), NULL, NULL, &pos, 0xFFFFFFFF);
pSprite->End();

// Present the backbuffer.
HR(gd3dDevice->Present(0, 0, 0, 0));
}

void ShadowMapDemo::drawShadowMap()
{
mShadowMap->beginScene();
HR(gd3dDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 0, 0, 0 ), 1.0f, 0));

HR(mFX->SetTechnique(mhBuildShadowMapTech));

UINT numPasses = 0;
HR(mFX->Begin(&numPasses, 0));
HR(mFX->BeginPass(0));

// Draw scene mesh.
HR(mFX->SetMatrix(mhLightWVP, &(mSceneWorld*mLightVP)));
HR(mFX->CommitChanges());
for(UINT j = 0; j < mSceneMtrls.size(); ++j)
{
//comment out floor
//HR(mSceneMesh->DrawSubset(j));
}

// Draw car mesh.
HR(mFX->SetMatrix(mhLightWVP, &(mCarWorld*mLightVP)));
HR(mFX->CommitChanges());
for(UINT j = 0; j < mCarMtrls.size(); ++j)
{
HR(mCarMesh->DrawSubset(j));
}


HR(mFX->EndPass());
HR(mFX->End());

mShadowMap->endScene();
}





The floor is not drawn last as you can see above, perhaps there is some sort of render state that is missing. Though i cant think what it would be .... Any one have any ideas?

Thanks

[Edited by - themadme on March 15, 2010 12:40:54 PM]

Share this post


Link to post
Share on other sites
Erik Rufelt    5901
If that draw is all you comment out I don't see how it could influence things, but the documentation for DrawSubset says the following:
Quote:

An attribute table is used to identify areas of the mesh that need to be drawn with different textures, render states, materials, and so on. In addition, the application can use the attribute table to hide portions of a mesh by not drawing a given attribute identifier (AttribId) when drawing the frame.


Perhaps that particular code example relies on some attribute in the mesh. Have you tried using your own meshes?

To post code, use [source]source-code[/source] tags around it, as it's very hard to read now. It will look like this:

int asdf() {
return 0;
}

Share this post


Link to post
Share on other sites
themadme    122
Thanks dude, i was wondering what the code comment was.

Well i have my own directx application and it can only render shadows if the floor is casting a shadow (using my own models).

So nothing to do with the models ... maybe something to do with draw subset ... wonder what xna does differently to directx for drawing meshes.

Share this post


Link to post
Share on other sites
themadme    122
Oh this is just a tip but in a thread i had read http://www.gamedev.net/community/forums/topic.asp?topic_id=505893

When casting shadow maps from a directional light, instead of caluclatiing the centroid of the camera frustrum, which involves calculating the corners and etc. You could use the cameras forward direction, since that is already calculated for the camera wolrd matrix. Just use the forward direction times that by half of cameras far clip distance. Thus more cheaper i think

Share this post


Link to post
Share on other sites
themadme    122
I jsut realised that the texture that you create for the shadow map in directx is completely inverse to xna.

I dont understand, cause in xna when you created a texure its like a blue colour for the shadows and everything else is white but in directx its white that represents the shadows and blue for everythign else.

Thats pretty weird

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