Read the ZBuffer?
Hello!
How can i read the values from the ZBuffer? Is it possible to save for each pixel in the zbuffer for which object the pixel stands for? I needed this because i wanted to make a fast collission detection in 2d by first drawing one object then a second one and testing the zbuffer if the second object has overdrawn the first object or not.
Thanks a lot!!
If you want to find out how many pixels of an object are actually visible you can use D3D’s occlusion query feature. You can draw the second object under the first one and see if all pixels pass the depth test; this way you do not need to access the z-buffer.
http://www.codesampler.com/dx9src/dx9src_7.htm#dx9_occlusion_query
http://www.gamedev.net/reference/articles/article2128.asp
http://www.codesampler.com/dx9src/dx9src_7.htm#dx9_occlusion_query
http://www.gamedev.net/reference/articles/article2128.asp
Note that the sort of algorithm you're attempting will need to tolerate a couple of frames latency if you want really high performance. Issuing draw commands and expecting to immediately read the values back will force lock-step with CPU and GPU and kill the parallelism that helps makes GPU's so fast [smile]
There are a couple of lockable formats in the enumeration, but I'm not aware of there being much hardware support for these.
A typical approach would be to use a pixel shader and possibly MRT's to output the Z value and/or an Object ID value.
hth
Jack
Quote:Original post by daliMake sure you understand the performance implications of occlusion queries; they're a nice tool but they can be painful...
Oh thanks a very good hint!
Quote:Original post by daliYou don't.
But how can i directly access the zbuffer?
There are a couple of lockable formats in the enumeration, but I'm not aware of there being much hardware support for these.
A typical approach would be to use a pixel shader and possibly MRT's to output the Z value and/or an Object ID value.
hth
Jack
Quote:Original post by dali
Oh thanks a very good hint! But how can i directly access the zbuffer?
1. Use the D3DFMT_D16_LOCKABLE or D3DFMT_D32F_LOCKABLE format for yout depth buffer (depending on which your graphics hardware/device driver supports - some don't support any lockable formats).
2. IDirect3DDevice9::GetDepthStencilSurface gets you an IDirect3DSurface9 interface representing the depth and stencil surface. NOTE: the IDirect3DSurface9 interface is reference counted so you need to call ->Release() on it when you're done with the pointer.
3. finally IDirect3DSurface9::LockRect gets you direct access to the data in the depth buffer.
Generally though, I'd advise against trying to read back from the Z buffer using the CPU: the lock will cause a serialisation waiting for the GPU to finish rendering up to the point where you called LockRect; there's a very good chance you'll be reading back from uncached memory (slooooww for the CPU); you might not get the optimisation of proper hierarchical-Z (depending on the card).
There is usually always a better alternative to reading the Z buffer directly these days, for lens flare visibility tests occlusion queries are where it's at; for Z buffer based shadow techniques, use a render target texture and a shader to output the depth to a colour channel of that texture - use the texture where you would usually use the ZB, etc...
[edit]Bah, the lateness! That's what happens when I don't refresh enough[wink][/edit]
Ok thanks! Good to know that these locks need time but i hope this approach is faster as testing two objects manually against each other by comparing pixels.
Oh thanks again :)
I just have to write to the buffer once so this shouldnt be that big problem.
Quote:Original post by S1CA
Generally though, I'd advise against trying to read back from the Z buffer using the CPU...
I just have to write to the buffer once so this shouldnt be that big problem.
Quote:Original post by daliJust because you're writing depth doesn't mean you should read it - conceptually you are just talking about a block of video memory, but it's such an integral core part of GPU-based graphics that it's a focus of some serious optimizations by the IHV's.Quote:Original post by S1CA
Generally though, I'd advise against trying to read back from the Z buffer using the CPU...
I just have to write to the buffer once so this shouldnt be that big problem.
In general the depth information doesn't need to be accessed by the application and is optimized accordingly. By breaking that rule you'll effectively cancel out any of their optimizations and destroy the performance advantages (Hierarchical-Z and early-rejection can be huge performance gains), combine this with your proposed instant read-back of depth and you're forcing a sub-optimal rendering in lock-step with the CPU. Bottom line is you'll be wasting such a huge amount of potential performance it brings into question whether you'll see much advantage by offloading this GPGPU style...
hth
Jack
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement