r.ReflectionMethod

r.ReflectionMethod

#Overview

name: r.ReflectionMethod

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 23 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of r.ReflectionMethod is to control the reflection method used in Unreal Engine’s rendering system. It is a crucial setting for determining how reflections are calculated and rendered in the game or application.

This setting variable is primarily used by the rendering subsystem of Unreal Engine. It’s referenced in various parts of the engine, including the Renderer module, the Engine module, and the GameProjectGeneration module.

The value of this variable is set through several means:

  1. It can be configured in the project settings (URendererSettings class).
  2. It can be set via console command using the CVarReflectionMethod.
  3. It’s also set as a default value when creating new projects in the GameProjectUtils.

The r.ReflectionMethod variable interacts closely with the ‘Reflections’ variable in the URendererSettings class. They share the same value and are updated together.

Developers should be aware of the following when using this variable:

  1. It has three possible values: 0 (None), 1 (Lumen), and 2 (SSR - Screen Space Reflections).
  2. Changing this value can have significant impacts on rendering performance and visual quality.
  3. When using Lumen for Global Illumination, the engine automatically sets this to Lumen Reflections for compatibility.

Best practices when using this variable include:

  1. Consider the performance implications of each method, especially on different hardware.
  2. Ensure consistency with other rendering settings, particularly when using advanced features like Lumen.
  3. Test thoroughly on target platforms to ensure the chosen method performs well and looks good.

Regarding the associated ‘Reflections’ variable: The purpose of the Reflections variable is to provide a project-level setting for the reflection method, which directly corresponds to the r.ReflectionMethod console variable. It’s part of the URendererSettings class and allows for easy configuration through the Unreal Editor’s project settings.

This variable is used in the renderer settings and is automatically updated when r.ReflectionMethod is changed. It’s also used to enforce certain combinations of settings, such as automatically enabling Lumen Reflections when Lumen Global Illumination is enabled.

Developers should be aware that changes to this variable in the project settings will be reflected in the r.ReflectionMethod console variable, and vice versa. It’s important to consider the implications of changing this setting, as it can affect both visual quality and performance.

#Setting Variables

#References In INI files

Location: <Workspace>/Projects/Lyra/Config/DefaultEngine.ini:116, 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:483

Scope (from outer to inner):

file
class        class URendererSettings : public UDeveloperSettings

Source code excerpt:


	UPROPERTY(config, EditAnywhere, Category=Reflections, meta=(
		ConsoleVariable="r.ReflectionMethod",DisplayName="Reflection Method",
		ToolTip="Reflection Method"))
	TEnumAsByte<EReflectionMethod::Type> Reflections;

	UPROPERTY(config, EditAnywhere, Category = Reflections, meta = (
		ConsoleVariable = "r.ReflectionCaptureResolution", DisplayName = "Reflection Capture Resolution",
		ToolTip = "The cubemap resolution for all reflection capture probes. Must be power of 2. Note that for very high values the memory and performance impact may be severe."))

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/IndirectLightRendering.cpp:46

Scope: file

Source code excerpt:

// Note: Default for new projects set by GameProjectUtils
static TAutoConsoleVariable<int32> CVarReflectionMethod(
	TEXT("r.ReflectionMethod"), 2,
	TEXT("0 - None.  Reflections can come from placed Reflection Captures, Planar Reflections and Skylight but no global reflection method will be used.\n")
	TEXT("1 - Lumen.  Use Lumen Reflections, which supports Screen / Software / Hardware Ray Tracing together and integrates with Lumen Global Illumination for rough reflections and Global Illumination seen in reflections.\n")
	TEXT("2 - SSR.  Standalone Screen Space Reflections.  Low cost, but limited by screen space information.\n"),
	ECVF_RenderThreadSafe);

static TAutoConsoleVariable<int32> CVarDiffuseIndirectHalfRes(

#Loc: <Workspace>/Engine/Plugins/VirtualProduction/ICVFXTesting/Source/ICVFXTesting/Public/ICVFXTestControllerBase.h:77

Scope (from outer to inner):

file
class        class UICVFXTestControllerBase : public UGauntletTestController

Source code excerpt:

		TEXT("r.RayTracing"),
		TEXT("r.DynamicGlobalIlluminationMethod"),
		TEXT("r.ReflectionMethod"),
		TEXT("r.Lumen"),
		TEXT("FX.AllowGPUParticles"),
		TEXT("r.Shadow.Virtual.Enable")};

	uint32 RunCount;

#Loc: <Workspace>/Engine/Source/Editor/GameProjectGeneration/Private/GameProjectUtils.cpp:115

Scope (from outer to inner):

file
namespace    anonymous
function     void AddLumenConfigValues

