r.StencilForLODDither

r.StencilForLODDither

#Overview

name: r.StencilForLODDither

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

It is referenced in 8 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of r.StencilForLODDither is to control whether stencil tests are used for LOD (Level of Detail) dithering in the rendering process. This setting is primarily related to the rendering system in Unreal Engine 5.

The Unreal Engine subsystems that rely on this setting variable are primarily the Renderer and Material systems. This can be seen from the file locations where the variable is referenced, such as DepthRendering.cpp, MaterialShared.cpp, and RenderUtils.cpp.

The value of this variable is set through the console variable system, as evidenced by the TAutoConsoleVariable declaration. It can also be configured through the RendererSettings class, where it’s exposed as a user-configurable property.

This variable interacts with the LOD dithering system and the depth pass rendering. It’s closely associated with CVarStencilForLODDither, which is the actual console variable implementation.

Developers must be aware that:

  1. Enabling this feature forces a full prepass, which can impact performance.
  2. Changing this setting requires restarting the editor.
  3. It’s only applicable for feature levels SM5 and above.

Best practices when using this variable:

  1. Consider the performance implications of enabling a full prepass before using this feature.
  2. Test thoroughly in different scenarios to ensure it doesn’t negatively impact your specific use case.
  3. Be aware that it may interact with other rendering features, so test in combination with other relevant settings.

Regarding the associated variable CVarStencilForLODDither: This is the actual console variable implementation of r.StencilForLODDither. It’s an integer variable that determines whether to use stencil tests in the prepass and depth-equal tests in the base pass for LOD dithering. When disabled, LOD dithering is done through clip() instructions, which disables EarlyZ. This variable is read-only at runtime and affects the render thread. Developers should be aware that changing this variable will have immediate effects on the rendering pipeline and should be used cautiously, especially in performance-critical scenarios.

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Engine/RendererSettings.h:764

Scope (from outer to inner):

file
class        class URendererSettings : public UDeveloperSettings

Source code excerpt:


	UPROPERTY(config, EditAnywhere, Category=Optimizations, meta=(
		ConsoleVariable="r.StencilForLODDither",DisplayName="Use Stencil for LOD Dither Fading",
		ToolTip="Whether to use stencil for LOD dither fading.  This saves GPU time in the base pass for materials with dither fading enabled, but forces a full prepass. Changing this setting requires restarting the editor.",
		ConfigRestartRequired=true))
	uint32 bStencilForLODDither:1;

	UPROPERTY(config, EditAnywhere, Category = Optimizations, meta = (
		ConsoleVariable="r.EarlyZPass",DisplayName="Early Z-pass",

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/DepthRendering.cpp:67

Scope: file

Source code excerpt:


static TAutoConsoleVariable<int32> CVarStencilForLODDither(
	TEXT("r.StencilForLODDither"),
	0,
	TEXT("Whether to use stencil tests in the prepass, and depth-equal tests in the base pass to implement LOD dithering.\n")
	TEXT("If disabled, LOD dithering will be done through clip() instructions in the prepass and base pass, which disables EarlyZ.\n")
	TEXT("Forces a full prepass when enabled."),
	ECVF_RenderThreadSafe | ECVF_ReadOnly);

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Materials/MaterialShared.cpp:2784

Scope (from outer to inner):

file
function     void FMaterial::SetupMaterialEnvironment

Source code excerpt:

	if (IsFeatureLevelSupported(Platform, ERHIFeatureLevel::SM5))
	{	
		static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.StencilForLODDither"));
		SET_SHADER_DEFINE(OutEnvironment, USE_STENCIL_LOD_DITHER_DEFAULT, CVar->GetValueOnAnyThread() != 0 ? 1 : 0);
	}

	if (FDataDrivenShaderPlatformInfo::GetSupportsVariableRateShading(Platform) && 
		(GRHIAttachmentVariableRateShadingEnabled || GetShadingRate() != MSR_1x1) &&
		IsVariableRateShadingAllowed())

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Public/MaterialShared.h:1768

Scope (from outer to inner):

file
class        class FMaterial
function     FMaterial

Source code excerpt:

		if (CVarStencilDitheredLOD == nullptr)
		{
			CVarStencilDitheredLOD = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.StencilForLODDither"));
		}
		bStencilDitheredLOD = (CVarStencilDitheredLOD->GetValueOnAnyThread() != 0);
#if UE_CHECK_FMATERIAL_LIFETIME
		bOwnerBeginDestroyed = false;
#endif
	}

#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/RenderUtils.cpp:630

Scope (from outer to inner):

file
function     bool ShouldForceFullDepthPass

Source code excerpt:

		const bool bVirtualTextureEnabled = UseVirtualTexturing(Platform);

		static const auto StencilLODDitherCVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.StencilForLODDither"));
		const bool bStencilLODDither = StencilLODDitherCVar->GetValueOnAnyThread() != 0;

		static const auto AOComputeCVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.AmbientOcclusion.Compute"));
		const bool bAOCompute = AOComputeCVar->GetValueOnAnyThread() > 0;

		const bool bEarlyZMaterialMasking = MaskedInEarlyPass(Platform);

#Loc: <Workspace>/Engine/Source/Runtime/RenderCore/Private/Shader.cpp:1873

Scope (from outer to inner):

file
function     void ShaderMapAppendKeyString

Source code excerpt:

	if (IsFeatureLevelSupported(Platform, ERHIFeatureLevel::SM5))
	{
		static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.StencilForLODDither"));
		if (CVar && CVar->GetValueOnAnyThread() > 0)
		{
			KeyString += TEXT("_SD");
		}
	}

#Associated Variable and Callsites

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

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/DepthRendering.cpp:66

Scope: file

Source code excerpt:

	ECVF_RenderThreadSafe);

static TAutoConsoleVariable<int32> CVarStencilForLODDither(
	TEXT("r.StencilForLODDither"),
	0,
	TEXT("Whether to use stencil tests in the prepass, and depth-equal tests in the base pass to implement LOD dithering.\n")
	TEXT("If disabled, LOD dithering will be done through clip() instructions in the prepass and base pass, which disables EarlyZ.\n")
	TEXT("Forces a full prepass when enabled."),
	ECVF_RenderThreadSafe | ECVF_ReadOnly);

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/DepthRendering.cpp:99

Scope (from outer to inner):

file
function     FDepthPassInfo GetDepthPassInfo

Source code excerpt:

	Info.EarlyZPassMode = Scene ? Scene->EarlyZPassMode : DDM_None;
	Info.bEarlyZPassMovable = Scene ? Scene->bEarlyZPassMovable : false;
	Info.bDitheredLODTransitionsUseStencil = CVarStencilForLODDither.GetValueOnAnyThread() > 0;
	Info.StencilDitherPassFlags = ERDGPassFlags::Raster;

	if (GRHISupportsDepthUAV && !IsHMDHiddenAreaMaskActive())
	{
		switch (CVarStencilLODDitherMode.GetValueOnAnyThread())
		{