Quick answer: Mark every renderer that should be culled or used as an occluder with Occludee Static or Occluder Static. Tune Smallest Occluder down for tight interiors. Split giant meshes into per-room pieces so they can be individually culled.
You bake occlusion, run the scene, and the profiler shows no draw call savings. The cells visualization shows the player’s cell but reports every renderer as visible. The bake didn’t actually capture the geometry you expected.
The Symptom
Occlusion Culling baked, no errors. Frame Debugger or Stats panel shows the same renderer count whether you face into a wall or away from it. The visualization in the Occlusion window shows boxes but no actual occlusion happening.
What Causes This
Three common causes:
- Static flags missing. Renderers must be Occludee Static (to be cullable) or Occluder Static (to block the view of others). The header Static dropdown shows the bitmask.
- Smallest Occluder too large. Default 5m means a 4m corridor wall doesn’t occlude anything. For tight scenes, 1–2m is needed.
- One giant mesh. Unity culls per renderer. A 200m airport import as a single mesh is all-or-nothing — you can’t cull half of it.
The Fix
Step 1: Static flags. Select all level geometry. In Inspector header, click the Static dropdown and tick:
- Occluder Static (this mesh blocks views)
- Occludee Static (this mesh can be culled)
- Batching Static (also useful but separate)
You can mark a mesh both Occluder and Occludee. Walls and large props should be both. Tiny props should be Occludee only (small things rarely block views meaningfully).
Step 2: Tune bake parameters. Window → Rendering → Occlusion Culling → Bake tab.
Smallest Occluder: 2.0 // down from default 5
Smallest Hole: 0.25
Backface Threshold: 100 // fully ignore backfaces
Lowering Smallest Occluder makes the bake slower but captures more occluding walls.
Step 3: Split giant meshes. If you have a single huge level mesh, re-export from your DCC tool with separate meshes per room or section. Or in Unity, use a tool like Mesh Splitter to break apart by bounds.
Step 4: Bake and check the visualization. Click Bake. Visualization tab → tick “View Volumes” and “Visibility Lines.” Move the camera; only the active cell’s visible meshes should highlight. If nothing highlights, the bake is empty.
Dynamic Occludees
For movable objects (NPCs, vehicles) that you still want culled by static walls, mark them with the Dynamic Occludee component (or just check Dynamic Occludee on the MeshRenderer). They’re tested per-frame against the baked occlusion volumes.
Verifying
Stats panel → check Tris and SetPass calls before and after entering a room with closed walls. SetPass calls should drop visibly. If the count stays similar, occlusion isn’t firing — revisit static flags.
“Static flags. Smallest Occluder small enough. Split giant meshes. Bake. Walls block draws.”
Related Issues
For LOD popping, see LOD popping. For high draw calls, see draw call reduction.
Static flags. Tune the threshold. Split big meshes. Walls work.