Quick answer: Add the OcclusionPortal component to the door GameObject, rebake occlusion with the portal in the scene, mark the door’s frame and adjacent geometry as Occluder Static, and toggle portal.open at runtime.
A castle level uses Occlusion Portals on doors to cull entire rooms when doors are closed. The portals are placed, the doors animate, but the rooms beyond render unchanged regardless of door state. Memory bandwidth doesn’t drop; frame rate doesn’t improve.
Three Required Pieces
Working Occlusion Portals need:
- An
OcclusionPortalcomponent on a child GameObject with a fitted bounding box (set the OcclusionPortal’s Center and Size to match the door’s opening). - The portal’s frame (door frame, walls around the opening) marked Occluder Static.
- The scene rebaked via Window → Rendering → Occlusion Culling → Bake with the portal in the scene.
At runtime, toggle portal.open = false to close (occlude beyond) or true to open (render normally).
Step 1: Add the Portal
On your door GameObject (or a child), add an OcclusionPortal component. Set Center and Size to match the door opening exactly. Too small: leaks light through edges. Too large: door area includes adjacent geometry that shouldn’t be portal-controlled.
Step 2: Mark Surrounding Geometry Static
The door frame, walls flanking the opening, and the floor/ceiling at the opening must be Occluder Static. The bake uses these as anchors for portal-aware visibility. Without static neighbors, the portal can’t meaningfully cull.
Step 3: Rebake
Open Window → Rendering → Occlusion Culling. Click Bake. The bake takes 1–30 minutes depending on scene size. Watch the bake progress; the result is an Occlusion.asset stored next to the scene.
Step 4: Runtime Toggle
using UnityEngine;
public class Door : MonoBehaviour
{
[SerializeField] OcclusionPortal portal;
public void Open() {
portal.open = true;
// play animation, etc.
}
public void Close() {
portal.open = false;
}
}
Close the door, watch the room beyond stop rendering. Frame rate should improve in large multi-room levels.
Diagnose with the Stats Window
Game view → Stats. Note “Saved by occlusion culling”. Should be non-zero when closed portals hide a room. If it stays at 0, the portal isn’t affecting culling — check the three-step setup again.
Common Mistakes
- Portal Size too small to fully cover the opening.
- Door geometry itself marked Occluder Static — baked occlusion treats it as a fixed wall and ignores the portal.
- Forgot to rebake after adding the portal.
Verifying
Walk into the doorway. Toggle portal.open via a debug command. With it false, scene complexity behind should drop dramatically; with true, restored. Stats panel confirms the saved-by-occlusion count changing.
“Portals + Static + Bake. All three for working occlusion. Miss one and the door is decoration.”
For procedural levels where rebaking is impractical, use Occlusion Areas + manual visibility scripting instead — portals don’t fit dynamic geometry.