How can I fill the zbuffer from a texture?

Started by
7 comments, last by MJP 14 years, 7 months ago
I want to render a zbuffer to a texture, and then be able to display a photo and use the texture to fill the zbuffer. I have tried several things without success, so I was wondering if anyone here has done this and how? I am using DX9. Thanks.
Advertisement
You can write to DEPTH0 from a pixel shader in order to output to the depth buffer (just like you output to COLOR0 to output to the render target).
Quote:Original post by MJP
You can write to DEPTH0 from a pixel shader in order to output to the depth buffer (just like you output to COLOR0 to output to the render target).

What he said. Basically what you're going to be doing is reading a vale from a texture, decoding as necessary, and then just dropping it directly into the depth register. You can also likely disable color writes, though I don't know if you'd get the double-speed Z writes.
clb: At the end of 2012, the positions of jupiter, saturn, mercury, and deimos are aligned so as to cause a denormalized flush-to-zero bug when computing earth's gravitational force, slinging it to the sun.
Quote:Original post by MJP
You can write to DEPTH0 from a pixel shader in order to output to the depth buffer (just like you output to COLOR0 to output to the render target).


OK, I am still having some problems.
I want to render a scene and it's depthstencil to textures, and then be able to render that static scene by drawing the textures. I am then trying to render these texures to restore a static scene that I can move objects through. The scene draws fine, but the zbuffer does not.


Here is the code for creating the texures:

hr = Gfx::CreateTexture(m_width, m_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_renderTarget);m_renderTarget->GetSurfaceLevel(0, &m_renderSurface);hr = Gfx::CreateTexture(m_width, m_height,1, D3DUSAGE_DEPTHSTENCIL, D3DFMT_D32, D3DPOOL_DEFAULT,&m_depthTexture);m_depthTexture->GetSurfaceLevel(0,&m_depthStencil);


I push and set the rendertarget and depth stencil, render my scene, and then pop the rendertarget and depthstencil.

I then set the rendertarget and depthstencil textures as inputs for a DetailSampler and ZSampler respectively, clear the rendertarget and zbuffer, then render a fullwindow quad using the following pixelshader:

void zbufferPS( in float2 Texture	: TEXCOORD0,				out float4 color: COLOR0,				out float depth : DEPTH0){	color = tex2D(DetailSampler, Texture);	depth = tex2D(ZSampler, Texture).r;}



Long story short, the scene draws fine, but the zbuffer is empty. Is it possible to read from a depth stencil texture, and if not how can I get around this? I am using an Nvidia GFX 280 video card and DX9. Thanks.
D3DFMT_D32 is not a valid format for a render target, it can only be used for depth-stencil surfaces. Use something like R32F instead.
Quote:Original post by MJP
D3DFMT_D32 is not a valid format for a render target, it can only be used for depth-stencil surfaces. Use something like R32F instead.


I am using that surface for the depth stencil. The render target's format is D3DFMT_A8R8G8B8. I push the render target and depth stencil, call SetRenderTarget(0, m_renderSurface) and SetDepthStencilSurface(m_depthStencil) before rendering the scene, and pop the render target and depth stencil back, then try using the textures for my samplers.
You cannot read directly from a depth stencil in DX9, at least it's not supported.

What you should do is render your scene normally, with your colour target and a R32F target present, writing depth to COLOR1 to populate the depth target.

Then read from that, like you've been trying to with the depth stencil and write it out to DEPTH0.
Quote:Original post by adt7
You cannot read directly from a depth stencil in DX9, at least it's not supported.

What you should do is render your scene normally, with your colour target and a R32F target present, writing depth to COLOR1 to populate the depth target.

Then read from that, like you've been trying to with the depth stencil and write it out to DEPTH0.


Do I have access to the depth information in the pixel shader, or do I need to recreate it by passing position in a texcoord from the vertex shader, and then save z/w or something like that? Is the depth format that I write out to DEPTH0 consistent across video cards? Thanks for any help you can give.


BTW, I am reading directly using the depthstencil for my hardware shadow mapping, which works fine, but I am guessing this is a video card specific feature.
Quote:Original post by GMano

Do I have access to the depth information in the pixel shader, or do I need to recreate it by passing position in a texcoord from the vertex shader, and then save z/w or something like that? Is the depth format that I write out to DEPTH0 consistent across video cards? Thanks for any help you can give.



No, you don't have access to it. You'll need to pass z and w to the pixel shader, then in the pixel shader divide z by w and output it. And yeah, that should be consistent across all video cards.


Quote:Original post by GMano
BTW, I am reading directly using the depthstencil for my hardware shadow mapping, which works fine, but I am guessing this is a video card specific feature.



Indeed, doing that is an IHV-specific extensions and only works for shadow maps (not for generalized readback of depth data).

This topic is closed to new replies.

Advertisement