Occlusion queries are cool

I set up occlusion queries. At first it was much slower, but I learned to perform all queries at once, and to offset the feedback gathering by a few frames.

Here is the layout:

-Check occlusion queries from a few frames ago
-Start rendering
-Render everything that isn’t culled and insert every rendered object into a queue
-Done rendering
-Render every AABB of each object in the queue as an occlusion query

If an object is culled, it stays hidden for about 20 millisecs. Once that delay is up, another query is performed and the object is culled one more frame. This prevents me from re-rendering hidden objects. This approach also eliminates the need for an extra depth pass, or for special occlusion geometry.

The only problem I have is that when I turn the camera quickly, there is a noticable fluttering along the edge where hidden objects are reappearing.

which is unacceptable for me.

I was able to reduce this by adding a bounding box frustum test after the bounding sphere test. Fewer unneeded occlusion queries means an object is less likely to be hidden just offscreen due to an occlusion query, since the frustum culling happens first.

Hi Leadwerks. Have you looked at the article “Coherent Hierarchical Occlusion Culling: Hardware Occlusion Culling made useful” (Bittner, et. al.) (http://www.cg.tuwien.ac.at/research/vr/chcull/bittner-eg04-chcull.pdf) and also GPU Gems 2, chapter 6.

I plan on trying it out for terrain rendering myself. If it works satisfactory I would enable this algorithm after view frustum culling, if the angle between a down vector and the view direction vector is less than some threshold value (maybe 45 degrees to start with). Perhaps make the threshold value a function of the steepness of the terrain dataset. It is just a heuristics to avoid issuing occlusion queries unnecessarily.

Completely replacing VFC with “occlusion” queries may also be possible but it is hard to say anything about performance characteristics in advance.

Unreal Engine 3 has the same problem (at least at the low FPS i get). Doesn’t bother me much (as a gamer).

The only idea i have, that you might be able to do, is not to clear your color-buffer, so that the area, where something isn’t drawn but should be, has the same color as the previous frame, thus making it less noticeable.

Problem is, without clearing the color-buffer you loose color-compression. So maybe just clear your buffer to a color that is very unnoticeable in your environment (ie. black or brown or grey, depending on the style of your game).


Could attempt to stretch your geometry for occlusion queries based on estimated (or computed) motion.

I think it’s just something I will let the end user toggle on/off. The usefulness of occlusion queries is highly questionable and highly dependent on the context, but it is a nice gimmick that makes your engine look very high-tech.

Now if OpenGL let you specify an AABB surrounding a vertex array, and if it tested this first before processing the array, that might be really good. There would be no syncronizing issues, and it would be very easy to manage. I can’t think of any situation where it would fail, unless the camera was inside the AABB, which is easy for the programmer to test for first.

Something like this:

glboxfv [x0, y0, z0, x1, y1, z1]
glEnable GL_BOX_TEST
//If box test fails primitives rendering is skipped
Render stuff here
glDisable GL_BOX_TEST

I think I have heard about something like this, called predicated rendering.

Ha there it is, end of the page :
So it is still “in the works” :

nVidia exposes this extension under OpenGL, but they don’t mention it often. There was a thread here, a long time ago, where it was said how to use it (the exact enum-values, etc.). I really don’t understand, why they keep it so secretly. Maybe a D3D vs. OpenGL thing, since DX10 exposes this feature.


Another topic on our agenda is to look at so-called ‘predicated rendering.’ Think of this as an occlusion query test, where the result of the test automatically controls whether a set of geometry is rendered by the GPU, without any CPU intervention.

Thanks for finding that. That is exactly what I was describing. It just makes sense.