Render to texture and copying depth buffer...

Started by
1 comment, last by burak575 14 years, 11 months ago
Hi everyone, I have a couple questions. I have a OpenGL background and just trying to figure out how multiple render targets, rendering to texture and using depth as a texture works in DirectX. I made couple searches and found useful docs about these topics, but I got stuck in some questions... I am trying to create a texture with "D3DUSAGE_DEPTHSTENCIL" flag and using It's surface as depthstencil surface with "device->SetDepthStencilSurface(depthsfc)". And setting color render targets with "device->SetRenderTarget(0,colorsfc)". Problem is when I try to render a quad on screen with that depthtex , it renders with red and black colors and if I use debug version of DirectX it says lots of these when setting texture: ASSERTION FAILED! File E:\dxsdk\wggt_apr07\Private\MultiMedia\DirectX\dx\d3d9\fw\texture.hpp Line 71: GetBufferDesc()->Format == GetUserFormat() If I use colortex instead of depthtex, no problem occurs. So I think, using that depthtex as a texture for rendering objects is illegal. Another question is render targets. In DepthOfField example in DX sdk, they used D3DXCreateRenderToSurface api to create a "render to surface" for old cards. Do I really need it, or is it a just wrapper? Also It seems it has a new depthbuffer for itself, how can I dump it's depth buffer? These things was easy in opengl but it seems a little complicated in DX. --== Summary =-- How can I render depth of offscreen render result to a quad, or use it on shaders as texture or copy it's contents to system memory? (it can't be lockable so how can i read it or use as actual texture?) How to get depth from Render To Surface that created with D3DXCreateRenderToSurface? Thanks for reading and help...
Advertisement
DirectX9 has no support for readback of depthstencil surfaces, unless it's a lockable format (in which case performance will be abysmal, so it wouldn't be worth it). This functionality was added for DX10. The only way you can create a depthstencil surface is with IDirect3DDevice9::CreateDepthStencilSurface, you can't do it by any other means. Once you've created it, the only thing you can do with it is bind it to the device with IDirect3DDevice9::SetDepthStencilSurface.

The only way around this is with Nvidia or ATI-specific driver hacks designed for shadow mapping. Look into hardware PCF for Nvidia, or Fetch4 for ATI. Be aware that these will cause errors when using the debug runtimes, because you must perform technically illegal operations to use these techniques.

If you're not looking to use depth for shadow mapping, your best bet is just to render depth manually to a color render target texture (ideally R32F format). It should be relatively cheap since you can use a simple pixel shader, and you can also store linear depth if you want to get around the precision issues caused by a non-linear depth buffer.

Also...ID3DXRenderToSurface is just a helper, you don't need to use it. You can just create a render target texture manually using IDirect3DDevice9::CreateTexture, just make sure you place it in D3DPOOL_DEFAULT and specify D3DUSAGE_RENDERTARGET. Then when you want to set it as the current render target for the device, access the top-level surface using IDirect3DTexture9::GetSurfaceLevel.
Thanks MJP [smile], that really helped. It will save me lot of energy [wink]

This topic is closed to new replies.

Advertisement