r.SceneCulling
r.SceneCulling
#Overview
name: r.SceneCulling
This variable is created as a Console Variable (cvar).
- type:
Var
- help:
Enable/Disable scene culling.\n While enabled, it will only build the instance hierarchy if used by any system - currently that corresponds to Nanite being enabled.\n Forces a recreate of all render state since (at present) there is only an incremental update path.
It is referenced in 6
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of r.SceneCulling is to enable or disable scene culling in Unreal Engine 5’s rendering system. Scene culling is a technique used to improve rendering performance by determining which objects or parts of a scene are visible to the camera and need to be rendered.
This setting variable is primarily used in the Renderer module of Unreal Engine 5, specifically in the SceneCulling subsystem. It’s also referenced in the Engine module, particularly in the InstancedStaticMesh component.
The value of this variable is set through the console variable system in Unreal Engine. It’s defined as a TAutoConsoleVariable with a default value of 1 (enabled).
The r.SceneCulling variable interacts with other variables, such as r.SceneCulling.Precomputed and those related to Nanite (Unreal’s virtualized geometry system). It’s also associated with the CVarSceneCulling variable, which shares the same value and is used internally in the code.
Developers should be aware that:
- Enabling scene culling (r.SceneCulling = 1) will only build the instance hierarchy if it’s used by any system, currently corresponding to Nanite being enabled.
- Changing this value forces a recreate of all render states, as there’s only an incremental update path at present.
- The effectiveness of scene culling is tied to the Nanite system. If Nanite is not used or not supported on a particular shader platform, scene culling may be disabled even if r.SceneCulling is set to 1.
Best practices when using this variable include:
- Keep it enabled (default value of 1) for better rendering performance in most scenarios.
- Be cautious when disabling it, as it may significantly impact performance, especially in scenes with many objects.
- When debugging rendering issues, temporarily disabling scene culling might help isolate problems related to object visibility.
- Be aware of its interaction with Nanite and other rendering systems when optimizing performance.
Regarding the associated variable CVarSceneCulling:
The purpose of CVarSceneCulling is the same as r.SceneCulling, as they share the same value. It’s an internal representation of the console variable used within the C++ code.
CVarSceneCulling is used directly in the Renderer module, specifically in the SceneCulling system. It’s used to check the current state of scene culling and to control the behavior of the FSceneCulling class.
The value of CVarSceneCulling is set when r.SceneCulling is set, as they are the same console variable.
Developers should be aware that:
- CVarSceneCulling is used in conjunction with other systems like Nanite to determine if scene culling should be active.
- It’s used in both runtime and editor contexts.
Best practices for CVarSceneCulling are the same as for r.SceneCulling, as they are effectively the same variable. Developers working directly with the renderer code should use CVarSceneCulling.GetValueOnAnyThread() to check the current state of scene culling.
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/SceneCulling/SceneCulling.cpp:104
Scope: file
Source code excerpt:
static TAutoConsoleVariable<int32> CVarSceneCulling(
TEXT("r.SceneCulling"),
1,
TEXT("Enable/Disable scene culling.\n")
TEXT(" While enabled, it will only build the instance hierarchy if used by any system - currently that corresponds to Nanite being enabled.\n")
TEXT(" Forces a recreate of all render state since (at present) there is only an incremental update path."),
FConsoleVariableDelegate::CreateLambda([](IConsoleVariable* InVariable)
{
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/InstancedStaticMesh/ISMInstanceDataManager.cpp:1069
Scope (from outer to inner):
file
function static bool ShouldUsePrecomputed
Source code excerpt:
{
static const auto CVarPrecomputed = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.SceneCulling.Precomputed"));
static const auto CVarSceneCull = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.SceneCulling"));
return CVarSceneCull && CVarSceneCull->GetValueOnAnyThread() != 0
&& CVarPrecomputed && CVarPrecomputed->GetValueOnAnyThread() != 0;
}
#if WITH_EDITOR
#Associated Variable and Callsites
This variable is associated with another variable named CVarSceneCulling
. They share the same value. See the following C++ source code.
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/SceneCulling/SceneCulling.cpp:103
Scope: file
Source code excerpt:
LLM_DEFINE_TAG(SceneCulling, NAME_None, NAME_None, GET_STATFNAME(STAT_SceneCullingLLM), GET_STATFNAME(STAT_SceneCullingLLM));
static TAutoConsoleVariable<int32> CVarSceneCulling(
TEXT("r.SceneCulling"),
1,
TEXT("Enable/Disable scene culling.\n")
TEXT(" While enabled, it will only build the instance hierarchy if used by any system - currently that corresponds to Nanite being enabled.\n")
TEXT(" Forces a recreate of all render state since (at present) there is only an incremental update path."),
FConsoleVariableDelegate::CreateLambda([](IConsoleVariable* InVariable)
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/SceneCulling/SceneCulling.cpp:271
Scope (from outer to inner):
file
function static bool UseSceneCulling
Source code excerpt:
static bool UseSceneCulling(EShaderPlatform ShaderPlatform)
{
return CVarSceneCulling.GetValueOnAnyThread() != 0 && UseNanite(ShaderPlatform);
}
// doesn't exist in the global definitions for some reason
using FInt8Vector3 = UE::Math::TIntVector3<int8>;
namespace EUpdateFrequencyCategory
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/SceneCulling/SceneCulling.cpp:2635
Scope (from outer to inner):
file
function FSceneCulling::FSceneCulling
Source code excerpt:
{
#if (!(UE_BUILD_SHIPPING || UE_BUILD_TEST))
if (CVarSceneCulling.GetValueOnAnyThread() != 0 && !UseNanite(InScene.GetShaderPlatform()))
{
UE_LOG(LogRenderer, Log, TEXT("SceneCulling instance hierarchy is disabled as UseNanite(%s) returned false, for scene: '%s'."), *LexToString(InScene.GetShaderPlatform()), *Scene.GetFullWorldName());
}
#endif
}
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/SceneCulling/SceneCulling.cpp:2661
Scope (from outer to inner):
file
function FSceneCulling::FUpdater &FSceneCulling::BeginUpdate
Source code excerpt:
#if (!(UE_BUILD_SHIPPING || UE_BUILD_TEST))
if (bIsEnabled && CVarSceneCulling.GetValueOnAnyThread() != 0 && !UseNanite(Scene.GetShaderPlatform()))
{
UE_LOG(LogRenderer, Log, TEXT("SceneCulling instance hierarchy is disabled as UseNanite(%s) returned false, for scene: '%s'."), *LexToString(Scene.GetShaderPlatform()), *Scene.GetFullWorldName());
}
#endif
// Note: this only works in concert with the FGlobalComponentRecreateRenderStateContext on the CVarSceneCulling callback ensuring all geometry is re-registered
bIsEnabled = UseSceneCulling(Scene.GetShaderPlatform());
bUseExplictBounds = CVarSceneCullingUseExplicitCellBounds.GetValueOnRenderThread() != 0;
SmallFootprintCellSideThreshold = CVarSmallFootprintSideThreshold.GetValueOnRenderThread();
bUseAsyncUpdate = CVarSceneCullingAsyncUpdate.GetValueOnRenderThread() != 0;