r.Decal.NormalReprojectionEnabled

r.Decal.NormalReprojectionEnabled

#Overview

name: r.Decal.NormalReprojectionEnabled

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

It is referenced in 4 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of r.Decal.NormalReprojectionEnabled is to control the normal reprojection feature for DBuffer decals in the Unreal Engine 5 rendering system. This setting variable is specifically related to the deferred decal rendering process.

The Unreal Engine subsystem that relies on this setting variable is the Renderer module, particularly the deferred decal rendering component. This can be seen from the file location where the variable is defined and used: “Engine/Source/Runtime/Renderer/Private/CompositionLighting/PostProcessDeferredDecals.cpp”.

The value of this variable is set as a console variable using the TAutoConsoleVariable template. It is initialized to false by default, meaning the feature is disabled unless explicitly enabled.

This variable interacts with several other variables and systems:

  1. It depends on the motion in depth prepass being enabled (r.VelocityOutputPass=0).
  2. It’s used in conjunction with CVarDBufferDecalNormalReprojectionThresholdLow and CVarDBufferDecalNormalReprojectionThresholdHigh.
  3. It interacts with the View.PrevViewInfo.GBufferA buffer from the previous frame.

Developers must be aware that:

  1. This feature is only effective when motion in depth prepass is enabled.
  2. It affects the performance and visual quality of DBuffer decals.
  3. It may introduce artifacts if not used correctly, as it relies on data from the previous frame.

Best practices when using this variable include:

  1. Only enable it if you need the visual improvement for DBuffer decals and can afford the performance cost.
  2. Ensure that motion in depth prepass is enabled when using this feature.
  3. Test thoroughly to ensure no unwanted artifacts are introduced.

Regarding the associated variable CVarDBufferDecalNormalReprojectionEnabled:

The purpose of CVarDBufferDecalNormalReprojectionEnabled is to provide programmatic access to the r.Decal.NormalReprojectionEnabled setting within the C++ code. It’s an internal representation of the console variable.

This variable is used in the Renderer module to determine if normal reprojection should be applied during the deferred decal rendering process.

The value of this variable is set by the console variable system when r.Decal.NormalReprojectionEnabled is modified.

It interacts directly with the rendering logic, influencing how normals are processed for DBuffer decals.

Developers should be aware that this variable reflects the state of the console variable and should not be modified directly in most cases.

Best practices for using this variable include:

  1. Use GetValueOnRenderThread() to safely access its value in render thread code.
  2. Don’t modify this variable directly; instead, change the console variable r.Decal.NormalReprojectionEnabled.
  3. Be aware of its performance implications when enabled.

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/CompositionLighting/PostProcessDeferredDecals.cpp:48

Scope: file

Source code excerpt:


static TAutoConsoleVariable<bool> CVarDBufferDecalNormalReprojectionEnabled(
	TEXT("r.Decal.NormalReprojectionEnabled"),
	false, 
	TEXT("If true, normal reprojection from the previous frame is allowed in SceneTexture nodes on DBuffer decals, provided that motion ")
	TEXT("in depth prepass is enabled as well (r.VelocityOutputPass=0). Otherwise the fallback is the normal extracted from the depth buffer."),
	ECVF_RenderThreadSafe);

bool AreDecalsEnabled(const FSceneViewFamily& ViewFamily)

#Associated Variable and Callsites

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

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/CompositionLighting/PostProcessDeferredDecals.cpp:47

Scope: file

Source code excerpt:

	ECVF_RenderThreadSafe);

static TAutoConsoleVariable<bool> CVarDBufferDecalNormalReprojectionEnabled(
	TEXT("r.Decal.NormalReprojectionEnabled"),
	false, 
	TEXT("If true, normal reprojection from the previous frame is allowed in SceneTexture nodes on DBuffer decals, provided that motion ")
	TEXT("in depth prepass is enabled as well (r.VelocityOutputPass=0). Otherwise the fallback is the normal extracted from the depth buffer."),
	ECVF_RenderThreadSafe);

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/CompositionLighting/PostProcessDeferredDecals.cpp:251

Scope (from outer to inner):

file
function     TUniformBufferRef<FDeferredDecalUniformParameters> CreateDeferredDecalUniformBuffer

Source code excerpt:

	const bool bIsMotionInDepth = FVelocityRendering::DepthPassCanOutputVelocity(View.GetFeatureLevel());
	// if we have early motion vectors (bIsMotionInDepth) and the cvar is enabled and we actually have a buffer from the previous frame (View.PrevViewInfo.GBufferA.IsValid())
	const bool bIsNormalReprojectionEnabled = (bIsMotionInDepth && CVarDBufferDecalNormalReprojectionEnabled.GetValueOnRenderThread() && View.PrevViewInfo.GBufferA.IsValid());

	FDeferredDecalUniformParameters UniformParameters;
	UniformParameters.NormalReprojectionThresholdLow  = CVarDBufferDecalNormalReprojectionThresholdLow .GetValueOnRenderThread();
	UniformParameters.NormalReprojectionThresholdHigh = CVarDBufferDecalNormalReprojectionThresholdHigh.GetValueOnRenderThread();
	UniformParameters.NormalReprojectionEnabled = bIsNormalReprojectionEnabled ? 1 : 0;
	

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/CompositionLighting/PostProcessDeferredDecals.cpp:738

Scope (from outer to inner):

file
function     void ExtractNormalsForNextFrameReprojection

Source code excerpt:

{
	// save the previous frame if early motion vectors are enabled and normal reprojection is enabled, so there should be no cost if these options are off
	const bool bIsNormalReprojectionEnabled = CVarDBufferDecalNormalReprojectionEnabled.GetValueOnRenderThread();

	if (bIsNormalReprojectionEnabled)
	{
		for (int32 Index = 0; Index < Views.Num(); Index++)
		{
			if (FVelocityRendering::DepthPassCanOutputVelocity(Views[Index].GetFeatureLevel()))