Source code excerpt:

		ConfigValues.Emplace(TEXT("DefaultEngine.ini"),
			TEXT("/Script/Engine.RendererSettings"),
			TEXT("r.ReflectionMethod"),
			TEXT("1"),
			true /* ShouldReplaceExistingValue */);
	}

	void AddNewProjectDefaultShadowConfigValues(const FProjectInformation& InProjectInfo, TArray<FTemplateConfigValue>& ConfigValues)
	{
		// Enable support for virtual shadow maps by default for new projects
		ConfigValues.Emplace(TEXT("DefaultEngine.ini"),
			TEXT("/Script/Engine.RendererSettings"),
			TEXT("r.Shadow.Virtual.Enable"),

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Engine/EngineTypes.h:440

Scope: file

Source code excerpt:

}

// Note: Must match r.ReflectionMethod, this is used in URendererSettings
UENUM()
namespace EReflectionMethod
{
	enum Type : int
	{
		/** No global reflection method will be used. Reflections can still come from Reflection Captures, Planar Reflections or a Skylight placed in the level. */

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/RendererSettings.cpp:218

Scope (from outer to inner):

file
function     void URendererSettings::PostEditChangeProperty

Source code excerpt:

				Reflections = EReflectionMethod::Lumen;

				IConsoleVariable* CVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.ReflectionMethod"));
				CVar->Set((int32)Reflections, ECVF_SetByProjectSetting);

				UpdateDependentPropertyInConfigFile(this, GET_MEMBER_NAME_CHECKED(URendererSettings, Reflections));
			}

			if (!bGenerateMeshDistanceFields)

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/SceneView.cpp:2004

Scope (from outer to inner):

file
function     void FSceneView::StartFinalPostprocessSettings

Source code excerpt:


		{
			static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.ReflectionMethod"));
			FinalPostProcessSettings.ReflectionMethod = (EReflectionMethod::Type)CVar->GetValueOnGameThread();
		}

		{
			static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.Lumen.TranslucencyReflections.FrontLayer.EnableForProject"));
			FinalPostProcessSettings.LumenFrontLayerTranslucencyReflections = CVar->GetValueOnGameThread() != 0;

#Associated Variable and Callsites

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

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

Scope (from outer to inner):

file
class        class URendererSettings : public UDeveloperSettings

Source code excerpt:

		ConsoleVariable="r.ReflectionMethod",DisplayName="Reflection Method",
		ToolTip="Reflection Method"))
	TEnumAsByte<EReflectionMethod::Type> Reflections;

	UPROPERTY(config, EditAnywhere, Category = Reflections, meta = (
		ConsoleVariable = "r.ReflectionCaptureResolution", DisplayName = "Reflection Capture Resolution",
		ToolTip = "The cubemap resolution for all reflection capture probes. Must be power of 2. Note that for very high values the memory and performance impact may be severe."))
	int32 ReflectionCaptureResolution;

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/RendererSettings.cpp:212

Scope (from outer to inner):

file
function     void URendererSettings::PostEditChangeProperty

Source code excerpt:

			&& DynamicGlobalIllumination == EDynamicGlobalIlluminationMethod::Lumen)
		{
			if (Reflections != EReflectionMethod::Lumen)
			{
				FMessageDialog::Open(EAppMsgType::Ok, LOCTEXT("Lumen Reflections automatically enabled", "Lumen Reflections are designed to work with Lumen Global Illumination, and have been automatically enabled."));

				Reflections = EReflectionMethod::Lumen;

				IConsoleVariable* CVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.ReflectionMethod"));
				CVar->Set((int32)Reflections, ECVF_SetByProjectSetting);

				UpdateDependentPropertyInConfigFile(this, GET_MEMBER_NAME_CHECKED(URendererSettings, Reflections));
			}

			if (!bGenerateMeshDistanceFields)
			{
				FMessageDialog::Open(EAppMsgType::Ok, LOCTEXT("'Generate Mesh Distance Fields' automatically enabled", "Lumen Global Illumination requires 'Generate Mesh Distance Fields'.  This has been enabled automatically, and requires an editor restart."));

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/RendererSettings.cpp:365

Scope (from outer to inner):

file
function     bool URendererSettings::CanEditChange

Source code excerpt:


	if (InProperty->GetFName() == GET_MEMBER_NAME_CHECKED(URendererSettings, DynamicGlobalIllumination)
		|| InProperty->GetFName() == GET_MEMBER_NAME_CHECKED(URendererSettings, Reflections)
		|| InProperty->GetFName() == GET_MEMBER_NAME_CHECKED(URendererSettings, ShadowMapMethod))
	{
		return !bForwardShading;
	}

	if ((InProperty->GetFName() == GET_MEMBER_NAME_CHECKED(URendererSettings, bMobileSupportDeferredOnOpenGL)))

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/DeferredShadingRenderer.h:101

Scope: file

Source code excerpt:

	None = 0,
	ScreenProbeGather = 1u << 0,
	Reflections = 1u << 1,
	StoreDepthHistory = 1u << 2,
	Composite = 1u << 3,
	All = ScreenProbeGather | Reflections | StoreDepthHistory | Composite
};
ENUM_CLASS_FLAGS(ELumenIndirectLightingSteps)

struct FAsyncLumenIndirectLightingOutputs
{
	struct FViewOutputs

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/DeferredShadingRenderer.h:134

Scope (from outer to inner):

file
function     void DoneAsync

Source code excerpt:

		if (bAsyncReflections)
		{
			EnumRemoveFlags(StepsLeft, ELumenIndirectLightingSteps::Reflections | ELumenIndirectLightingSteps::StoreDepthHistory);
		}
	}

	void DonePreLights()
	{
		if (StepsLeft == ELumenIndirectLightingSteps::All)

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/IndirectLightRendering.cpp:1052

Scope (from outer to inner):

file
function     void FDeferredShadingSceneRenderer::RenderDiffuseIndirectAndAmbientOcclusion

Source code excerpt:

			if (ViewPipelineState.ReflectionsMethod == EReflectionsMethod::Lumen)
			{
				if (EnumHasAnyFlags(StepsLeft, ELumenIndirectLightingSteps::Reflections))
				{
					const auto& MeshSDFGridParams = bDoComposite ? MeshSDFGridParameters : AllViewOutputs[ViewIndex].MeshSDFGridParameters;
					const auto& RadianceCacheParams = bDoComposite ? RadianceCacheParameters : AllViewOutputs[ViewIndex].RadianceCacheParameters;

					OutTextures.Textures[3] = RenderLumenReflections(
						GraphBuilder,

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

Scope (from outer to inner):

file
namespace    anonymous

Source code excerpt:


	// Denoise first bounce specular.
	Reflections,

	// Denoise ambient occlusion.
	AmbientOcclusion,

	// Denoise first bounce diffuse and ambient occlusion.
	DiffuseAndAmbientOcclusion,

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/ScreenSpaceDenoise.cpp:215

Scope (from outer to inner):

file
namespace    anonymous
function     static bool UsesConstantPixelDensityPassLayout

Source code excerpt:

		SignalProcessing == ESignalProcessing::ShadowVisibilityMask ||
		SignalProcessing == ESignalProcessing::PolychromaticPenumbraHarmonic ||
		SignalProcessing == ESignalProcessing::Reflections ||
		SignalProcessing == ESignalProcessing::AmbientOcclusion ||
		SignalProcessing == ESignalProcessing::DiffuseAndAmbientOcclusion ||
		SignalProcessing == ESignalProcessing::DiffuseSphericalHarmonic ||
		SignalProcessing == ESignalProcessing::ScreenSpaceDiffuseIndirect ||
		SignalProcessing == ESignalProcessing::IndirectProbeHierarchy);
}

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/ScreenSpaceDenoise.cpp:227

Scope (from outer to inner):

file
namespace    anonymous
function     static bool SignalSupportsUpscaling

Source code excerpt:

{
	return (
		SignalProcessing == ESignalProcessing::Reflections ||
		SignalProcessing == ESignalProcessing::AmbientOcclusion ||
		SignalProcessing == ESignalProcessing::DiffuseAndAmbientOcclusion);
}

/** Returns whether a signal processing uses an injestion pass. */
static bool SignalUsesInjestion(ESignalProcessing SignalProcessing)

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/ScreenSpaceDenoise.cpp:250

Scope (from outer to inner):

file
namespace    anonymous
function     static bool SignalUsesPreConvolution

Source code excerpt:

	return
		SignalProcessing == ESignalProcessing::ShadowVisibilityMask ||
		SignalProcessing == ESignalProcessing::Reflections ||
		SignalProcessing == ESignalProcessing::AmbientOcclusion ||
		SignalProcessing == ESignalProcessing::DiffuseAndAmbientOcclusion;
}

/** Returns whether a signal processing uses a history rejection pre convolution pass. */
static bool SignalUsesRejectionPreConvolution(ESignalProcessing SignalProcessing)

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/ScreenSpaceDenoise.cpp:303

Scope (from outer to inner):

file
namespace    anonymous
function     static int32 SignalMaxBatchSize

Source code excerpt:

	}
	else if (
		SignalProcessing == ESignalProcessing::Reflections ||
		SignalProcessing == ESignalProcessing::PolychromaticPenumbraHarmonic ||
		SignalProcessing == ESignalProcessing::AmbientOcclusion ||
		SignalProcessing == ESignalProcessing::DiffuseAndAmbientOcclusion ||
		SignalProcessing == ESignalProcessing::DiffuseSphericalHarmonic ||
		SignalProcessing == ESignalProcessing::ScreenSpaceDiffuseIndirect ||
		SignalProcessing == ESignalProcessing::IndirectProbeHierarchy)

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/ScreenSpaceDenoise.cpp:330

Scope (from outer to inner):

file
namespace    anonymous
function     static bool SignalSupportMultiSPP

Source code excerpt:

		SignalProcessing == ESignalProcessing::ShadowVisibilityMask ||
		SignalProcessing == ESignalProcessing::PolychromaticPenumbraHarmonic ||
		SignalProcessing == ESignalProcessing::Reflections ||
		SignalProcessing == ESignalProcessing::AmbientOcclusion ||
		SignalProcessing == ESignalProcessing::DiffuseAndAmbientOcclusion ||
		SignalProcessing == ESignalProcessing::DiffuseSphericalHarmonic ||
		SignalProcessing == ESignalProcessing::ScreenSpaceDiffuseIndirect ||
		SignalProcessing == ESignalProcessing::IndirectProbeHierarchy);
}

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/ScreenSpaceDenoise.cpp:765

