Skip to main content
GameDev.net gamedev.net
🔒 Locked

Shadow Maps

Started by jsaade May 23, 2006 at 7:40 AM 1 replies 1.5k views
Original Post
jsaade
jsaade
I have been trying to use shadow maps in my game. I followed the D3D sample (Dx9) as my game is using dx9. I am doing a flight sim. so my world is mostly outdoors. I am still in early stages of shadow implementation, so i am having some bugs, the rendering of the plane using the same way of the sample works, fine, but if i try with other big models (ex: the terrain), the rendering becomes messed up as it seems the textures are inside each other or something. As i said before i am new to shadow mapping, can it be that the shadow surface buffer is too small?
cwhite
cwhite
Could you post some screenshots and maybe even some code too? I'm not sure exactly what you mean by "textures are inside each other or something."
jsaade
jsaade
sorry about the earlier post, i was a bit in a hurry so here is more explanation about my program:

1st initializing the light:
Lights.push_back(new LightStruct());D3DXVECTOR3 vecDir;ZeroMemory( &(Lights[0]->lt), sizeof(D3DLIGHT9) );Lights[0]->lt.Type = D3DLIGHT_SPOT ;//Lights[0]->lt.Position = D3DXVECTOR3( 0, 1000.0f, -780 );Lights[0]->lt.Position = D3DXVECTOR3( -150, 100, -780 );Lights[0]->lt.Direction = D3DXVECTOR3( 1, -1, 0 );Lights[0]->lt.Range = 10000;//Lights[0]->lt.Attenuation0 =1;Lights[0]->lt.Diffuse.a = 1.0f;		Lights[0]->lt.Diffuse.r = 1.0;Lights[0]->lt.Diffuse.g = 1.0f;Lights[0]->lt.Diffuse.b = 1.0f;Lights[0]->lt.Ambient =  Lights[0]->lt.Specular = Lights[0]->lt.Diffuse;Lights[0]->lt.Theta = 1;Lights[0]->lt.Phi = 1;Game::g_pd3dDevice->SetLight( 0, &(Lights[0]->lt) );Game::g_pd3dDevice->LightEnable( 0, TRUE );Game::g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );


