Visibility Culling Overview
- How does it work?
- Culling Methods
- Stats for Culling Performance
- Troubleshooting & Tips
How does it work?
Camera View Frustum
- View Frustum: The area between the Near and Far Clip Planes. Anything within this view is rendered.
- Field of View (FOV): The width of the camera's view angle measured in degrees.
- Near Clip Plane: The nearest point to the camera that will render.
- Far Clip Plane: The farthest point from the camera that will render. This is handled by Scene Depth in UE4.
View Frustum Culling
The example below demonstrates the camera view frustum from a top-down perspective and the camera's perspective view. The Yellow area represents what is within view of the camera. This area will be rendered. The Red area represents what is out of view of the camera frustum. Actors in this area will not be rendered, unless their bounds are large enough to be within the camera frustum (This is not represented in this example). Also keep in mind that anything outside of the camera frustum view is being culled as well.
In this view both the Sphere and Cone actors are not rendered because they are occluded from the view of the camera.
|Min Draw Distance||The minimum distance at which the primitive should be rendered. This is measured in world space units from the center of the primitives bounding sphere to the camera position.|
|Desired Max Draw Distance||Max draw distance exposed to the LDs. The real max draw distance is the min (disregarding 0) of this and volumes effecting this object.|
|Current Max Draw Distance||The distance to cull this primitive at. A CachedMaxDrawDistance of 0 indicates that the primitive should not be culled by distance.|
In the examples below the Min and Max Distance have been set for the cube. These values determine the closest distance to render the actor or the farthest distance that the actor can be rendered from the camera view.
- Min Draw Distance: 500
- Max Draw Distance: 1000
The Max Draw Distance is the maximum distance at which the mesh will be rendered. Anything beyond this value will from the center of the actor will not be rendered.
The Camera Frustum View example above is an example of this type of dynamic hardware occlusion.
Controls when occlusion queries are rendered. Rendering before the base pass may give worse occlusion (because not all occluders generally render in the earlyzpass). However, it may reduce CPU waiting for query result stalls on some platforms and increase overall performance.
|r.AllowOcclusionQueries||If zero, occlusion queries will not be used to cull primitives.|
|r.DownsampledOcclusionQueries||Whether to issue occlusion queries to a downsampled depth buffer.|
|r.NumBufferedOcclusionQueries||Number of frames to buffer occlusion queries (including the current renderthread frame). More frames reduce the chance of stalling the CPU waiting for results, but increases out of date query artifacts.|
Hardware Occlusion Queries (Default)
Hierarchical Z-Buffer Occlusion
Hierarchical Z-Buffer Occlusion works by looking at an actor based on its relative size in the world and approximates the bounds. This can help reduce the "popping" in of an actor that can happen when the default method is used, which has a tight bounding box around the geometry of the actor.
|r.HZBOcclusion||If 0, this will use the default Hardware Occlusion Queries system. By using 1 this will use the HZB occlusion system, which will have less GPU and CPU cost with more conservative results. When set to 2 this will force HZB occlusion system which will override any rendering platform preferences.|
Precomputed Visibility Volume
For more information on using and setting up Precomputed Visibility Volumes you can read about them in this page.
Cull Distance Volume
Brief overview of what it is and how it works.
Instanced static meshes not supported
It can be helpful to see the bounds of a mesh in your scene in some instances. You can enable this visualization by going to the Viewport and selecting Show > Advanced > Bounds. To view the bounds of an actor you must select it in your scene.
You can access the Project Settings by going to the Menu > Edit > Project Settings in the Rendering category.
|Occlusion Culling||Allows occluded meshes to be culled and not rendered. If this is disabled all occlusion culling will be disabled for the project which can have performance implications.|
|Min Screen Radius for Lights||This is the screen radius at which lights are culled. Larger values can improve performance but causes lights to pop off when they affect a small area of the screen.|
|Min Screen Radius for Early Z Pass||Screen radius at which objects are culled for early Z pass. Larger values can improve performance but very large values can degrade performance if large occluders are not rendered.|
|Min Screen Radius for Cascaded Shadow Maps||This is the screen radius at which objects are culled for cascaded shadow map depth passes. Larger values can improve performance but can cause artifacts as objects stop casting shadows.|
|Warn about no precomputed visibility||Displays a warning when no precomputed visibility data is available for the current camera location. This can be helpful if you are making a game that relies on precomputed visibility.|
Stats for Culling Performance
|Frustum Culled Primitives|
|Visible Culled Primitives|
|Visibile Dynamic Primitives|
Visible static mesh elements is the single biggest contributor to rendering thread time and should be carefully watched and optimized.
Here are the culling methods listed in order they are applied to each primitive, which is also from least to most expensive in terms of rendering thread cost.
- Distance culling
- View frustum culling
- Precomputed occlusion culling
- Dynamic occlusion culling (hardware occlusion queries)
Of course, it's even better if that distant section of the map could be streamed out completely.
- Occlusion culling is disabled in Wireframe viewmode
- Use the Console Command 'Stat Initviews' in PIE or Standalone games.
Troubleshooting & tips
- In larger scenes or those with long view distances use large occluders where possible to limit distance that can be viewed. This will help reduce the number objects drawn to the screen
- Point lights are culled based on their screen size. This is set by default in the Project Settings > Rendering
- BSP culls each face and not based the entire mesh like Static Meshes
- For dark areas, like caves where you can sometimes get pop-in, this can cause a bright flash of light depending on what is located on the other side of the object. To address this, use a large static mesh that can encapsulate or block the backside of that object.
- Use large Static Mesh occluders in place of increasing mesh bounds.
- Construct assets in a thoughtful way that does not over modularize the level. This can reduce the number of draw-calls, occlusion queries, and reduce instances where the pop-in from one frame lag can happen.
- Enable the Console Command r.VisualizeOccludedPrimitives in the editor. This Editor-Only command will show the bounding box of any primitive that is occluded.
- Enable the Console Command FREEZERENDERING to freeze the scene at this point in the editor. You can now freely move around to inspect specific rendering issues you may have. This is extremely helpful for troubleshooting and inspecting occlusion culling issues.