Understanding Frustum and Occlusion Culling in Unity3D
You may have heard of these terms before, but what do they really mean? Let’s break this down piece by piece, and then get into using occlusion culling in your Unity project.
The medical definition of occlusion is the blockage or closing of a blood vessel or hollow organ. While occlusion in video games is not medically lethal, a similar line can be drawn.
Ambient occlusion is used in 3D software to create more realistic soft shadows by blocking the ambient light source with the object or objects casting the shadow. It detects each surface area and how obscured it is from the ambient light sources, to generate more realistic graphics. Similarly, an occlusion map is used to determine which areas of a 3D model should indirect lighting, and how much.
With occlusion culling, objects that are outside of the main camera view, or blocked by other objects in the scene, will not be rendered. This is a very powerful and useful tool when it comes to saving a whole lot of GPU processing while running a game. Could you imagine having a giant game map where the computer is constantly updating the entire map, rather than just the particular room the player is currently in? Occlusion culling really enables people to make modern games as large and beautiful as they are.
Before jumping right into occlusion culling, let’s talk about frustum culling. Unity automatically performs frustum culling, which means it will exclude all Renderers that are outside of the view of the Main Camera’s view frustum. More on that here
The weak spot to frustum culling, is that it does not check if one object is being blocked by another object. Unity might spin it’s gears unnecessarily rendering objects that won’t be visible to the player. Occlusion culling prevents Unity from rendering objects that aren’t immediately needed. With that all being said, let’s get into setting up occlusion culling for your Unity project!
Navigate to Window>Rendering>Occlusion Culling.
You should now see an Occlusion window. Feel free to dock it wherever you see fit.
Occlusion culling will only work on static (still) objects in the scene, or dynamic (moving) objects that have their Tag switched to be static. The easy way to do this is to select all of the static objects in your scene, via the hierarchy.
In the inspector, press the drop-down arrow next to Static to show some occlusion options. Note that the check box next to static will be empty until we assign some occlusion settings. The Occluder Static tag needs to be assigned to any static game objects that you want to be part of your occlusion culling.
If you have child objects present, you will need to accept the changes to the children as well.
Now the dash shows in the Static box showing that I have multiple objects selected and assigned with the same tag.
When should you use Occludee Static? Small objects are less likely to occlude, or block, another object. Transparent objects also do not occlude, so both of these can be marked as Occludee Static, but do not need to be tagged as Occluder Static. These objects can still be occluded by other objects, but will not occlude other objects themselves, which saves some additional processing power.
Using the Everything option, will quickly select all of the occlusion option to be applied. If you have batching objects (using one draw call for all rather than multiple calls per object), navigation meshes, reflection probes, etc. you can enable everything. Here the Contribute GI (generating illumination) is disabled. I have static objects with emission channels for lighting, so I don’t want to lose any lighting information in the room just because the light is not in the immediate camera view.
The scene view does not yet reflect any changes, and that’s because we need to bake this information.
Back on the occlusion tab, change from object to bake. The default settings here are a great standard to begin with, but you might want to fine tune these settings for your scene if there is room for improvement.
The Smallest Occluder value is the minimum size of an object that will be able to hide other objects while occlusion culling.
The Smallest Hole value is the minimum space between geometry where the camera should see. This number is the diameter of the object that can fit through the hole. If you have a narrow double door with a small gap that you want the camera to be able to see through, your smallest hole value needs to be smaller than the gap between the doors.
The Backface Threshold gets rid of unnecessary detail information on the backfaces of objects, which the camera will typically never see. A value of 100 will never remove the backface data, where a lower value will exclude backface data from occlusion culling, saving additional processing. My gif here did not pick up me pressing the Bake button at the bottom of the Occlusion window. I do that now, accepting the default parameters.
Now you can see in the scene view that only the objects within the camera view are being rendered!
Here you can see me moving and rotating the direction that the player is looking. The game view on the bottom looks completely normal, while the scene view shows the occlusion culling in full effect!
I hope to see you in my next article where I add some fog into this scene and work with particles. Thanks for reading!