Scope (from outer to inner):

file
namespace    anonymous
function     static bool ShouldCompileSignalPipeline

Source code excerpt:

		return FDataDrivenShaderPlatformInfo::GetCompileSignalProcessingPipeline(Platform) || FDataDrivenShaderPlatformInfo::GetSupportsSSDIndirect(Platform);
	}
	else if (SignalProcessing == ESignalProcessing::Reflections)
	{
		return RHISupportsRayTracingShaders(Platform);
	}
	else if (
		SignalProcessing == ESignalProcessing::ShadowVisibilityMask ||
		SignalProcessing == ESignalProcessing::AmbientOcclusion ||

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/ScreenSpaceDenoise.cpp:1428

Scope (from outer to inner):

file
function     static void DenoiseSignalAtConstantPixelDensity

Source code excerpt:

			HistoryDescs[1].Format = PF_FloatRGBA;
		}
		else if (Settings.SignalProcessing == ESignalProcessing::Reflections)
		{
			ReconstructionDescs[0].Format = HistoryDescs[0].Format = PF_FloatRGBA;
			ReconstructionDescs[1].Format = HistoryDescs[1].Format = PF_G16R16F;
			ReconstructionTextureCount = HistoryTextureCountPerSignal = 2;
			bHasReconstructionLayoutDifferentFromHistory = false;
		}

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/ScreenSpaceDenoise.cpp:2557

