r.CustomDepth

r.CustomDepth

#Overview

name: r.CustomDepth

The value of this variable can be defined or overridden in .ini config files. 1 .ini config file referencing this setting variable.

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

It is referenced in 19 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of r.CustomDepth is to control the custom depth-stencil pass in Unreal Engine’s rendering pipeline. This setting is primarily used for the rendering system, specifically for postprocessing effects and custom rendering scenarios.

The Unreal Engine subsystems that rely on this setting include:

  1. Rendering system
  2. Postprocessing system
  3. Primitive component rendering
  4. Landscape rendering
  5. Foliage rendering
  6. Movie Pipeline rendering

The value of this variable is set through the console variable system, project settings, or programmatically. It can be set to:

0: Feature is disabled 1: Feature is enabled, texture is created on demand 2: Feature is enabled, texture is not released until required 3: Feature is enabled, stencil writes are enabled, texture is not released until required

This variable interacts with the CustomDepthStencil setting in the RendererSettings class. They share the same value and purpose.

Developers must be aware that:

  1. Enabling custom depth can impact performance and memory usage.
  2. Some features, like Per Actor Color Correction, require the custom depth mode to be set to “Enabled With Stencil” (value 3).
  3. Changing this setting at runtime can cause a hitch due to resource reallocation.

Best practices when using this variable:

  1. Set it in project settings for consistent behavior across the project.
  2. Use the appropriate mode based on your specific needs to balance performance and functionality.
  3. Be cautious when changing the value at runtime, as it can impact performance.

Regarding the associated variable CustomDepthStencil:

The purpose of CustomDepthStencil is to control whether the custom depth pass for tagging primitives for postprocessing passes is enabled. It is directly linked to the r.CustomDepth console variable.

This setting is used in the renderer settings and affects how primitives are rendered in the custom depth pass. It’s particularly important for features that rely on custom depth and stencil information, such as outline effects or custom post-processing.

When using CustomDepthStencil, developers should:

  1. Ensure it’s set correctly in the project settings to match the desired r.CustomDepth value.
  2. Be aware that changing this setting may require recompilation of shaders that depend on custom depth information.
  3. Consider the performance implications of enabling custom depth, especially on lower-end hardware.

Best practices include setting this value at the project level and only enabling it when necessary for specific rendering features to maintain optimal performance.

#Setting Variables

#References In INI files

Location: <Workspace>/Projects/Lyra/Config/DefaultEngine.ini:108, section: [/Script/Engine.RendererSettings]

#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:634

Scope (from outer to inner):

file
class        class URendererSettings : public UDeveloperSettings

Source code excerpt:


	UPROPERTY(config, EditAnywhere, Category=Postprocessing, meta=(
		ConsoleVariable="r.CustomDepth",DisplayName="Custom Depth-Stencil Pass",
		ToolTip="Whether the custom depth pass for tagging primitives for postprocessing passes is enabled. Enabling it on demand can save memory but may cause a hitch the first time the feature is used."))
	TEnumAsByte<ECustomDepthStencil::Type> CustomDepthStencil;

	UPROPERTY(config, EditAnywhere, Category = Postprocessing, meta = (
		ConsoleVariable = "r.CustomDepthTemporalAAJitter", DisplayName = "Custom Depth with TemporalAA Jitter",
		ToolTip = "Whether the custom depth pass has the TemporalAA jitter enabled. Disabling this can be useful when the result of the CustomDepth Pass is used after TAA (e.g. after Tonemapping)"))

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/SceneUtils.cpp:12

Scope: file

Source code excerpt:

static int32 GCustomDepthMode = 1;
static TAutoConsoleVariable<int32> CVarCustomDepth(
	TEXT("r.CustomDepth"),
	GCustomDepthMode,
	TEXT("0: feature is disabled\n")
	TEXT("1: feature is enabled, texture is created on demand\n")
	TEXT("2: feature is enabled, texture is not released until required (should be the project setting if the feature should not stall)\n")
	TEXT("3: feature is enabled, stencil writes are enabled, texture is not released until required (should be the project setting if the feature should not stall)"),
	ECVF_RenderThreadSafe);

#Loc: <Workspace>/Engine/Plugins/Experimental/ColorCorrectRegions/Source/ColorCorrectRegions/Private/ColorCorrectRegionsSceneViewExtension.cpp:248

Scope (from outer to inner):

file
namespace    anonymous
function     void StencilMerger

