r.Shadow.Virtual.ResolutionLodBiasDirectional
r.Shadow.Virtual.ResolutionLodBiasDirectional
#Overview
name: r.Shadow.Virtual.ResolutionLodBiasDirectional
The value of this variable can be defined or overridden in .ini config files. 9
.ini config files referencing this setting variable.
This variable is created as a Console Variable (cvar).
- type:
Var
- help:
Bias applied to LOD calculations for directional lights. -1.0 doubles resolution, 1.0 halves it and so on.
It is referenced in 4
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of r.Shadow.Virtual.ResolutionLodBiasDirectional is to adjust the resolution of virtual shadow maps for directional lights in Unreal Engine 5. It is used in the rendering system, specifically for shadow mapping.
This setting variable is primarily used in the Renderer module of Unreal Engine 5, particularly in the Virtual Shadow Maps subsystem. It is referenced in the VirtualShadowMapClipmap.cpp and VirtualShadowMapCacheManager.cpp files, which are part of the virtual shadow mapping implementation.
The value of this variable is set as a console variable with a default value of -0.5f. It can be modified at runtime through the console or programmatically.
The variable interacts with another related variable, CVarVirtualShadowMapResolutionLodBiasDirectionalMoving, which is used for moving directional lights. These variables are often used together to calculate the final resolution bias for virtual shadow maps.
Developers should be aware that this variable affects the quality and performance of directional shadow maps. A lower value (e.g., -1.0) increases the resolution, potentially improving shadow quality at the cost of performance, while a higher value (e.g., 1.0) decreases the resolution, potentially improving performance at the cost of shadow quality.
Best practices when using this variable include:
- Adjusting it based on the specific needs of your project, balancing between shadow quality and performance.
- Testing different values to find the optimal balance for your target hardware.
- Considering the interaction with other shadow-related settings, such as r.Shadow.Virtual.MaxPhysicalPages.
The associated variable CVarVirtualShadowMapResolutionLodBiasDirectional is essentially the same as r.Shadow.Virtual.ResolutionLodBiasDirectional. It is the internal representation of the console variable in the C++ code. This variable is used directly in the rendering code to apply the resolution bias to virtual shadow map calculations for directional lights. The same considerations and best practices apply to this variable as well.
#Setting Variables
#References In INI files
Location: <Workspace>/Engine/Config/BaseScalability.ini:142, section: [ShadowQuality@0]
- INI Section:
ShadowQuality@0
- Raw value:
0.0
- Is Array:
False
Location: <Workspace>/Engine/Config/BaseScalability.ini:166, section: [ShadowQuality@1]
- INI Section:
ShadowQuality@1
- Raw value:
0.0
- Is Array:
False
Location: <Workspace>/Engine/Config/BaseScalability.ini:193, section: [ShadowQuality@2]
- INI Section:
ShadowQuality@2
- Raw value:
-0.5
- Is Array:
False
Location: <Workspace>/Engine/Config/BaseScalability.ini:220, section: [ShadowQuality@3]
- INI Section:
ShadowQuality@3
- Raw value:
-1.5
- Is Array:
False
Location: <Workspace>/Engine/Config/BaseScalability.ini:247, section: [ShadowQuality@Cine]
- INI Section:
ShadowQuality@Cine
- Raw value:
-1.5
- Is Array:
False
Location: <Workspace>/Projects/Lyra/Config/DefaultScalability.ini:19, section: [ShadowQuality@0]
- INI Section:
ShadowQuality@0
- Raw value:
0
- Is Array:
False
Location: <Workspace>/Projects/Lyra/Config/DefaultScalability.ini:22, section: [ShadowQuality@1]
- INI Section:
ShadowQuality@1
- Raw value:
0
- Is Array:
False
Location: <Workspace>/Projects/Lyra/Config/DefaultScalability.ini:25, section: [ShadowQuality@2]
- INI Section:
ShadowQuality@2
- Raw value:
0
- Is Array:
False
Location: <Workspace>/Projects/Lyra/Config/DefaultScalability.ini:28, section: [ShadowQuality@3]
- INI Section:
ShadowQuality@3
- Raw value:
-1.5
- Is Array:
False
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/VirtualShadowMaps/VirtualShadowMapClipmap.cpp:22
Scope: file
Source code excerpt:
static TAutoConsoleVariable<float> CVarVirtualShadowMapResolutionLodBiasDirectional(
TEXT( "r.Shadow.Virtual.ResolutionLodBiasDirectional" ),
-0.5f,
TEXT( "Bias applied to LOD calculations for directional lights. -1.0 doubles resolution, 1.0 halves it and so on." ),
ECVF_Scalability | ECVF_RenderThreadSafe
);
static TAutoConsoleVariable<float> CVarVirtualShadowMapResolutionLodBiasDirectionalMoving(
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/VirtualShadowMaps/VirtualShadowMapCacheManager.cpp:552
Scope (from outer to inner):
file
function FVirtualShadowMapArrayCacheManager::FVirtualShadowMapArrayCacheManager
lambda-function
Source code excerpt:
{
static const auto* CVarResolutionLodBiasLocalPtr = IConsoleManager::Get().FindTConsoleVariableDataFloat(TEXT("r.Shadow.Virtual.ResolutionLodBiasLocal"));
static const auto* CVarResolutionLodBiasDirectionalPtr = IConsoleManager::Get().FindTConsoleVariableDataFloat(TEXT("r.Shadow.Virtual.ResolutionLodBiasDirectional"));
UE_LOG(LogRenderer, Warning, TEXT("Virtual Shadow Map Page Pool overflow (%d page allocations were not served), this will produce visual artifacts (missing shadow), increase the page pool limit or reduce resolution bias to avoid.\n")
TEXT(" See r.Shadow.Virtual.MaxPhysicalPages (%d), r.Shadow.Virtual.ResolutionLodBiasLocal (%.2f), r.Shadow.Virtual.ResolutionLodBiasDirectional (%.2f), Global Resolution Lod Bias (%.2f)"),
-LastFreePhysicalPages,
MaxPhysicalPages,
CVarResolutionLodBiasLocalPtr->GetValueOnRenderThread(),
CVarResolutionLodBiasDirectionalPtr->GetValueOnRenderThread(),
GlobalResolutionLodBias);
bLoggedPageOverflow = true;
}
LastOverflowTime = float(FGameTime::GetTimeSinceAppStart().GetRealTimeSeconds());
#endif
}
#if !UE_BUILD_SHIPPING
else
{
bLoggedPageOverflow = false;
}
#endif
});
#if !UE_BUILD_SHIPPING
// Handle message with stats sent back from GPU whenever stats are enabled
StatsFeedbackSocket = GPUMessage::RegisterHandler(TEXT("Shadow.Virtual.StatsFeedback"), [this](GPUMessage::FReader Message)
{
// Culling stats
int32 NaniteNumTris = Message.Read<int32>(0);
int32 NanitePostCullNodeCount = Message.Read<int32>(0);
int32 NonNanitePostCullInstanceCount = Message.Read<int32>(0);
CSV_CUSTOM_STAT(VSM, NaniteNumTris, NaniteNumTris, ECsvCustomStatOp::Set);
CSV_CUSTOM_STAT(VSM, NanitePostCullNodeCount, NanitePostCullNodeCount, ECsvCustomStatOp::Set);
CSV_CUSTOM_STAT(VSM, NonNanitePostCullInstanceCount, NonNanitePostCullInstanceCount, ECsvCustomStatOp::Set);
// Large page area items
LastLoggedPageOverlapAppTime.SetNumZeroed(Scene->GetMaxPersistentPrimitiveIndex());
float RealTimeSeconds = float(FGameTime::GetTimeSinceAppStart().GetRealTimeSeconds());
TConstArrayView<uint32> PageAreaDiags = Message.ReadCount(FVirtualShadowMapArray::MaxPageAreaDiagnosticSlots * 2);
for (int32 Index = 0; Index < PageAreaDiags.Num(); Index += 2)
{
uint32 Overlap = PageAreaDiags[Index];
uint32 PersistentPrimitiveId = PageAreaDiags[Index + 1];
int32 PrimtiveIndex = Scene->GetPrimitiveIndex(FPersistentPrimitiveIndex{ int32(PersistentPrimitiveId) });
if (Overlap > 0 && PrimtiveIndex != INDEX_NONE)
{
if (RealTimeSeconds - LastLoggedPageOverlapAppTime[PersistentPrimitiveId] > 5.0f)
{
LastLoggedPageOverlapAppTime[PersistentPrimitiveId] = RealTimeSeconds;
UE_LOG(LogRenderer, Warning, TEXT("Non-Nanite VSM page overlap performance Warning, %d, %s, %s"), Overlap, *Scene->Primitives[PrimtiveIndex]->GetOwnerActorNameOrLabelForDebuggingOnly(), *Scene->Primitives[PrimtiveIndex]->GetFullnameForDebuggingOnly());
}
LargePageAreaItems.Add(PersistentPrimitiveId, FLargePageAreaItem{ Overlap, RealTimeSeconds });
}
}
});
#endif
#if !UE_BUILD_SHIPPING
ScreenMessageDelegate = FRendererOnScreenNotification::Get().AddLambda([this](TMultiMap<FCoreDelegates::EOnScreenMessageSeverity, FText >& OutMessages)
{
float RealTimeSeconds = float(FGameTime::GetTimeSinceAppStart().GetRealTimeSeconds());
// Show for ~5s after last overflow
if (LastOverflowTime >= 0.0f && RealTimeSeconds - LastOverflowTime < 5.0f)
{
OutMessages.Add(FCoreDelegates::EOnScreenMessageSeverity::Warning, FText::FromString(FString::Printf(TEXT("Virtual Shadow Map Page Pool overflow detected (%0.0f seconds ago)"), RealTimeSeconds - LastOverflowTime)));
}
for (const auto& Item : LargePageAreaItems)
{
int32 PrimtiveIndex = Scene->GetPrimitiveIndex(FPersistentPrimitiveIndex{ int32(Item.Key) });
uint32 Overlap = Item.Value.PageArea;
if (PrimtiveIndex != INDEX_NONE && RealTimeSeconds - Item.Value.LastTimeSeen < 2.5f)
{
OutMessages.Add(FCoreDelegates::EOnScreenMessageSeverity::Warning, FText::FromString(FString::Printf(TEXT("Non-Nanite VSM page overlap performance Warning: Primitive '%s' overlapped %d Pages"), *Scene->Primitives[PrimtiveIndex]->GetOwnerActorNameOrLabelForDebuggingOnly(), Overlap)));
}
}
#Associated Variable and Callsites
This variable is associated with another variable named CVarVirtualShadowMapResolutionLodBiasDirectional
. They share the same value. See the following C++ source code.
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/VirtualShadowMaps/VirtualShadowMapClipmap.cpp:21
Scope: file
Source code excerpt:
extern int32 GForceInvalidateDirectionalVSM;
static TAutoConsoleVariable<float> CVarVirtualShadowMapResolutionLodBiasDirectional(
TEXT( "r.Shadow.Virtual.ResolutionLodBiasDirectional" ),
-0.5f,
TEXT( "Bias applied to LOD calculations for directional lights. -1.0 doubles resolution, 1.0 halves it and so on." ),
ECVF_Scalability | ECVF_RenderThreadSafe
);
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/VirtualShadowMaps/VirtualShadowMapClipmap.cpp:180
Scope (from outer to inner):
file
function FVirtualShadowMapClipmap::FVirtualShadowMapClipmap
Source code excerpt:
// just resizing the virtual shadow maps for each clipmap, but convenient for now. This means we need to additionally bias
// which levels are present.
ResolutionLodBias = FVirtualShadowMapArray::InterpolateResolutionBias(CVarVirtualShadowMapResolutionLodBiasDirectional.GetValueOnRenderThread(), CVarVirtualShadowMapResolutionLodBiasDirectionalMoving.GetValueOnRenderThread(), LightMobilityFactor) + FMath::Log2(LodScale);
ResolutionLodBias += GetLightSceneInfo().Proxy->GetVSMResolutionLodBias();
// Clamp negative absolute resolution biases as they would exceed the maximum resolution/ranges allocated
ResolutionLodBias = FMath::Max(0.0f, ResolutionLodBias);
WorldOrigin = CameraViewMatrices.GetViewOrigin();
CameraToViewTarget = FVector::ZeroVector;