Occlusion Culling is a feature that disables rendering of objects when they are not currently seen by the camera because they are obscured (occluded) by other objects. This does not happen automatically in 3D computer graphics since most of the time objects farthest away from the camera are drawn first and closer objects are drawn over the top of them (this is called “overdraw”). Occlusion Culling is different from Frustum Culling. Frustum Culling only disables the renderers for objects that are outside the camera’s viewing area but does not disable anything hidden from view by overdraw. Note that when you use Occlusion Culling you will still benefit from Frustum Culling.
The occlusion culling process will go through the scene using a virtual camera to build a hierarchy of potentially visible sets of objects. This data is used at runtime by each camera to identify what is visible and what is not. Equipped with this information, Unity will ensure only visible objects get sent to be rendered. This reduces the number of draw calls and increases the performance of the game.
The data for occlusion culling is composed of cells. Each cell is a subdivision of the entire bounding volume of the scene. More specifically the cells form a binary tree. Occlusion Culling uses two trees, one for View Cells (Static Objects) and the other for Target Cells (Moving Objects). View Cells map to a list of indices that define the visible static objects which gives more accurate culling results for static objects.
It is important to keep this in mind when creating your objects because you need a good balance between the size of your objects and the size of the cells. Ideally, you shouldn’t have cells that are too small in comparison with your objects but equally you shouldn’t have objects that cover many cells. You can sometimes improve the culling by breaking large objects into smaller pieces. However, you can still merge small objects together to reduce draw calls and, as long as they all belong to the same cell, occlusion culling will not be affected. The collection of cells and the visibility information that determines which cells are visible from any other cell is known as a PVS (Potentially Visible Set).
You can use the ‘overdraw’ scene rendering mode to see the amount of overdraw that is occuring, and the stats information pane in the game view to see the amount of triangles, verts, and batches that are being rendered. Below is a comparison of these before and after applying occlusion culling.
In order to use Occlusion Culling, there is some manual setup involved. First, your level geometry must be broken into sensibly sized pieces. It is also helpful to lay out your levels into small, well defined areas that are occluded from each other by large objects such as walls, buildings, etc. The idea here is that each individual mesh will be turned on or off based on the occlusion data. So if you have one object that contains all the furniture in your room then either all or none of the entire set of furniture will be culled. This doesn’t make nearly as much sense as making each piece of furniture its own mesh, so each can individually be culled based on the camera’s view point.
You need to tag all scene objects that you want to be part of the occlusion to Inspector. The fastest way to do this is to multi-select the objects you want to be included in occlusion calculations, and mark them as and .
in theWhen should you use
? Transparent objects that do not occlude, as well as small objects that are unlikely to occlude other things, should be marked as , but not . This means they will be considered in occlusion by other objects, but will not be considered as occluders themselves, which will help reduce computation.For most operations dealing with Occlusion Culling, you should use the Occlusion Culling Window (
)In the Occlusion Culling Window, you can work with occluder meshes, and Occlusion Areas.
If you are in the Mesh Renderer selected in the scene, you can modify the relevant Static flags:
tab of the and have aIf you are in the Occlusion Area selected, you can work with relevant OcclusionArea properties (for more details go to the Occlusion Area section)
tab of the and have anNOTE: By default if you don’t create any occlusion areas, occlusion culling will be applied to the whole scene.
NOTE: Whenever your camera is outside occlusion areas, occlusion culling will not be applied. It is important to set up your Occlusion Areas to cover the places where the camera can potentially be, but making the areas too large incurs a cost during baking.
The occlusion culling bake window has a “Set Default Parameters” button, which allows you to reset the bake values to Unity’s default values. These are good for many typical scenes, however you’ll often be able to get better results by adjusting the values to suit the particular contents of your scene.
Property |
---|
Smallest Occluder |
Smallest Hole |
Backface Threshold |
At the bottom of the bake tab is are the Clear and Bake buttons. Click on the
Button to start generating the Occlusion Culling data. Once the data is generated, you can use the Visualization tab to preview and test the occlusion culling. If you are not satisfied with the results, click on the button to remove previously calculated data, adjust the settings, and bake again.All the objects in the scene affect the size of the bounding volume so try to keep them all within the visible bounds of the scene.
When you’re ready to generate the occlusion data, click the
button. Remember to choose the in the tab. Lower values make the generation quicker and less precise, higher values are to be used for production quality closer to release.Bear in mind that the time taken to build the occlusion data will depend on the cell levels, the data size and the quality you have chosen. Unity will show the status of the PVS generation at the bottom of the main window.
After the processing is done, you should see some colorful cubes in the View Area. The colored areas are regions that share the same occlusion data.
Click on
if you want to remove all the pre-calculated data for Occlusion Culling.To apply occlusion culling to moving objects you have to create an Occlusion Area and then modify its size to fit the space where the moving objects will be located (of course the moving objects cannot be marked as static). You can create Occlusion Areas by adding the Occlusion Area component to an empty game object ( in the menus).
After creating the Occlusion Area, check the Is Target Volume checkbox to occlude moving objects.
Property: | Function: |
---|---|
Size | Defines the size of the Occlusion Area. |
Center | Sets the center of the Occlusion Area. By default this is 0,0,0 and is located in the center of the box. |
Is View Volume | Defines where the camera can be. Check this in order to occlude static objects that are inside this Occlusion Area. |
After you have added the Occlusion Area, you need to see how it divides the box into cells. To see how the occlusion area will be calculated, select Occlusion Culling Preview Panel.
and toggle the button in theAfter your occlusion is set up, you can test it by enabling the Occlusion Culling (in the Occlusion Culling Preview Panel in Visualize mode) and moving the Main Camera around in the scene view.
As you move the Main Camera around (whether or not you are in Play mode), you’ll see various objects disable themselves. The thing you are looking for here is any error in the occlusion data. You’ll recognize an error if you see objects suddenly popping into view as you move around. If this happens, your options for fixing the error are either to change the resolution (if you are playing with target volumes) or to move objects around to cover up the error. To debug problems with occlusion, you can move the Main Camera to the problematic position for spot-checking.
When the processing is done, you should see some colorful cubes in the View Area. The blue cubes represent the cell divisions for Target Volumes. The white cubes represent cell divisions for View Volumes. If the parameters were set correctly you should see some objects not being rendered. This will be because they are either outside of the view frustum of the camera or else occluded from view by other objects.
After occlusion is completed, if you don’t see anything being occluded in your scene then try breaking your objects into smaller pieces so they can be completely contained inside the cells.
In order to create occlusion primitives which are openable and closable at runtime, Unity uses Occlusion Portals.
Property: | Function: |
---|---|
Open | Indicates if the portal is open (scriptable). |
Center | Sets the center of the Occlusion Area. By default this is 0,0,0 and is located in the center of the box. |
Size | Defines the size of the Occlusion Area. |