Jump to content
  • Advertisement
Sign in to follow this  
leet bix

Getting depth buffer

This topic is 3408 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'm trying to get the depth buffer, which as far as I'm aware can be gotten like this: PDIRECT3DSURFACE9 pSurfDS; pd3dDevice->SetRenderState(D3DRS_ZENABLE, TRUE); RenderScene(); g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE); g_pd3dDevice->GetDepthStencilSurface(pSurfDS); although I need it as a texture so I can pass it to a pixel shader, how do I set this to a texture? Thanks

Share this post


Link to post
Share on other sites
Advertisement
D3D9 doesn't support that functionality natively, it's new for D3D10. There are vendor-specific hacks for readback of a z-buffer, but they're aimed at shadow mapping. Lookup hardware shadow maps for Nvidia, and Fetch4 for ATI.

Share this post


Link to post
Share on other sites
Ok, thank you.

Edit: I've just read something about shadow mapping, and I've read this:

"use the light's depth buffer (shadow map).."

does this mean a shodow map is effectively a depth buffer converted into a texture representing the interpolated z values?

Share this post


Link to post
Share on other sites
Shadow mapping works by rendering the scene from the view of the light source. But this view is not displayed on the screen instead the corresponding depth buffer is stored for this light source. Then, when rendering your scene, you can find out if a light source can "see" the object you are now rendering by transforming your object to the light source coordinate system in checking the light source's depth buffer. If this transformed object "survives" the check against the light source's depth buffer then the light source can "see" the object and hence it is lit and not in shadow.

Share this post


Link to post
Share on other sites
When the depth stencil is created for the light, isn't it changed into a texture then it computes weather a pixel is occluded? Or does it just leave it as the depth stencil surface and compare with the view of the camera? If it's the first, would that not suggest there's a fairly easy way of creating it as there seem to be a lot of shadow map code around.

Share this post


Link to post
Share on other sites
Its the first, a texture gets written with the depth values as viewed from the light source. So you end up with one shadow (depth) map per light source. When rendering your scene you first have to create the light maps (if either the geometry or the light source have changed). Then you render your scene to the color render target. Now depending on how you apply your shadow you also transform each vertex or pixel to each light source space and compare against the light map if the light source can see the vertex or pixel. If not there is shadow on this vertex or pixel for this particular light source.

Check out the DX SDK there are also light map samples.

Share this post


Link to post
Share on other sites
ok I've taken a look at the Shadow map exapmle and have come up with this, however it doesn't work:


[source lang = "cpp"]

// snip


// create motion blur render target texture
g_pd3dDevice->CreateTexture(SCREEN_WIDTH,
SCREEN_HEIGHT,
1,
D3DUSAGE_RENDERTARGET,
D3DFMT_A8R8G8B8,
D3DPOOL_DEFAULT,
&g_pTexMotionBlur,
NULL);

// create the depth stencil texture
g_pd3dDevice->CreateTexture(SCREEN_WIDTH, SCREEN_HEIGHT,
1, D3DUSAGE_RENDERTARGET,
D3DFMT_R32F,
D3DPOOL_DEFAULT,
&g_pTexDepthStencil,
NULL);

// create depth stencil surface
g_pd3dDevice->CreateDepthStencilSurface(SCREEN_WIDTH,
SCREEN_HEIGHT,
PresentParameters.AutoDepthStencilFormat,
D3DMULTISAMPLE_NONE,
0,
TRUE,
&g_pSurfDepthStencil,
NULL);

// snip


/**********************************************************************************
Render
**********************************************************************************/

HRESULT Render()
{
HRESULT hr;

PDIRECT3DSURFACE9 pSurfDS; // Low dynamic range depth stencil surface

g_pd3dDevice->GetDepthStencilSurface(&pSurfDS);

// start rendering the scene
g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER , D3DCOLOR_COLORVALUE(0.0f, 0.0f, 0.0f, 1.0f), 1.0f, 0);

if(SUCCEEDED(g_pd3dDevice->BeginScene()))
{
g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, TRUE);

hr = RenderScene();
CHECK_RESULT(hr, "RenderScene failed");

g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE);

// snip
hr = g_pTexDepthStencil->GetSurfaceLevel(0, &g_pSurfDepthStencil);

hr = ScreenGrabSurface(g_pSurfDepthStencil);
if(FAILED(hr)) MessageBox(NULL, "could not capture depth stencil", NULL, NULL);


g_pd3dDevice->EndScene();
}

else return E_FAIL;

g_pd3dDevice->Present(NULL, NULL, NULL, NULL);

SAFE_RELEASE(pSurfDS);

return hr;
}




ScreenGrabSurface() always fails so I can tell that simply coping the surface from one surface to another will not work, I assume this is due to the fact that the texture is the format is D3DFMT_R32F while the depth stencil format is D3DFMT_D16 and there needs to be some conversion between them as you cannot explicitly create a texture with the format D3DFMT_D16 as it is not a valid texture format.
any help would be great, thanks.

Share this post


Link to post
Share on other sites
You can't copy data from depthstencil surface. In D3D9 the only thing you can do with a ds surface is set it on the device.

What that Shadowmap sample does in the SDK is it uses a shader that calculates depth, and outputs this depth value to the R32F texture. Then that texture is sampled for the shadow comparison.

Share this post


Link to post
Share on other sites
Is that what this piece of shader code does?


//-----------------------------------------------------------------------------
// Vertex Shader: VertShadow
// Desc: Process vertex for the shadow map
//-----------------------------------------------------------------------------
void VertShadow( float4 Pos : POSITION,
float3 Normal : NORMAL,
out float4 oPos : POSITION,
out float2 Depth : TEXCOORD0 )
{
//
// Compute the projected coordinates
//
oPos = mul( Pos, g_mWorldView );
oPos = mul( oPos, g_mProj );

//
// Store z and w in our spare texcoord
//
Depth.xy = oPos.zw;
}




//-----------------------------------------------------------------------------
// Pixel Shader: PixShadow
// Desc: Process pixel for the shadow map
//-----------------------------------------------------------------------------
void PixShadow( float2 Depth : TEXCOORD0,
out float4 Color : COLOR )
{
//
// Depth is z / w
//
Color = Depth.x / Depth.y;
}




Take the current vertex position and multiply it with the world view matrix, then multiply that by the projection matrix, then the z value divided by the w component will give you the depth? Then you save that to a R32F texture then you can sample it?

Share this post


Link to post
Share on other sites
Hi,

Quote:
Is that what this piece of shader code does?


Yes. But note that the view and projection matrices are calculated from light's parameters. They're not game camera's matrices.

Quote:
... then the z value divided by the w component will give you the depth? Then you save that to a R32F texture then you can sample it?


Correct. But sampling coords must be calculated from the light's projection space vertex position:


...
float4 prjCoord = mul (in.VertexLocalPos, mul(g_WorldMatrix, g_LightViewProjMatrix));
prjCoord.xyz /= prjCoord.w;
prjCoords.x = 0.5 * (1 + prjCoords.x);
prjCoords.y = 0.5 * (1 - prjCoords.y);

float shadow = tex2D (smpShadowMap, prjCoords.xy).r;

Note: You need to perform a PCF (percentage closer filtering) to avoid shadow artifacts.

Hope this helps.
Regards,
Rohat.

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!