[Urgent] Depth buffer based occlusion queries?

Started by
21 comments, last by Leo_E_49 18 years, 7 months ago
How do you go about doing depth buffer based occlusion queries? Is it possible to determine whether one or more pixels of a mesh has passed the depth test? If so, how do you go about doing this? Can such a method be implemented in both OpenGL and Direct3D? My basic understanding is that you would render a value of e.g. 1.0f to a stencil buffer based on depth pass. Then you would tally the number of pixels which passed the depth check and if greater than 0, the object is not occluded. My problem is the tallying part. How would you go about adding up the pixels in the stencil buffer to check whether they are greater than 0?
Advertisement
Occlusion queries do exactly this. They will report how many pixels have passed the depth test in a given render. THey're usable in both OGL and D3D -- the only draw back is that their results tend to be delayed.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
So there's an inbuilt framework for these tests in both OpenGL and Direct3D? Could you provide a link or some functions/interfaces I could look up for how to use them?

Is there any way I can access the stencil buffer manually (perhaps in a pixel shader?). I would like to know in case I want to port this technique to a non-OpenGL or DirectX API, e.g. SPS2.
As far as I know the stencil buffer isn't used for occlusion queries in OpenGL (I assume D3D is the same). Look up the ARB_occlusion_query extension. You can't access stencil buffers manually in pixel shaders as far as I know (in fact you can't access any of the output buffers - all the output is fixed function). Accessing stencil buffers and doing occlusion querys are both API specific so there isn't really any general method you can use.
In Direct3D, you call Direct3DDevice::CreateQuery to create the query object, use Query::Issue to signal the beginning of the query, render your geometry, issue the 'end' signal, then call Query::GetData to see when the results are ready (and retrieve them if they are).

Richard "Superpig" Fine - saving pigs from untimely fates - Microsoft DirectX MVP 2006/2007/2008/2009
"Shaders are not meant to do everything. Of course you can try to use it for everything, but it's like playing football using cabbage." - MickeyMouse

Thank you both! [grin]
Oohh, I just had a brain-wave! [grin] What if I do a render to texture of the full scene, with the stencil buffer checking for depth pass? Then I lock the texture and count the number of pixels which passed the test! In theory this could even work accurately with alpha blended sprites.

Do you think this is a viable strategy?
No.

Richard "Superpig" Fine - saving pigs from untimely fates - Microsoft DirectX MVP 2006/2007/2008/2009
"Shaders are not meant to do everything. Of course you can try to use it for everything, but it's like playing football using cabbage." - MickeyMouse

Quote:Original post by superpig
No.


As hilariously rude as that was, he's right. Locking textures and manually counting pixels is the fastest way to get the slowest renderer.

[Edited by - Cypher19 on August 30, 2005 12:43:01 PM]
What if I do it on a low resolution texture, say 1/4 the screen size, it would still give good results if done that way. Although, I'm sure it would be a lot slower than the hardware test, could it work real time? Would it be possible to tally the pixels with a pixel shader somehow? I wonder if you know any way to implement it on the PS2?

This topic is closed to new replies.

Advertisement