foliage.DitheredLOD
foliage.DitheredLOD
#Overview
name: foliage.DitheredLOD
This variable is created as a Console Variable (cvar).
- type:
Var
- help:
If greater than zero, dithered LOD is used, otherwise popping LOD is used.
It is referenced in 8
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of foliage.DitheredLOD is to control the LOD (Level of Detail) transition method for foliage in Unreal Engine 5. It determines whether dithered LOD or popping LOD is used for foliage rendering.
This setting variable is primarily used by the rendering system, specifically for foliage and hierarchical instanced static meshes. It is part of the Engine module and is also utilized by the MovieRenderPipeline plugin.
The value of this variable is set through a console variable (CVar) named CVarDitheredLOD. It is initialized with a default value of 1, meaning dithered LOD is enabled by default. The value can be changed at runtime through console commands or programmatically.
The main subsystems that rely on this setting variable are:
- The Hierarchical Instanced Static Mesh rendering system
- The Movie Render Pipeline
The associated variable CVarDitheredLOD interacts directly with foliage.DitheredLOD, as they share the same value and purpose.
Developers should be aware of the following when using this variable:
- A value greater than zero enables dithered LOD, while a value of zero or less uses popping LOD.
- It can be overridden in certain scenarios, such as during movie rendering, to force a specific LOD behavior.
- It interacts with other LOD-related variables like foliage.ForceLOD.
Best practices when using this variable include:
- Consider the performance implications of dithered vs. popping LOD transitions.
- Test the visual quality and performance with different values to find the optimal setting for your project.
- Be cautious when overriding this value, especially in movie rendering scenarios, as it may affect the final output quality.
Regarding the associated variable CVarDitheredLOD: The purpose of CVarDitheredLOD is to provide a programmatic way to access and modify the foliage.DitheredLOD setting. It is implemented as a TAutoConsoleVariable, which allows for easy runtime modification and querying of the value.
CVarDitheredLOD is used in the Hierarchical Instanced Static Mesh rendering code to determine whether to use multiple sections for LOD transitions. It is checked on the render thread to ensure thread-safe access to the current value.
Developers should be aware that changes to CVarDitheredLOD will directly affect the behavior of foliage LOD transitions in the engine. When using this variable, ensure that any modifications are made in a thread-safe manner, especially when accessing it from different engine subsystems.
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/HierarchicalInstancedStaticMesh.cpp:66
Scope: file
Source code excerpt:
static TAutoConsoleVariable<int32> CVarDitheredLOD(
TEXT("foliage.DitheredLOD"),
1,
TEXT("If greater than zero, dithered LOD is used, otherwise popping LOD is used."));
static TAutoConsoleVariable<int32> CVarOverestimateLOD(
TEXT("foliage.OverestimateLOD"),
0,
#Loc: <Workspace>/Engine/Plugins/MovieScene/MovieRenderPipeline/Source/MovieRenderPipelineCore/Private/Graph/Nodes/MovieGraphGlobalGameOverrides.cpp:53
Scope (from outer to inner):
file
function void UMovieGraphGlobalGameOverridesNode::BuildNewProcessCommandLineArgsImpl
Source code excerpt:
InOutDeviceProfileCvars.Add(TEXT("r.SkeletalMeshLODBias=-10"));
InOutDeviceProfileCvars.Add(TEXT("r.ParticleLODBias=-10"));
InOutDeviceProfileCvars.Add(TEXT("foliage.DitheredLOD=0"));
InOutDeviceProfileCvars.Add(TEXT("foliage.ForceLOD=0"));
}
if (bDisableHLODs)
{
// It's a command and not an integer cvar (despite taking 1/0)
#Loc: <Workspace>/Engine/Plugins/MovieScene/MovieRenderPipeline/Source/MovieRenderPipelineCore/Private/Graph/Nodes/MovieGraphGlobalGameOverrides.cpp:119
Scope (from outer to inner):
file
function void UMovieGraphGlobalGameOverridesNode::ApplySettings
Source code excerpt:
MOVIEPIPELINE_STORE_AND_OVERRIDE_CVAR_INT(PreviousSkeletalMeshBias, TEXT("r.SkeletalMeshLODBias"), -10, bOverrideValues);
MOVIEPIPELINE_STORE_AND_OVERRIDE_CVAR_INT(PreviousParticleLODBias, TEXT("r.ParticleLODBias"), -10, bOverrideValues);
MOVIEPIPELINE_STORE_AND_OVERRIDE_CVAR_INT(PreviousFoliageDitheredLOD, TEXT("foliage.DitheredLOD"), 0, bOverrideValues);
MOVIEPIPELINE_STORE_AND_OVERRIDE_CVAR_INT(PreviousFoliageForceLOD, TEXT("foliage.ForceLOD"), 0, bOverrideValues);
}
if (bDisableHLODs)
{
// It's a command and not an integer cvar (despite taking 1/0), so we can't cache it
#Loc: <Workspace>/Engine/Plugins/MovieScene/MovieRenderPipeline/Source/MovieRenderPipelineCore/Private/MoviePipelineGameOverrideSetting.cpp:67
Scope (from outer to inner):
file
function void UMoviePipelineGameOverrideSetting::ApplyCVarSettings
Source code excerpt:
MOVIEPIPELINE_STORE_AND_OVERRIDE_CVAR_INT(PreviousSkeletalMeshBias, TEXT("r.SkeletalMeshLODBias"), -10, bOverrideValues);
MOVIEPIPELINE_STORE_AND_OVERRIDE_CVAR_INT(PreviousParticleLODBias, TEXT("r.ParticleLODBias"), -10, bOverrideValues);
MOVIEPIPELINE_STORE_AND_OVERRIDE_CVAR_INT(PreviousFoliageDitheredLOD, TEXT("foliage.DitheredLOD"), 0, bOverrideValues);
MOVIEPIPELINE_STORE_AND_OVERRIDE_CVAR_INT(PreviousFoliageForceLOD, TEXT("foliage.ForceLOD"), 0, bOverrideValues);
}
if (bDisableHLODs)
{
// It's a command and not an integer cvar (despite taking 1/0), so we can't cache it
#Loc: <Workspace>/Engine/Plugins/MovieScene/MovieRenderPipeline/Source/MovieRenderPipelineCore/Private/MoviePipelineGameOverrideSetting.cpp:193
Scope (from outer to inner):
file
function void UMoviePipelineGameOverrideSetting::BuildNewProcessCommandLineArgsImpl
Source code excerpt:
InOutDeviceProfileCvars.Add(TEXT("r.SkeletalMeshLODBias=-10"));
InOutDeviceProfileCvars.Add(TEXT("r.ParticleLODBias=-10"));
InOutDeviceProfileCvars.Add(TEXT("foliage.DitheredLOD=0"));
InOutDeviceProfileCvars.Add(TEXT("foliage.ForceLOD=0"));
}
if (bDisableHLODs)
{
// It's a command and not an integer cvar (despite taking 1/0)
#Loc: <Workspace>/Engine/Plugins/MovieScene/MovieRenderPipeline/Source/MovieRenderPipelineCore/Public/Graph/Nodes/MovieGraphGlobalGameOverrides.h:120
Scope (from outer to inner):
file
function class MOVIERENDERPIPELINECORE_API UMovieGraphGlobalGameOverridesNode : public UMovieGraphSettingNode { GENERATED_BODY
Source code excerpt:
* - r.SkeletalMeshLODBias
* - r.ParticleLODBias
* - foliage.DitheredLOD
* - foliage.ForceLOD
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Rendering", meta = (EditCondition = "bOverride_bDisableLODs"))
bool bDisableLODs;
/**
* Determines if hierarchical LODs should be disabled and their real meshes used instead, regardless of distance.
* Note that this does not affect World Partition HLODs.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Rendering", meta = (EditCondition = "bOverride_bDisableHLODs"))
bool bDisableHLODs;
/**
* Flushing level streaming ensures that any pending changes to sub-levels or world partition are fully processed before we render
* the frame. This feature generally only adds to render times on the frames that have level visibility state changes, so generally
* safe to leave turned on all the time.
#Associated Variable and Callsites
This variable is associated with another variable named CVarDitheredLOD
. They share the same value. See the following C++ source code.
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/HierarchicalInstancedStaticMesh.cpp:65
Scope: file
Source code excerpt:
ECVF_Scalability);
static TAutoConsoleVariable<int32> CVarDitheredLOD(
TEXT("foliage.DitheredLOD"),
1,
TEXT("If greater than zero, dithered LOD is used, otherwise popping LOD is used."));
static TAutoConsoleVariable<int32> CVarOverestimateLOD(
TEXT("foliage.OverestimateLOD"),
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/HierarchicalInstancedStaticMesh.cpp:1490
Scope (from outer to inner):
file
function void FHierarchicalStaticMeshSceneProxy::GetDynamicMeshElements
Source code excerpt:
SCOPE_CYCLE_COUNTER(STAT_HISMCGetDynamicMeshElement);
bool bMultipleSections = bDitheredLODTransitions && CVarDitheredLOD.GetValueOnRenderThread() > 0;
// Disable multiple selections when forced LOD is set
bMultipleSections = bMultipleSections && ForcedLodModel <= 0 && CVarForceLOD.GetValueOnRenderThread() < 0;
bool bSingleSections = !bMultipleSections;
bool bOverestimate = CVarOverestimateLOD.GetValueOnRenderThread() > 0;