Source code excerpt:

	{
		static bool bNotifiedAboutCustomDepth = false;
		static const auto CVarCustomDepth = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.CustomDepth"));
		const int32 EnabledWithStencil = 3;

		if (CVarCustomDepth->GetValueOnAnyThread() != EnabledWithStencil && !bNotifiedAboutCustomDepth)
		{
			UE_LOG(ColorCorrectRegions, Error, TEXT("Per Actor Color Correction requires Custom Depth Mode to be set to \"Enabled With Stencil\""));
			bNotifiedAboutCustomDepth = true;

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/Niagara/Classes/NiagaraSystem.h:641

Scope: file

Source code excerpt:

	/**
	When enabled this is the default value set on the component.
	Optionally write this 0-255 value to the stencil buffer in CustomDepth pass (Requires project setting or r.CustomDepth == 3)
	*/
	UPROPERTY(EditAnywhere, BlueprintReadOnly, AdvancedDisplay, Category="Rendering", meta=(DisplayName="Default CustomDepthStencil Value", editcondition="bOverrideCustomDepthStencilWriteMask", UIMin = "0", UIMax = "255"))
	int32 CustomDepthStencilValue = 0;

	/**
	When enabled this is the default value set on the component.
	Adjusts the translucent object sorting priority, see PrimitiveComponent description for more details.
	*/
	UPROPERTY(EditAnywhere, BlueprintReadOnly, AdvancedDisplay, Category="Rendering", meta=(editcondition="bOverrideTranslucencySortPriority"))

#Loc: <Workspace>/Engine/Plugins/MovieScene/MovieRenderPipeline/Source/MovieRenderPipelineRenderPasses/Private/MoviePipelineDeferredPasses.cpp:263

Scope (from outer to inner):

file
function     void UMoviePipelineDeferredPassBase::SetupImpl

Source code excerpt:

	if (bEnableStencilPass)
	{
		IConsoleVariable* CVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.CustomDepth"));
		if (CVar)
		{
			PreviousCustomDepthValue = CVar->GetInt();
			const int32 CustomDepthWithStencil = 3;
			if (PreviousCustomDepthValue != CustomDepthWithStencil)
			{

#Loc: <Workspace>/Engine/Plugins/MovieScene/MovieRenderPipeline/Source/MovieRenderPipelineRenderPasses/Private/MoviePipelineDeferredPasses.cpp:347

Scope (from outer to inner):

file
function     void UMoviePipelineDeferredPassBase::TeardownImpl

Source code excerpt:

	if (PreviousCustomDepthValue.IsSet())
	{
		IConsoleVariable* CVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.CustomDepth"));
		if (CVar)
		{
			if (CVar->GetInt() != PreviousCustomDepthValue.GetValue())
			{
				UE_LOG(LogMovieRenderPipeline, Log, TEXT("Restoring custom depth/stencil value to: %d"), PreviousCustomDepthValue.GetValue());
				CVar->Set(PreviousCustomDepthValue.GetValue(), EConsoleVariableFlags::ECVF_SetByProjectSetting);

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Components/PrimitiveComponent.h:749

Scope (from outer to inner):

file
class        class ERayTracingGroupCullingPriority : uint8
class        class UPrimitiveComponent : public USceneComponent, public INavRelevantInterface, public IInterface_AsyncCompilation, public IPhysicsComponent

Source code excerpt:

	int32 VisibilityId=0;

	/** Optionally write this 0-255 value to the stencil buffer in CustomDepth pass (Requires project setting or r.CustomDepth == 3) */
	UPROPERTY(EditAnywhere, AdvancedDisplay, BlueprintReadOnly, Category=Rendering,  meta=(UIMin = "0", UIMax = "255", editcondition = "bRenderCustomDepth", DisplayName = "CustomDepth Stencil Value"))
	int32 CustomDepthStencilValue;

private:
	/** Optional user defined default values for the custom primitive data of this primitive */
	UPROPERTY(EditAnywhere, Category=Rendering, meta = (DisplayName = "Custom Primitive Data Defaults"))

#Loc: <Workspace>/Engine/Source/Runtime/Foliage/Public/FoliageType.h:386

Scope (from outer to inner):

file
class        class UFoliageType : public UObject

Source code excerpt:

	ERendererStencilMask CustomDepthStencilWriteMask;

	/** Optionally write this 0-255 value to the stencil buffer in CustomDepth pass (Requires project setting or r.CustomDepth == 3) */
	UPROPERTY(EditAnywhere, AdvancedDisplay, BlueprintReadOnly, Category=InstanceSettings,  meta=(UIMin = "0", UIMax = "255", editcondition = "bRenderCustomDepth", DisplayName = "CustomDepth Stencil Value"))
	int32 CustomDepthStencilValue;

	/**
	 * Translucent objects with a lower sort priority draw behind objects with a higher priority.
	 * Translucent objects with the same priority are rendered from back-to-front based on their bounds origin.

#Loc: <Workspace>/Engine/Source/Runtime/Landscape/Classes/LandscapeProxy.h:748

Scope: file

Source code excerpt:

	ERendererStencilMask CustomDepthStencilWriteMask;

	/** Optionally write this 0-255 value to the stencil buffer in CustomDepth pass (Requires project setting or r.CustomDepth == 3) */
	UPROPERTY(EditAnywhere, AdvancedDisplay, BlueprintReadOnly, Category=Rendering,  meta=(UIMin = "0", UIMax = "255", editcondition = "bRenderCustomDepth", DisplayName = "CustomDepth Stencil Value", LandscapeOverridable))
	int32 CustomDepthStencilValue;

	/**  Max draw distance exposed to LDs. The real max draw distance is the min (disregarding 0) of this and volumes affecting this object. */
	UPROPERTY(EditAnywhere, AdvancedDisplay, BlueprintReadOnly, Category=Rendering, meta = (DisplayName = "Desired Max Draw Distance", LandscapeOverridable))
	float LDMaxDrawDistance;

#Loc: <Workspace>/Engine/Source/Runtime/Landscape/Classes/LandscapeSplineControlPoint.h:161

Scope (from outer to inner):

file
class        class ULandscapeSplineControlPoint : public UObject

Source code excerpt:

	ERendererStencilMask CustomDepthStencilWriteMask;

	/** Optionally write this 0-255 value to the stencil buffer in CustomDepth pass (Requires project setting or r.CustomDepth == 3) */
	UPROPERTY(EditAnywhere, AdvancedDisplay, Category = Mesh, meta = (UIMin = "0", UIMax = "255", editcondition = "bRenderCustomDepth", DisplayName = "CustomDepth Stencil Value"))
	int32 CustomDepthStencilValue;

	/** 
	 * Array of runtime virtual textures into which we draw the spline segment. 
	 * The material also needs to be set up to output to a virtual texture. 

#Loc: <Workspace>/Engine/Source/Runtime/Landscape/Classes/LandscapeSplineSegment.h:258

Scope (from outer to inner):

file
class        class ULandscapeSplineSegment : public UObject

Source code excerpt:

	ERendererStencilMask CustomDepthStencilWriteMask;

	/** Optionally write this 0-255 value to the stencil buffer in CustomDepth pass (Requires project setting or r.CustomDepth == 3) */
	UPROPERTY(EditAnywhere, AdvancedDisplay, Category = LandscapeSplineMeshes, meta = (UIMin = "0", UIMax = "255", editcondition = "bRenderCustomDepth", DisplayName = "CustomDepth Stencil Value"))
	int32 CustomDepthStencilValue;

	/** 
	 * Array of runtime virtual textures into which we draw the spline segment. 
	 * The material also needs to be set up to output to a virtual texture. 

#Associated Variable and Callsites

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

#Loc: <Workspace>/Engine/Plugins/Experimental/Avalanche/Source/AvalancheMaskEditor/Private/AvaMaskEditorSVE.cpp:31

Scope (from outer to inner):

file
function     void FAvaMaskSceneViewExtension::SetupView

Source code excerpt:

{
	// Don't apply without this setting
	if (GetDefault<URendererSettings>()->CustomDepthStencil != ECustomDepthStencil::EnabledWithStencil)
	{
		UE_LOG(LogAvaMaskEditor, Warning, TEXT("The Mask overlay requires CustomDepth to be \"EnabledWithStencil\" in Project Settings."))
	}
	else
	{
		FPostProcessSettings PostProcessSettings = InView.FinalPostProcessSettings;

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

Scope (from outer to inner):

file
class        class URendererSettings : public UDeveloperSettings

Source code excerpt:

		ConsoleVariable="r.CustomDepth",DisplayName="Custom Depth-Stencil Pass",
		ToolTip="Whether the custom depth pass for tagging primitives for postprocessing passes is enabled. Enabling it on demand can save memory but may cause a hitch the first time the feature is used."))
	TEnumAsByte<ECustomDepthStencil::Type> CustomDepthStencil;

	UPROPERTY(config, EditAnywhere, Category = Postprocessing, meta = (
		ConsoleVariable = "r.CustomDepthTemporalAAJitter", DisplayName = "Custom Depth with TemporalAA Jitter",
		ToolTip = "Whether the custom depth pass has the TemporalAA jitter enabled. Disabling this can be useful when the result of the CustomDepth Pass is used after TAA (e.g. after Tonemapping)"))
	uint32 bCustomDepthTaaJitter : 1;

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/PrimitiveSceneProxy.cpp:888

Scope (from outer to inner):

file
function     void FPrimitiveSceneProxy::BuildUniformShaderParameters

Source code excerpt:

	if (ShouldRenderCustomDepth())
	{
		Builder.CustomDepthStencil(GetCustomDepthStencilValue(), GetStencilWriteMask());
	}
}

void FPrimitiveSceneProxy::SetTransform(FRHICommandListBase& RHICmdList, const FMatrix& InLocalToWorld, const FBoxSphereBounds& InBounds, const FBoxSphereBounds& InLocalBounds, FVector InActorPosition)
{
	// Update the cached transforms.

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Public/PrimitiveUniformShaderParametersBuilder.h:280

Scope (from outer to inner):

file
function     inline FPrimitiveUniformShaderParametersBuilder& CustomDepthStencil

Source code excerpt:

	}

	inline FPrimitiveUniformShaderParametersBuilder& CustomDepthStencil(uint8 StencilValue, EStencilMask StencilWriteMask)
	{
		// Translate the enum to a mask that can be consumed by the GPU with fewer operations
		uint32 GPUStencilMask;
		switch (StencilWriteMask)
		{		
		case SM_Default:

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/CustomDepthRendering.cpp:395

Scope (from outer to inner):

file
function     bool FSceneRenderer::RenderCustomDepthPass

Source code excerpt:

		const FSceneTexturesConfig& Config = FSceneTexturesConfig::Get();
		// TextureView is not supported in GLES, so we can't lookup CustomDepth and CustomStencil from a single texture
		// Do a copy of the CustomDepthStencil texture if CustomStencil is sampled in a shader.
		if (IsOpenGLPlatform(ShaderPlatform))
		{
			if (Config.bSamplesCustomStencil)
			{
				FRDGTextureRef CustomStencil = GraphBuilder.CreateTexture(CustomDepthTextures.Depth->Desc, TEXT("CustomStencil"));
				AddCopyTexturePass(GraphBuilder, CustomDepthTextures.Depth, CustomStencil);

#Loc: <Workspace>/Engine/Plugins/Experimental/ColorCorrectRegions/Source/ColorCorrectRegions/Private/ColorCorrectRegionsSceneViewExtension.cpp:248

Scope (from outer to inner):

file
namespace    anonymous
function     void StencilMerger

Source code excerpt:

	{
		static bool bNotifiedAboutCustomDepth = false;
		static const auto CVarCustomDepth = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.CustomDepth"));
		const int32 EnabledWithStencil = 3;

		if (CVarCustomDepth->GetValueOnAnyThread() != EnabledWithStencil && !bNotifiedAboutCustomDepth)
		{
			UE_LOG(ColorCorrectRegions, Error, TEXT("Per Actor Color Correction requires Custom Depth Mode to be set to \"Enabled With Stencil\""));
			bNotifiedAboutCustomDepth = true;
			return;
		}
		else if (CVarCustomDepth->GetValueOnAnyThread() == EnabledWithStencil)
		{
			bNotifiedAboutCustomDepth = false;
		}

		if (StencilIds.Num() == 0)
		{

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/SceneUtils.cpp:11

Scope: file

Source code excerpt:


static int32 GCustomDepthMode = 1;
static TAutoConsoleVariable<int32> CVarCustomDepth(
	TEXT("r.CustomDepth"),
	GCustomDepthMode,
	TEXT("0: feature is disabled\n")
	TEXT("1: feature is enabled, texture is created on demand\n")
	TEXT("2: feature is enabled, texture is not released until required (should be the project setting if the feature should not stall)\n")
	TEXT("3: feature is enabled, stencil writes are enabled, texture is not released until required (should be the project setting if the feature should not stall)"),

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/SceneUtils.cpp:25

Scope (from outer to inner):

file
function     void OnCustomDepthChanged

Source code excerpt:

	FlushRenderingCommands();
	FGlobalComponentReregisterContext ReregisterContext;
	GCustomDepthMode = CVarCustomDepth.GetValueOnAnyThread();
}

void InitCustomDepth()
{
	CVarCustomDepth.AsVariable()->SetOnChangedCallback(FConsoleVariableDelegate::CreateStatic(&OnCustomDepthChanged));
}

ECustomDepthMode GetCustomDepthMode()
{
	switch (GCustomDepthMode)
	{