Occlusion culling in 2.0 is very easy to use. There is a good set of defaults that does not affect picture quality but can give you a 2x performance increase when rendering a large amount of geometry that will be in the view frustum but not visible. The occlusion culling that was implemented does the following:
- Roughly sorts the scene front to back
- Render the major occluders
- Decide if objects will be occluded, if so test, otherwise just draw the object
- When the test buffer gets full, draw the objects that came back visible
- Goto 3 until all tests and geometry are checked/drawn
Below is a code sample that illustrates all of user tweakable paramaters that are available followed by an explanation of each.
RenderAction *ract = RenderAction::create(); // Don't draw or test any object taking up less than 15 pixels ract->setOcclusionCullingMinimumFeatureSize(15); // Any object with an 80% or better chance of being covered, test instead of draw ract->setOcclusionCullingCoveredThreshold(0.8); // If the test comes back with less than 15 pixels that would have changed // then discard this geometry and don't draw it ract->setOcclusionCullingVisibilityThreshold(15); // Use a query buffer that can hold 600 tests at a time ract->setOcclusionCullingQueryBufferSize(600); // Objects with less than 50 triangles, just draw and don't test ract->setOcclusionCullingMinimumTriangleCount(50); // Turn Occlusion Culling on ract->setOcclusionCulling(true);
Small Feature Culling
From the above example, ract->setOcclusionCullingMinimumFeatureSize(15) tells the occlusion culling algorithm that if it estimates the number of pixels the object would take up on the screen, is less than 15 pixels, then not to draw it. This is very useful when you want to get rid of tiny objects that only contribute detail to the final rendering. When set very low, the final rendering will look very similar to a full rendering. When set high there will be a lot of details missing from the scene. Default is 0 px, so no small feature culling.
For each object in the view frustum the algorithm calculates the probability that the object is covered. This value is compared against the user set threshold and if it exceeds it the object is tested for its visibility. The value is set by calling ract->setOcclusionCullingCoveredThreshold(0.x). The default value is 0.7, or 70%.
When an object is tested, the result of that test is how many pixels the object would affect if drawn. This user tweakable setting is related to the small feature culling, but different: small feature culling uses a rough estimate of pixels that would be affected based on the objects bounding box (small feature culling assumes that the bounding box that would be drawn would be 100% visible), small feature culling doesn't use the results of any test from the object. For example, if we tested an object that is almost completely hidden behind another object, the number of affected pixels would be very small. By using the visibilty threshold we could tell the occlusion culling algorithm to not draw the object. Like the small feature culling, this setting affects the final rendering. It can be set from the example above by calling: ract->setOcclusionCullingVisibilityThreshold(pixels). Default is 0, so no visibility threshold.
Query Buffer Size
This setting simply affects the number of tests that are preformed before checking test results. It can come in handy when there are a lot of objects in the scene that are not visible because a few objects cover most of them. In this case you would want to set the buffer size larger. It can be set by calling: ract->setOcclusionCullingQueryBufferSize(numTests). The default is 1000.
Minimum Triangle Count
This setting specifies how many triangles an object must have before testing it. To perform a test, the bounding box is drawn (12 triangles). So, in reality, if the object has 12 triangles, sending it out for a test would be a waste of time and resources. However, the latency involved in sending the test out and then later retrieving its results makes the number of triangles needed before testing higher. This setting really depends on how fast the graphis card can render geometry. It can be set by calling: ract->setOcclusionCullingMinimumTriangleCount(minTriangles). The default is 500 triangles, so all objects under 500 triangles are rendered and are never tested.