ShowFlag.LocalExposure

ShowFlag.LocalExposure

#Overview

name: ShowFlag.LocalExposure

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

It is referenced in 16 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of ShowFlag.LocalExposure is to control the visibility of local exposure in the rendering process. Local exposure is a post-processing effect that adjusts the brightness of different parts of an image based on their local luminance, enhancing the overall contrast and detail visibility.

This setting variable is primarily used in the rendering system, specifically in the post-processing pipeline. It is part of Unreal Engine’s advanced rendering features.

The Unreal Engine subsystems that rely on this setting variable are:

  1. The Renderer module
  2. The Engine module, particularly in scene view and post-processing components

The value of this variable is set through the engine’s show flags system, which allows toggling various rendering features on and off. It can be controlled via the engine’s UI or programmatically.

The associated variable LocalExposure interacts closely with ShowFlag.LocalExposure. When ShowFlag.LocalExposure is disabled, the LocalExposure settings are effectively nullified in the post-processing pipeline.

Developers should be aware that:

  1. This feature can have a significant impact on the final rendered image and should be used judiciously.
  2. It interacts with other post-processing effects like eye adaptation and tonemapping.
  3. Enabling or disabling this feature may require adjustments to other exposure-related settings for optimal results.

Best practices when using this variable include:

  1. Testing the visual impact with and without local exposure enabled to ensure it enhances rather than detracts from the scene.
  2. Adjusting related parameters like LocalExposureHighlightContrastScale and LocalExposureShadowContrastScale for fine-tuning.
  3. Considering performance implications, especially on lower-end hardware.

Regarding the associated variable LocalExposure:

The purpose of LocalExposure is to store and manage the actual parameters for the local exposure effect. It contains various settings that control how the local exposure is calculated and applied.

This variable is used extensively in the rendering pipeline, particularly in post-processing passes related to exposure, eye adaptation, and tonemapping.

The values for LocalExposure are typically set in the post-processing volume or camera settings, and can be adjusted in real-time.

LocalExposure interacts with several other variables and systems, including eye adaptation, bloom, and tonemapping.

Developers should be aware that:

  1. The effects of LocalExposure can be subtle but significant, affecting the overall look and feel of the scene.
  2. It’s important to balance LocalExposure settings with global exposure for a cohesive look.

Best practices for using LocalExposure include:

  1. Fine-tuning its parameters in conjunction with other exposure and post-processing settings.
  2. Using it to enhance local contrast and detail without creating an unnatural look.
  3. Testing in various lighting conditions to ensure consistent results across different scenes.

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Public/ShowFlagsValues.inl:23

Scope: file

Source code excerpt:

SHOWFLAG_ALWAYS_ACCESSIBLE(Bloom, SFG_PostProcess, NSLOCTEXT("UnrealEd", "BloomSF", "Bloom"))
/** Local Exposure, for now SHOWFLAG_ALWAYS_ACCESSIBLE because it's exposed in SceneCapture */
SHOWFLAG_ALWAYS_ACCESSIBLE(LocalExposure, SFG_PostProcess, NSLOCTEXT("UnrealEd", "LocalExposureSF", "Local Exposure"))
/** HDR->LDR conversion is done through a tone mapper (otherwise linear mapping is used) */
SHOWFLAG_FIXED_IN_SHIPPING(1, Tonemapper, SFG_PostProcess, NSLOCTEXT("UnrealEd", "TonemapperSF", "Tonemapper"))
/** Any Anti-aliasing e.g. FXAA, Temporal AA, for now SHOWFLAG_ALWAYS_ACCESSIBLE because it's exposed in SceneCapture */
SHOWFLAG_ALWAYS_ACCESSIBLE(AntiAliasing, SFG_Normal, NSLOCTEXT("UnrealEd", "AntiAliasingSF", "Anti-aliasing"))
/** Only used in AntiAliasing is on, true:uses Temporal AA, otherwise FXAA, for now SHOWFLAG_ALWAYS_ACCESSIBLE because it's exposed in SceneCapture  */
SHOWFLAG_ALWAYS_ACCESSIBLE(TemporalAA, SFG_Advanced, NSLOCTEXT("UnrealEd", "TemporalAASF", "Temporal AA (instead FXAA)"))