Scope (from outer to inner):

file
class        class FDefaultScreenSpaceDenoiser : public IScreenSpaceDenoiser
function     FReflectionsOutputs DenoiseReflections

Source code excerpt:

		FSSDConstantPixelDensitySettings Settings;
		Settings.FullResViewport = View.ViewRect;
		Settings.SignalProcessing = ESignalProcessing::Reflections;
		Settings.InputResolutionFraction = RayTracingConfig.ResolutionFraction;
		Settings.ReconstructionSamples = CVarReflectionReconstructionSampleCount.GetValueOnRenderThread();
		Settings.PreConvolutionCount = CVarReflectionPreConvolutionCount.GetValueOnRenderThread();
		Settings.bUseTemporalAccumulation = CVarReflectionTemporalAccumulation.GetValueOnRenderThread() != 0;
		Settings.MaxInputSPP = RayTracingConfig.RayCountPerPixel;

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/ScreenSpaceDenoise.cpp:2606

Scope (from outer to inner):

file
class        class FDefaultScreenSpaceDenoiser : public IScreenSpaceDenoiser
function     FReflectionsOutputs DenoiseWaterReflections

Source code excerpt:

		FSSDConstantPixelDensitySettings Settings;
		Settings.FullResViewport = View.ViewRect;
		Settings.SignalProcessing = ESignalProcessing::Reflections; // TODO: water reflection to denoise only water pixels
		Settings.InputResolutionFraction = RayTracingConfig.ResolutionFraction;
		Settings.ReconstructionSamples = CVarReflectionReconstructionSampleCount.GetValueOnRenderThread();
		Settings.PreConvolutionCount = CVarReflectionPreConvolutionCount.GetValueOnRenderThread();
		Settings.bUseTemporalAccumulation = CVarReflectionTemporalAccumulation.GetValueOnRenderThread() != 0;
		Settings.MaxInputSPP = RayTracingConfig.RayCountPerPixel;