r.Shadow.PreshadowsForceLowestDetailLevel

r.Shadow.PreshadowsForceLowestDetailLevel

#Overview

name: r.Shadow.PreshadowsForceLowestDetailLevel

This variable is created as a Console Variable (cvar).

It is referenced in 5 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of r.Shadow.PreshadowsForceLowestDetailLevel is to control the level of detail (LOD) used for static meshes when rendering preshadow depth maps in Unreal Engine 5’s rendering system.

This setting variable is primarily used by the rendering subsystem, specifically in the shadow rendering and setup components. It affects how preshadows are rendered for static meshes.

The value of this variable is set through the console variable system in Unreal Engine. It’s initialized to 0 (disabled) by default, but can be changed at runtime.

The associated variable GPreshadowsForceLowestLOD directly interacts with r.Shadow.PreshadowsForceLowestDetailLevel. They share the same value, with GPreshadowsForceLowestLOD being the internal C++ representation used in the engine code.

Developers must be aware that enabling this variable (setting it to 1) will force static meshes to render their lowest detail level into preshadow depth maps. This can cause artifacts with poor quality LODs, particularly with objects like tree billboards.

Best practices when using this variable include:

  1. Keep it disabled by default for better visual quality.
  2. Consider enabling it only when performance is a critical concern and the visual artifacts are acceptable.
  3. Test thoroughly with various static meshes, particularly those with multiple LOD levels, to ensure the visual impact is acceptable for your project.

Regarding the associated variable GPreshadowsForceLowestLOD:

Developers should be cautious when directly interacting with GPreshadowsForceLowestLOD in custom engine modifications, as it’s generally preferable to use the console variable r.Shadow.PreshadowsForceLowestDetailLevel for controlling this behavior.

#References in C++ code

#Callsites

This variable is referenced in the following C++ source code:

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/ShadowSetup.cpp:181

Scope: file

Source code excerpt:

int32 GPreshadowsForceLowestLOD = 0;
FAutoConsoleVariableRef CVarPreshadowsForceLowestLOD(
	TEXT("r.Shadow.PreshadowsForceLowestDetailLevel"),
	GPreshadowsForceLowestLOD,
	TEXT("When enabled, static meshes render their lowest detail level into preshadow depth maps.  Disabled by default as it causes artifacts with poor quality LODs (tree billboard)."),
	ECVF_Scalability | ECVF_RenderThreadSafe
	);

/**

#Associated Variable and Callsites

This variable is associated with another variable named GPreshadowsForceLowestLOD. They share the same value. See the following C++ source code.

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/ShadowDepthRendering.cpp:1252

Scope (from outer to inner):

file
function     void FProjectedShadowInfo::ModifyViewForShadow

Source code excerpt:

	FoundView->ViewRect = OriginalViewRect;

	extern int32 GPreshadowsForceLowestLOD;

	if (bPreShadow && GPreshadowsForceLowestLOD)
	{
		(int32&)FoundView->DrawDynamicFlags |= EDrawDynamicFlags::ForceLowestLOD;
	}
}

FViewInfo* FProjectedShadowInfo::FindViewForShadow(FSceneRenderer* SceneRenderer) const

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/ShadowSetup.cpp:179

Scope: file

Source code excerpt:

}

int32 GPreshadowsForceLowestLOD = 0;
FAutoConsoleVariableRef CVarPreshadowsForceLowestLOD(
	TEXT("r.Shadow.PreshadowsForceLowestDetailLevel"),
	GPreshadowsForceLowestLOD,
	TEXT("When enabled, static meshes render their lowest detail level into preshadow depth maps.  Disabled by default as it causes artifacts with poor quality LODs (tree billboard)."),
	ECVF_Scalability | ECVF_RenderThreadSafe
	);

/**
 * This value specifies how much bounds will be expanded when rendering a cached preshadow (0.15 = 15% larger).

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/ShadowSetup.cpp:1711

Scope (from outer to inner):

file
function     FLODMask FProjectedShadowInfo::CalcAndUpdateLODToRender

Source code excerpt:


	// Use lowest LOD for PreShadow
	if (bPreShadow && GPreshadowsForceLowestLOD)
	{
		int8 LODToRenderScan = -MAX_int8;

		for (int32 Index = 0; Index < PrimitiveSceneInfo->StaticMeshRelevances.Num(); Index++)
		{
			LODToRenderScan = FMath::Max<int8>(PrimitiveSceneInfo->StaticMeshRelevances[Index].GetLODIndex(), LODToRenderScan);

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/ShadowSetup.cpp:2671

Scope (from outer to inner):

file
function     bool FProjectedShadowInfo::GatherDynamicMeshElements

Source code excerpt:

		ReusedViewsArray[0] = ShadowDepthView;

		if (bPreShadow && GPreshadowsForceLowestLOD)
		{
			ShadowDepthView->DrawDynamicFlags = EDrawDynamicFlags::ForceLowestLOD;
		}

		if (CascadeSettings.bFarShadowCascade)
		{