#Associated Variable and Callsites

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

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

Scope (from outer to inner):

file
function     void FSceneView::EndFinalPostprocessSettings

Source code excerpt:

		const int LocalExposureCVarValue = LocalExposureCVar->GetValueOnGameThread();

		if (LocalExposureCVarValue <= 0 || !Family->EngineShowFlags.LocalExposure)
		{
			FinalPostProcessSettings.LocalExposureHighlightContrastScale = 1.0f;
			FinalPostProcessSettings.LocalExposureShadowContrastScale = 1.0f;
			FinalPostProcessSettings.LocalExposureHighlightContrastCurve = nullptr;
			FinalPostProcessSettings.LocalExposureShadowContrastCurve = nullptr;
			FinalPostProcessSettings.LocalExposureDetailStrength = 1.0f;

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Public/ShowFlagsValues.inl:23

Scope: file

Source code excerpt:

SHOWFLAG_ALWAYS_ACCESSIBLE(Bloom, SFG_PostProcess, NSLOCTEXT("UnrealEd", "BloomSF", "Bloom"))
/** Local Exposure, for now SHOWFLAG_ALWAYS_ACCESSIBLE because it's exposed in SceneCapture */
SHOWFLAG_ALWAYS_ACCESSIBLE(LocalExposure, SFG_PostProcess, NSLOCTEXT("UnrealEd", "LocalExposureSF", "Local Exposure"))
/** HDR->LDR conversion is done through a tone mapper (otherwise linear mapping is used) */
SHOWFLAG_FIXED_IN_SHIPPING(1, Tonemapper, SFG_PostProcess, NSLOCTEXT("UnrealEd", "TonemapperSF", "Tonemapper"))
/** Any Anti-aliasing e.g. FXAA, Temporal AA, for now SHOWFLAG_ALWAYS_ACCESSIBLE because it's exposed in SceneCapture */
SHOWFLAG_ALWAYS_ACCESSIBLE(AntiAliasing, SFG_Normal, NSLOCTEXT("UnrealEd", "AntiAliasingSF", "Anti-aliasing"))
/** Only used in AntiAliasing is on, true:uses Temporal AA, otherwise FXAA, for now SHOWFLAG_ALWAYS_ACCESSIBLE because it's exposed in SceneCapture  */
SHOWFLAG_ALWAYS_ACCESSIBLE(TemporalAA, SFG_Advanced, NSLOCTEXT("UnrealEd", "TemporalAASF", "Temporal AA (instead FXAA)"))

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/PostProcess/PostProcessBloomSetup.cpp:34

Scope (from outer to inner):

file
namespace    anonymous

Source code excerpt:

	SHADER_PARAMETER_RDG_TEXTURE(Texture2D, BlurredLogLum)
	SHADER_PARAMETER_SAMPLER(SamplerState, BlurredLogLumSampler)
	SHADER_PARAMETER_STRUCT(FLocalExposureParameters, LocalExposure)
	SHADER_PARAMETER_RDG_BUFFER_SRV(StructuredBuffer<float4>, EyeAdaptationBuffer)
	SHADER_PARAMETER_STRUCT(FEyeAdaptationParameters, EyeAdaptation)
	SHADER_PARAMETER(float, BloomThreshold)
END_SHADER_PARAMETER_STRUCT()

FBloomSetupParameters GetBloomSetupParameters(

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/PostProcess/PostProcessBloomSetup.cpp:55

Scope (from outer to inner):

file
namespace    anonymous
function     FBloomSetupParameters GetBloomSetupParameters

Source code excerpt:

	Parameters.BlurredLogLum = Inputs.BlurredLogLuminanceTexture;
	Parameters.BlurredLogLumSampler = TStaticSamplerState<SF_Bilinear, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();
	Parameters.LocalExposure = *Inputs.LocalExposureParameters;
	Parameters.EyeAdaptationBuffer = GraphBuilder.CreateSRV(Inputs.EyeAdaptationBuffer);
	Parameters.EyeAdaptation = *Inputs.EyeAdaptationParameters;
	Parameters.BloomThreshold = Inputs.Threshold;
	return Parameters;
}

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/PostProcess/PostProcessEyeAdaptation.cpp:840

Scope (from outer to inner):

file
function     FRDGBufferRef AddHistogramEyeAdaptationPass

Source code excerpt:

	FEyeAdaptationCS::FParameters* PassParameters = GraphBuilder.AllocParameters<FEyeAdaptationCS::FParameters>();
	PassParameters->EyeAdaptation = EyeAdaptationParameters;
	PassParameters->LocalExposure = LocalExposureParameters;
	PassParameters->HistogramTexture = HistogramTexture;
	PassParameters->RWEyeAdaptationBuffer = GraphBuilder.CreateUAV(OutputBuffer);

	FEyeAdaptationCS::FPermutationDomain PermutationVector;
	PermutationVector.Set<FEyeAdaptationCS::FComputeAverageLocalExposure>(bComputeAverageLocalExposure);

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/PostProcess/PostProcessEyeAdaptation.cpp:979

Scope (from outer to inner):

file
function     FRDGBufferRef AddBasicEyeAdaptationPass

Source code excerpt:

	PassParameters->View = View.ViewUniformBuffer;
	PassParameters->EyeAdaptation = EyeAdaptationParameters;
	PassParameters->LocalExposure = LocalExposureParameters;
	PassParameters->Color = GetScreenPassTextureViewportParameters(SceneColorViewport);
	PassParameters->ColorTexture = SceneColor.TextureSRV;
	PassParameters->EyeAdaptationBuffer = GraphBuilder.CreateSRV(EyeAdaptationBuffer);
	PassParameters->RWEyeAdaptationBuffer = GraphBuilder.CreateUAV(OutputBuffer);

	FBasicEyeAdaptationCS::FPermutationDomain PermutationVector;

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/PostProcess/PostProcessEyeAdaptation.cpp:1239

Scope (from outer to inner):

file
function     void FViewInfo::UpdatePreExposure

Source code excerpt:


		// How much the local exposure may change the overall image exposure when configured wrongly.
		const float LocalExposure = GetLastAverageLocalExposure();

		// The global exposure of the scene regardless of the method used.
		float GlobalExposure = 1.0;
		if (ExposureMethod == AEM_Manual)
		{
			// Bypasses round trip CPU -> GPU -> CPU and instead directly use current frame's manual exposure.

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/PostProcess/PostProcessEyeAdaptation.cpp:1258

Scope (from outer to inner):

file
function     void FViewInfo::UpdatePreExposure

Source code excerpt:


		// This computation must match FinalLinearColor in PostProcessTonemap.usf.
		const float FinalPreExposure = SceneColorTint * GlobalExposure * VignetteMask * LocalExposure;
		ensure(FinalPreExposure > 0.0f);

		// Apply the computed PreExposure to view and view state.
		PreExposure = FinalPreExposure;
		bUpdateLastExposure = ViewState != nullptr; // TODO: technically not needed when ExposureMethod == AEM_Manual, unless there is transition from AEM_Manual to auto.
	}

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/PostProcess/PostProcessHistogram.cpp:507

Scope (from outer to inner):

file
function     FRDGTextureRef AddLocalExposurePass

Source code excerpt:

			TexCreate_UAV | TexCreate_ShaderResource);

		LocalExposureTexture = GraphBuilder.CreateTexture(TextureDesc, TEXT("LocalExposure"));

		auto* PassParameters = GraphBuilder.AllocParameters<FHistogramCS::FParameters>();
		PassParameters->View = View.ViewUniformBuffer;
		PassParameters->EyeAdaptation = EyeAdaptationParameters;
		PassParameters->Input = GetScreenPassTextureViewportParameters(FScreenPassTextureViewport(SceneColor));
		PassParameters->InputSampler = TStaticSamplerState<SF_Point, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/PostProcess/PostProcessLocalExposure.cpp:18

