Jump to content
  • Advertisement
Sign in to follow this  
LevyDee

Revisiting Shadow Mapping =)

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

I had been working on shadow mapping a while back, to implement a basic system for it, but never got it finished and working. I am now back at that point, and have everything in place, but am not getting the proper results! I apologize in advanced for the length of material to look through!

My shadow map texture and depthstencil creation

////Create shadow map texture
if(_d3dDevice->CreateTexture(512, 512, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R32F, D3DPOOL_DEFAULT, &_shadowMap, 0) != D3D_OK)
ErrorMessenger::ReportMessage("Failed to create shadow map texture!", __FILE__, __LINE__);

////Create depth map
if(_d3dDevice->CreateDepthStencilSurface(512, 512, D3DFMT_D16, D3DMULTISAMPLE_NONE, 0, true, &_dssShadow, 0) != D3D_OK)
ErrorMessenger::ReportMessage("Failed to create depth surface!", __FILE__, __LINE__);


Map generation shader

void vsRenderShadowMap(float4 iPos : POSITION0,
out float4 oPos : POSITION0,
out float oDepth : TEXCOORD0)
{
float4 vWorldPos = mul(iPos, world);
float4 vLightViewPos = mul(vWorldPos, lView);
oPos = mul(vLightViewPos, lProj);

oDepth = oPos.z / oPos.w;
}

float4 psRenderShadowMap(float iDepth : TEXCOORD0) : COLOR0
{
return float4(iDepth, 0.0f, 0.0f, 1.0f);
}


Map generation render loop

//Back up old render targets
IDirect3DSurface9* oldDS;
_d3dDevice->GetDepthStencilSurface(&oldDS);

IDirect3DSurface9* oldRT;
_d3dDevice->GetRenderTarget(0, &oldRT);

//Set new render target and new depth surface
IDirect3DSurface9* shadowSurf;
_shadowMap->GetSurfaceLevel(0, &shadowSurf);
_d3dDevice->SetRenderTarget(0, shadowSurf);
_d3dDevice->SetDepthStencilSurface(_dssShadow);

//Clear the render target and begin to render
_d3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

_d3dDevice->BeginScene();

//Loop through and draw everything
for(int i = 0; i < _worlds[_views[view].world].Size(); i++)
{
if(_worlds[_views[view].world]->GetEffect()->SetTechnique("RenderShadowMap") != D3D_OK)
ErrorMessenger::ReportMessage("Failed to set technique!", __FILE__, __LINE__);

if(_worlds[_views[view].world]->GetEffect()->SetMatrix("lView", &lightView) != D3D_OK)
ErrorMessenger::ReportMessage("Failed to set world matrix!", __FILE__, __LINE__);

if(_worlds[_views[view].world]->GetEffect()->SetMatrix("lProj", &lightProj) != D3D_OK)
ErrorMessenger::ReportMessage("Failed to set projection matrix!", __FILE__, __LINE__);

//Draw the item
_worlds[_views[view].world]->Draw(_d3dDevice);
}

_d3dDevice->EndScene();

//After drawing to the shadow map, set old render targets back.
_d3dDevice->SetRenderTarget(0, oldRT);
oldRT->Release();

_d3dDevice->SetDepthStencilSurface(oldDS);
oldDS->Release();


Shader to render using the shadowmap

void vsRenderSceneWithLight(float4 iPos : POSITION0,
float4 iNormal : NORMAL,
float2 iUV : TEXCOORD0,
out float4 oPos : POSITION0,
out float2 oUV : TEXCOORD0,
out float4 oLightPos : TEXCOORD1,
out float oDepth : TEXCOORD2)
{
//Get the vertices world position
float4 vWorldPos = mul(iPos, world);

//Transform the position to the camera view and perspective
float4 vViewPos = mul(vWorldPos, cView);
oPos = mul(vViewPos, cProj);

//Get the pixel depth from the view of the camera
oDepth = (oPos.z / oPos.w);

//Transform the position to the light view and perspective
float4 lViewPos = mul(vWorldPos, lView);
oLightPos = mul(lViewPos, lProj);

oUV = iUV;
}

