Shadow Maps
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?
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."
sorry about the earlier post, i was a bit in a hurry so here is more explanation about my program:
1st initializing the light:
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:
so now i started implementing the shadow map.
on initialization, i create the shadow map and surface:
on rendering:
the render scene function:
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:
Applying it to road only:
Applying it to all the scene 1:
all the scene 2: (camera moved)
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:
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:
Applying it to road only:
Applying it to all the scene 1:
all the scene 2: (camera moved)
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement