Day 36: Checking out Occlusion Culling

Japji Multani
3 min readFeb 18, 2023

--

A few days ago I learned about the URP and the stages that occur to render a Scene. One of the stages is culling, in which the render pipeline figures out what objects to render. In this stage, Unity uses frustum culling and optionally occlusion culling.

Frustum Culling

When we use a camera with a perspective projection in Unity, it sees into the Scene through a frustum (a pyramid with the top cut off parallel to the base) region. The region’s plane closer to the camera is called the near-clipping plane and the region’s plane farther from the camera is called the far-clipping plane. Any objects within this frustum will be rendered to the screen, including objects that are behind other objects, aka occluded objects. This can affect performance for larger-scale Scenes and to address that, there is an occlusion culling feature in Unity that can be enabled.

https://docs.unity3d.com/Manual/UnderstandingFrustum.html

Occlusion Culling in Unity

In Unity, occlusion culling can prevent occluded GameObjects from rendering by utilizing precomputed data at runtime. From what I understood, that’ll add more work for the CPU and occupy more memory to cut back on the GPU workload.

GameObjects that don’t move are considered static and those that move are considered dynamic. To inform certain systems that a GameObject is to be treated as a static GameObject, you set one of the Static Editor Flags on the GameObject itself. The Occluder Static and Occludee Static flags inform the occlusion culling system of the static GameObjects to include when you bake the pre-computed data. The Occluder Static flag should be set on GameObjects that will block other GameObjects, aka Occluders. The Occludee Static flag should be set on GameObjects that’ll be blocked by Occluders, aka Occludees. A GameObject could be both an Occluder and an Occludee.

Setting Occluders and Occludes From the Inspector Window

For dynamic GameObjects to be culled when occluded, their MeshRenderer component has a Dynamic Occlusion property that needs to be checked. This’ll prevent the GameObject from being rendered if it is behind an Occluder.

Making a Dynamic GameObject an Occludee

To enable Occlusion Culling, I go to the Camera Component’s Rendering section and checkmark the Occlusion Culling property. After that, I mark my Occluder and Occludees.

Enabling Occlusion Culling on a Camera

Finally, I open the Occlusion Culling window by going to the Unity Editor’s navigation bar and clicking Window > Rendering > Occlusion Culling. In the Occlusion Culling window, I click on the Bake tab and click the Bake button at the bottom right to generate the occlusion culling data. You can customize how to bake the data by modifying the parameters in the Bake tab before generating the occlusion-culling data.

Occlusion Culling window in the Bake section

We can also check out our occlusion culling in action by clicking on the Visualization tab in the Occlusion Culling window, selecting a Camera that has occlusion culling enabled, and moving/rotating the camera around the Scene view.

Visualizing Occlusion Culling

Any additional information, feedback, or correction is appreciated!

--

--