Jump to content
  • Advertisement
Sign in to follow this  
dali

Read the ZBuffer?

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

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!!

Share this post


Link to post
Share on other sites
Advertisement
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]

Quote:
Original post by dali
Oh thanks a very good hint!
Make sure you understand the performance implications of occlusion queries; they're a nice tool but they can be painful...
Quote:
Original post by dali
But how can i directly access the zbuffer?
You don't.

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

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Oh thanks again :)

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.

Share this post


Link to post
Share on other sites
Quote:
Original post by dali
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.
Just 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.

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

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!