2nd the models and textures are loaded correctly, i tested them with
Drawsubset dx function, in my structure, i have a plane object
and static objects (a bsp is built for these but for now lets say they are objects inside an instance called map.
so normal rendering calling:
mymap->Update();
plane->Render();
gives:
normal dx render

so now i started implementing the shadow map.
on initialization, i create the shadow map and surface:
DWORD dwShaderFlags = D3DXFX_NOT_CLONEABLE;#ifdef DEBUG_VS    dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;#endif#ifdef DEBUG_PS    dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;#endifD3DXCreateEffectFromFile( Game::g_pd3dDevice, "shadowmap.fx", NULL, NULL, dwShaderFlags,                                 NULL, &g_pEffect, NULL );g_pEffect->SetVector( "g_vLightDiffuse", (D3DXVECTOR4 *)&Lights[0]->lt.Diffuse ) ;g_pEffect->SetFloat( "g_fCosTheta", cosf( Lights[0]->lt.Theta ));// Create the shadow map textureGame::g_pd3dDevice->CreateTexture( 512, 512,                                        1, D3DUSAGE_RENDERTARGET,                                        D3DFMT_R32F,                                        D3DPOOL_DEFAULT,                                        &g_pShadowMap,                                        NULL );// Create the depth-stencil bufferGame::g_pd3dDevice->CreateDepthStencilSurface(  512,												512,												D3DFMT_D16,								D3DMULTISAMPLE_NONE,												0,												TRUE,												&g_pDSShadow,												NULL );// Initialize the shadow projection matrix float g_fLightFov = 3.1415f/ 2.0f;D3DXMatrixPerspectiveFovLH( &g_mShadowProj, g_fLightFov, 1, 0.01f, 100.0f);



on rendering:
//get the view matrix of the light:D3DXMATRIXA16 mLightView;D3DXVECTOR3 vPos = Lights[0]->lt.Position;D3DXVECTOR3 vDir = Lights[0]->lt.Direction;mLightView._41 = mLightView._42 = mLightView._43 = 0.0f;D3DXVec3Normalize( &vDir, &vDir );vDir.x += vPos.x;  // vDir denotes the look-at pointvDir.y += vPos.y;vDir.z += vPos.z;D3DXVECTOR3 vUp( 1.0f, 0.0f, 0.0f ); /*assumption!*/D3DXMatrixLookAtLH( &mLightView, &vPos, &vDir, &vUp );// Render the shadow mapLPDIRECT3DSURFACE9 pOldRT = NULL;Game::g_pd3dDevice->GetRenderTarget( 0, &pOldRT );LPDIRECT3DSURFACE9 pShadowSurf;if( SUCCEEDED( g_pShadowMap->GetSurfaceLevel( 0, &pShadowSurf ) ) ){	Game::g_pd3dDevice->SetRenderTarget( 0, pShadowSurf );	SAFE_RELEASE( pShadowSurf );}LPDIRECT3DSURFACE9 pOldDS = NULL;if( SUCCEEDED( Game::g_pd3dDevice->GetDepthStencilSurface( &pOldDS ) ) )	Game::g_pd3dDevice->SetDepthStencilSurface( g_pDSShadow );{	RenderScene(true,&mLightView, &g_mShadowProj );}if( pOldDS ){	Game::g_pd3dDevice->SetDepthStencilSurface( pOldDS );	pOldDS->Release();}Game::g_pd3dDevice->SetRenderTarget( 0, pOldRT );SAFE_RELEASE( pOldRT );D3DXMATRIX *pmView = &Game::GameCam.FinalView;g_pEffect->SetTexture( "g_txShadow", g_pShadowMap );	// Compute the matrix to transform from view space to// light projection space.  This consists of// the inverse of view matrix * view matrix of light * light projection matrixD3DXMATRIXA16 mViewToLightProj;mViewToLightProj = *pmView;D3DXMatrixInverse( &mViewToLightProj, NULL, &mViewToLightProj );D3DXMatrixMultiply( &mViewToLightProj, &mViewToLightProj, &mLightView );D3DXMatrixMultiply( &mViewToLightProj, &mViewToLightProj, &g_mShadowProj );g_pEffect->SetMatrix( "g_mViewToLightProj", &mViewToLightProj );//same as D3DTS_PROJECTION set to device?D3DXMATRIXA16 matProj;D3DXMatrixPerspectiveRH(&matProj, 1, 1, 1.0f, 100000.0f);RenderScene(false, pmView, &matProj);g_pEffect->SetTexture( "g_txShadow", NULL );


the render scene function:
g_pEffect->SetMatrix( "g_mProj", pmProj );	D3DXVECTOR3 v = Lights[0]->lt.Position;    D3DXVECTOR4 v4;    D3DXVec3Transform( &v4, &v, pmView );    g_pEffect->SetVector( "g_vLightPos", &v4 );    *(D3DXVECTOR3*)&v4 = Lights[0]->lt.Direction;    v4.w = 0.0f;  // Set w 0 so that the translation part doesn't come to play    D3DXVec4Transform( &v4, &v4, pmView );  // Direction in view space    D3DXVec3Normalize( (D3DXVECTOR3*)&v4, (D3DXVECTOR3*)&v4 );   g_pEffect->SetVector( "g_vLightDir", &v4 );   bRenderShadow = false;   if( bRenderShadow )        g_pEffect->SetTechnique("RenderShadow");   else		g_pEffect->SetTechnique("RenderScene");   //render the objects:   for(int o =0; o < (int)mymap->staticObjects.size(); ++o)   {		Object * obj = mymap->staticObjects[o];		D3DXMATRIXA16 mWorldView = obj->matWorld;		D3DXMatrixMultiply( &mWorldView, &mWorldView, pmView );		g_pEffect->SetMatrix( "g_mWorldView", &mWorldView );		LPD3DXMESH pMesh = obj->g_pMesh;		UINT cPass;        g_pEffect->Begin( &cPass, 0 );		for( UINT p = 0; p < cPass; ++p )        {           g_pEffect->BeginPass( p );            for( DWORD i = 0; i < obj->g_dwNumMaterials; ++i )            {                D3DXVECTOR4 vDif( obj->g_pMeshMaterials.Diffuse.r,                                   obj->g_pMeshMaterials.Diffuse.g,                                    obj->g_pMeshMaterials.Diffuse.b,                                    obj->g_pMeshMaterials.Diffuse.a );               g_pEffect->SetVector( "g_vMaterial", &vDif );                if( obj->g_pMeshTextures )                    g_pEffect->SetTexture( "g_txScene", obj->g_pMeshTextures );                           g_pEffect->CommitChanges() ;                pMesh->DrawSubset( i ) ;            }            g_pEffect->EndPass();        }		g_pEffect->End();   }    Object * obj = plane;	D3DXMATRIXA16 mWorldView = obj->matWorld;	D3DXMatrixMultiply( &mWorldView, &mWorldView, pmView );	g_pEffect->SetMatrix( "g_mWorldView", &mWorldView );	LPD3DXMESH pMesh = obj->g_pMesh;	UINT cPass;    g_pEffect->Begin( &cPass, 0 );	for( UINT p = 0; p < cPass; ++p )    {        g_pEffect->BeginPass( p );        for( DWORD i = 0; i < obj->g_dwNumMaterials; ++i )        {            D3DXVECTOR4 vDif( obj->g_pMeshMaterials.Diffuse.r,                                obj->g_pMeshMaterials.Diffuse.g,                                obj->g_pMeshMaterials.Diffuse.b,                                obj->g_pMeshMaterials.Diffuse.a );            g_pEffect->SetVector( "g_vMaterial", &vDif );            if( obj->g_pMeshTextures )                g_pEffect->SetTexture( "g_txScene", obj->g_pMeshTextures );            g_pEffect->CommitChanges() ;            pMesh->DrawSubset( i ) ;        }        g_pEffect->EndPass();    }	g_pEffect->End();


please note that the dx clear and begin are called before the rendering process and end is called after it.

so as you can see, i followed the dx sample by word. and results were not very satisfactory, some more screen shots:

Applying shadow map to plane only:
plane

Applying it to road only:
road

Applying it to all the scene 1:
scene1

all the scene 2: (camera moved)
scene2

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.