This article covers most commonly encountered culling issues with instructions on how to debug and fix them.
Umbra Debugger is a graphical tool that allows visualizing occlusion and debugging potential issues. This article uses visualizations available in Umbra Debugger. These visualizations can be implemented in any application that uses Umbra runtime.
Occluded is one the main visualization modes available in Umbra Debugger, and is useful for quickly discovering any culling issues. It's activated from a checkbox near the top of the visualizations tab.
- Visible objects are rendered in gray
- Occluded objects are rendered in red
- Seeing any red objects indicates an error
Red objects are objects that are visible on screen, but determined to be hidden by Umbra. The color red should pop out easily from otherwise gray environment.
Note that any non-target objects are also shown as red, such as occluder-only and gate-only objects. It's possible that the target flag has been mistakenly omitted, but having such objects can also be intentional and not indicate an error. Gates and occluders can be hidden by unchecking Show occluders and Show gates from visualizations tab.
Smallest Hole issues
- Something seen through a hole or a gap is wrongly culled
- Debugger Occluded visualization: red objects are visible through a hole or a gap
- Umbra occlusion buffer doesn't match geometry - hole or gap becomes a solid surface
- Use smaller smallest hole parameter value
- Make the hole bigger
- Make objects around the hole non-occluder (i.e. target-only)
- (Umbra 3.4) If the artifact is at a distance, increase accurate occlusion threshold
This applies to something being incorrectly culled that's visible through a narrow gap or a hole. Such cases are usually smallest hole issues. Looking closely at Umbra occlusion buffer, you should see a solid surface where the hole is.
The hole or gap is smaller than smallest hole parameter value, and thus the algorithm doesn't see through it. For a more technical explanation, the hole doesn't fit an empty voxel - i.e. voxels are larger than the hole. Smallest hole parameter adjusts voxel size.
Using smaller smallest hole parameter value fixes this issue. Downside with decreasing smallest hole is longer computation time and larger computation memory usage.
Alternatively you can grow the hole, either by moving and resizing objects or by setting objects surrounding it non-occluders. This makes sense especially if the there's something like a grate or a fence. Such objects contain many small holes but don't occlude anything, and it's better to make them non-occluders rather than decreasing smallest hole.
(From Umbra 3.4 onwards) smallest hole parameter value increases with distance from camera. This means you can encounter this issue in a less obvious place, such as a doorway at a distance. Everything seen through the doorway gets occluded. The doorway is much bigger than smallest hole parameter, but due to distance and scaling it's affected. In addition to above fixes, you can alternatively increase runtime parameter accurate occlusion threshold. Article "Accurate occlusion threshold" and visibility data LOD in depth explains this parameter.
Smallest hole issue in Sponza Atrium.
Smallest hole parameter value is too big for the gaps between the pillar and the curtains. Occluded visualization shows incorrectly culled objects in red and occlusion buffer (bottom left) shows a solid surface.
Fixed by using smaller Smallest Hole value. The leaves were also made non-occluder.
No red objects are visible anymore. The change is also reflected in the occlusion buffer.
Triangle backface issues
- There's an area where culling result is mostly or completely invalid
- Debugger backface visualization: visible triangle backfaces nearby (red)
- Setting backface limit parameter 100 makes the issue disappear
- Increase backface limit
- Modify content so that (too many) backfaces aren’t visible
- Set the object's triangle winding as two sided
Umbra takes sufficient amount of visible triangle backfaces nearby as an indication that a location is invalid, where the camera isn't supposed to go. This is an important optimization. If there's an area where culling result is mostly or completely invalid, this is probably caused by nearby triangle backfaces. Query error ERROR_OUTSIDE_SCENE might also be reported, although not necessarily.
If culling results are invalid only very close to an occluder, the next issue below is a better candidate.
Backfaces are easy to find using Umbra Debugger backfaces visualization. The visualization is enabled from near the top of the visualizations tab. This visualization displays triangle backfaces in red and frontfaces in gray.
Umbra only considers triangles backfaces of occluder objects. This means that offending backfaces can also be hiding behind target-only objects. Enabling backfaces visualization automatically hides all target-only objects.
Setting backface limit parameter to 100 disables backface optimizations. This can be used to confirm whether an issue is in fact caused by backfaces, but is not the recommended fix.
Interpretation of backface limit is the percentage threshold of backfaces that must be visible in order for a location to be interpret as invalid. Increasing backface limit value makes the backface test less aggressive and can thus fix backface issues.
Modifying content so that backfaces are not visible is another possible fix. Finding a suitable backface limit value can help avoid manually fixing every backface issue. A suitable value would filter out intended invalid locations, such as space below ground and insides of objects, but leave the valid ones in.
If the object with backfaces is legitimately two sided, it's best to set the object's winding as two sided.
With backface issues it's tempting to disable the feature by setting backface limit to 100 or ignore problems by setting everything as two sided. It's recommended to fix these issues either by increasing backface limit or modifying content instead.
Visible backfaces are highlighted in red by Umbra Debugger backfaces visualization.
The curtain here has wrong triangle winding and will cause culling issues with sufficiently low backface limit values. There are also backfaces visible in some leaves, both around the pillars in the vases. These objects should probably be either two sided or target-only. However these particular objects are not significant enough to cause culling issues with any backface limit setting.
Issues very close to occluder surface (cell assignment)
- Culling result becomes mostly or completely invalid within a small area close to an occluder surface
- Camera is close to an occluder surface
- Debugger viewcell visualization shows the wrong viewcell
- Not a backface issue
- Smaller smallest hole / collision radius value
- A thicker wall
- Smaller backface limit - allows correctly detecting which side of the surface is the right one
- Ensure camera doesn’t go too close to an occluder
- Query flag IGNORE_CAMERA_POSITION makes runtime more resilient to these errors
Umbra visibility data consists of cells and portals. Cells are continuous volumes in space that are connected to each other by portals. When visibility query starts, the first step is to find out what cell the camera is in. Assigning camera to a wrong cell, for example one on the wrong side of a wall, causes invalid culling results.
Umbra is based on voxelization that ultimately has limited accuracy. A detailed occluder surface can have more detail than voxelization can reasonably represent. This means that correct behaviour can't always be guaranteed arbitrarily close to an occluder. However, there are steps you can take to improve accuracy and avoid situations where this is a problem.
Culling failures that happen only in a small location where camera is close to an occluder surface are probably cell assignment issues. Viewcell visualization (Umbra Debugger near the bottom of visualizations tab) can help to confirm this. This visualization shows the currently assigned cell or cells as white lines. If the displayed cell is in the wrong side of a wall or inside a wall, the issue is about cell assignment.
Decreasing smallest hole parameter value increases voxelization accuracy, and allows camera to go closer to occluders. (From Umbra 3.4 onwards) parameter collision radius is also supported. This allows increasing accuracy near occluders without it affecting smallest hole. Collision radius value is expected to be smaller than smallest hole.
Alternatively making the wall thicker that separates the two cells removes the need for more accuracy.
If you have disabled backface tests by using backface limit 100 or have otherwise high backface limit value, decreasing it can help Umbra correctly determine which side of the occluder surface is the correct one.
Enabling query flag IGNORE_CAMERA_POSITION causes the camera to be assigned to cells based on its near plane quad rather than camera origin point. This makes query behaviour less susceptible to these kinds of issues, but doesn't avoid them completely.
Umbra is often able to optimize visibility data so that culling behaves correctly even very close to occluders. Strictly speaking however, any given voxel size guaratees correct behaviour only up until sqrt(3) * (voxel size) distance from occluder surface. That is, sqrt(3) * min(smallest hole, collision radius). Sqrt(3) denotes square root of 3, and comes from computing the diagonal length of a voxel.
Cell assignment issue in Umbra House. Left viewport shows the camera view and right viewport shows view from above.
Viewcell visualization (white lines) shows that the camera is assigned to the wrong viewcell: one on the other side of the wall. Culling errors are visible on the left viewport (red objects, occluded visualization mode).
Fixed by using smaller smallest hole value.
Culling errors are gone. The camera is also now assigned on the correct side of the wall as shown by the viewcell visualization (white lines). You can see that the cell is now also more detailed than above due to smaller smallest hole value.