Scope (from outer to inner):

file
namespace    anonymous
class        class FSetupLogLuminanceCS : public FGlobalShader

Source code excerpt:

{
public:
	// Changing these numbers requires LocalExposure.usf to be recompiled
	static const uint32 ThreadGroupSizeX = 8;
	static const uint32 ThreadGroupSizeY = 8;

	DECLARE_GLOBAL_SHADER(FSetupLogLuminanceCS);
	SHADER_USE_PARAMETER_STRUCT(FSetupLogLuminanceCS, FGlobalShader);

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/PostProcess/PostProcessLocalExposure.cpp:51

Scope (from outer to inner):

file
namespace    anonymous
class        class FApplyLocalExposureCS : public FGlobalShader

Source code excerpt:

{
public:
	// Changing these numbers requires LocalExposure.usf to be recompiled
	static const uint32 ThreadGroupSizeX = 8;
	static const uint32 ThreadGroupSizeY = 8;

	DECLARE_GLOBAL_SHADER(FApplyLocalExposureCS);
	SHADER_USE_PARAMETER_STRUCT(FApplyLocalExposureCS, FGlobalShader);

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/PostProcess/PostProcessLocalExposure.cpp:238

Scope (from outer to inner):

file
function     void AddApplyLocalExposurePass

Source code excerpt:

	PassParameters->EyeAdaptationBuffer = GraphBuilder.CreateSRV(EyeAdaptationBuffer);

	PassParameters->LocalExposure = LocalExposureParamaters;
	PassParameters->LumBilateralGrid = LocalExposureTexture;
	PassParameters->BlurredLogLum = BlurredLogLuminanceTexture;

	PassParameters->TextureSampler = TStaticSamplerState<SF_Bilinear, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();;

	FComputeShaderUtils::AddPass(

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/PostProcess/PostProcessTonemap.cpp:313

Scope: file

Source code excerpt:

	SHADER_PARAMETER_STRUCT(FScreenPassTextureViewportParameters, Output)
	SHADER_PARAMETER_STRUCT(FEyeAdaptationParameters, EyeAdaptation)
	SHADER_PARAMETER_STRUCT(FLocalExposureParameters, LocalExposure)
	SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D, ColorTexture)

	// Parameters to apply to the scene color.
	SHADER_PARAMETER_RDG_BUFFER_SRV(StructuredBuffer<float4>, SceneColorApplyParamaters)

	// Bloom texture

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/PostProcess/PostProcessTonemap.cpp:804

Scope (from outer to inner):

file
function     FScreenPassTexture AddTonemapPass

Source code excerpt:

	{
		checkf(Inputs.LocalExposureParameters != nullptr, TEXT("When Local Exposure is enabled, corresponding parameters must be provided"));
		CommonParameters.LocalExposure = *Inputs.LocalExposureParameters;
	}

	CommonParameters.OutputDevice = GetTonemapperOutputDeviceParameters(ViewFamily);
	CommonParameters.Color = GetScreenPassTextureViewportParameters(SceneColorViewport);
	CommonParameters.Output = GetScreenPassTextureViewportParameters(OutputViewport);
	CommonParameters.ColorTexture = Inputs.SceneColor.TextureSRV;

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/PostProcess/PostProcessVisualizeLocalExposure.cpp:77

Scope (from outer to inner):

file
function     FScreenPassTexture AddVisualizeLocalExposurePass

Source code excerpt:

	PassParameters->View = View.ViewUniformBuffer;
	PassParameters->EyeAdaptation = *Inputs.EyeAdaptationParameters;
	PassParameters->LocalExposure = *Inputs.LocalExposureParameters;
	PassParameters->Input = GetScreenPassTextureViewportParameters(InputViewport);
	PassParameters->Output = GetScreenPassTextureViewportParameters(OutputViewport);
	PassParameters->HDRSceneColorTexture = Inputs.HDRSceneColor.Texture;
	PassParameters->EyeAdaptationBuffer = GraphBuilder.CreateSRV(Inputs.EyeAdaptationBuffer);
	PassParameters->LumBilateralGrid = Inputs.LumBilateralGridTexture;
	PassParameters->BlurredLogLum = Inputs.BlurredLumTexture;