float4 psRenderSceneWithLight(float2 iUV : TEXCOORD0,
float4 iLightPos : TEXCOORD1,
float iDepth : TEXCOORD2) : COLOR0
{
//Get UV coordinates for sampling depth map
iLightPos.xyz /= iLightPos.w;
float2 depthUV = iLightPos.xy * float2(0.5f, -0.5f) + 0.5f;

//Sample depth map using new UV coordinates
float lDepth = tex2D(ShadowMapSampler, depthUV).x;

//Returning test color before including my texture colors
if(iDepth >= lDepth)
return float4(0.0f, 0.0f, 0.0f, 1.0f);

else
return float4(1.0f, 1.0, 1.0f, 1.0f);
}


Render loop using the shadow map

IDirect3DSurface9* buffer;
_views[view].swapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &buffer);
_d3dDevice->SetRenderTarget(0, buffer);

_d3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, _views[view].targetClear, 1.0f, 0);

_d3dDevice->BeginScene();

//Loop through and draw everything in the world
for(int n = 0; n < _worlds[_views[view].world].Size(); n++)
{
//Set lighting parameters
if(lighting)
{
//Set the lighting technique
if(FAILED(_worlds[_views[view].world][n]->GetEffect()->SetTechnique("RenderSceneWithLight")))
ErrorMessenger::ReportMessage("Failed to set technique!", __FILE__, __LINE__);

//Set shadow map texture
if(FAILED(_worlds[_views[view].world][n]->GetEffect()->SetTexture("tShadowMap", _shadowMap)))
ErrorMessenger::ReportMessage("Failed to set texture!", __FILE__, __LINE__);
}
else if(!lighting)
{
if(!_worlds[_views[view].world][n]->GetPicked())
{
if(_worlds[_views[view].world][n]->GetEffect()->SetTechnique("RenderSceneWithoutLight") != D3D_OK)
ErrorMessenger::ReportMessage("Failed to set technique!", __FILE__, __LINE__);
}
else
if(_worlds[_views[view].world][n]->GetEffect()->SetTechnique("PickObject") != D3D_OK)
ErrorMessenger::ReportMessage("Failed to set technique!", __FILE__, __LINE__);
}

//Set view and projection matrices
if(_worlds[_views[view].world][n]->GetEffect()->SetMatrix("cView", &_camera->GetViewViewMatrix(view)) != D3D_OK)
ErrorMessenger::ReportMessage("Failed to set View Matrix!", __FILE__, __LINE__);

if(_worlds[_views[view].world][n]->GetEffect()->SetMatrix("cProj", &_camera->GetViewProjectionMatrix(view)) != D3D_OK)
ErrorMessenger::ReportMessage("Failed to set Projection Matrix!", __FILE__, __LINE__);

//Draw the item(world matrix is set in here)
_worlds[_views[view].world][n]->Draw(_d3dDevice);

//Kill object if requested to
if(_worlds[_views[view].world][n]->GetKill())
_worlds[_views[view].world].Free(n);
}

_d3dDevice->EndScene();

_views[view].swapChain->Present(0, 0, 0, 0, 0);

buffer->Release();


I know its kinda a lot to look through, but just by doing a quick read through, is there anything that stands out as wrong? Here is the shadow map I am getting. Edit: I have looked at my depth surface in pix, and it looks fine. This blue map is just saving the surface to file

ojMoZ.jpg

And this is the in-game result
AT77G.jpg

It seems that the distance of my camera effects what is colored

Share this post


Link to post
Share on other sites
Advertisement
Hi, i think that [color="#000000"]oPos[color="#666600"].[color="#000000"]z [color="#666600"]/[color="#000000"] oPos[color="#666600"].[color="#000000"]w shall be done in pixel shader instead of vertex shader. also you should add small value to depth (during depth comparison)

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!