ShowFlag.Tonemapper

ShowFlag.Tonemapper

#Overview

name: ShowFlag.Tonemapper

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

It is referenced in 12 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of ShowFlag.Tonemapper is to control whether HDR to LDR conversion is done through a tone mapper or if linear mapping is used instead. This setting is part of the post-processing system in Unreal Engine 5.

The Unreal Engine subsystems that rely on this setting variable are primarily the rendering system and post-processing modules. It’s particularly relevant for HDR rendering, color grading, and final image output.

The value of this variable is typically set in the engine show flags, which can be controlled through the engine’s rendering settings or programmatically. It’s often accessed through View.Family->EngineShowFlags.Tonemapper.

This variable interacts closely with other post-processing and rendering settings, particularly those related to HDR rendering, color grading, and gamma correction. For example, it’s often used in conjunction with PostProcessing show flag to determine the final rendering pipeline.

Developers must be aware that disabling the tonemapper can significantly change the appearance of the final rendered image, especially in HDR scenarios. When the tonemapper is disabled, the engine often applies a simple gamma correction instead.

Best practices when using this variable include:

  1. Ensure it’s enabled when working with HDR content to get proper color representation.
  2. Be cautious when disabling it, as it may require adjusting other post-processing settings to maintain desired visual quality.
  3. Consider the impact on performance, as tonemapping can have a computational cost.

The associated variable Tonemapper is used in similar contexts and often refers to the same setting. It’s used in various parts of the engine, including compositing elements and color conversion processes. When working with Tonemapper, developers should consider its interaction with color grading settings, film stock settings, and chromatic aberration effects. It’s particularly important in scenarios involving custom post-processing or compositing workflows.

#References in C++ code

#Callsites

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

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

Scope: file

Source code excerpt:

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)"))
/** e.g. Ambient cube map, for now SHOWFLAG_ALWAYS_ACCESSIBLE because it's exposed in SceneCapture */
SHOWFLAG_ALWAYS_ACCESSIBLE(AmbientCubemap, SFG_LightingFeatures, NSLOCTEXT("UnrealEd", "AmbientCubemapSF", "Ambient Cubemap"))

#Associated Variable and Callsites

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

#Loc: <Workspace>/Engine/Plugins/Compositing/Composure/Source/Composure/Private/CompositingElements/PlayerViewportCompositingOutput.cpp:283

Scope (from outer to inner):

file
function     bool UPlayerCompOutputCameraModifier::ModifyCamera

Source code excerpt:

		if (Owner->UseBuiltInColorConversion())
		{
			UCompositingTonemapPass* Tonemapper = CastChecked<UCompositingTonemapPass>(Owner->ColorConverter);

			FComposureTonemapperUtils::ApplyTonemapperSettings(
				Tonemapper->ColorGradingSettings,
				Tonemapper->FilmStockSettings,
				Tonemapper->ChromaticAberration,
				InOutPOV.PostProcessSettings
			);
		}

		if (!Owner->ApplyToneCurve)
		{

#Loc: <Workspace>/Engine/Plugins/Compositing/OpenColorIO/Source/OpenColorIO/Private/OpenColorIORendering.cpp:108

Scope (from outer to inner):

file
function     void FOpenColorIORendering::AddPass_RenderThread

Source code excerpt:

	// There is a special case where post processing and tonemapper are disabled. In this case tonemapper applies a static display Inverse of Gamma which defaults to 2.2.
	// In the case when Both PostProcessing and ToneMapper are disabled we apply gamma manually. In every other case we apply inverse gamma before applying OCIO.
	float DisplayGamma = (View.Family->EngineShowFlags.Tonemapper == 0) || (View.Family->EngineShowFlags.PostProcessing == 0) ? DefaultDisplayGamma : DefaultDisplayGamma / EngineDisplayGamma;

	FOpenColorIORendering::AddPass_RenderThread(
		GraphBuilder,
		View,
		View.GetFeatureLevel(),
		Input,

#Loc: <Workspace>/Engine/Plugins/Runtime/nDisplay/Source/DisplayCluster/Private/Render/DisplayDevice/Proxy/DisplayClusterDisplayDeviceProxy_OpenColorIO.cpp:18

Scope (from outer to inner):

file
namespace    UE::DisplayCluster
function     static inline float GetDisplayGamma

Source code excerpt:

		// There is a special case where post processing and tonemapper are disabled. In this case tonemapper applies a static display Inverse of Gamma which defaults to 2.2.
		// In the case when Both PostProcessing and ToneMapper are disabled we apply gamma manually. In every other case we apply inverse gamma before applying OCIO.
		const float DisplayGamma = (InViewportContext.RenderThreadData.EngineShowFlags.Tonemapper == 0) || (InViewportContext.RenderThreadData.EngineShowFlags.PostProcessing == 0) ? DefaultDisplayGamma : DefaultDisplayGamma / EngineDisplayGamma;

		return DisplayGamma;
	}
};

FDisplayClusterDisplayDeviceProxy_OpenColorIO::FDisplayClusterDisplayDeviceProxy_OpenColorIO(FOpenColorIOColorConversionSettings& InColorConversionSettings)

#Loc: <Workspace>/Engine/Plugins/Runtime/nDisplay/Source/DisplayCluster/Private/Render/Viewport/DisplayClusterViewport_OpenColorIO.cpp:56

Scope (from outer to inner):

file
function     float FDisplayClusterViewport_OpenColorIO::GetDisplayGamma

Source code excerpt:

	// There is a special case where post processing and tonemapper are disabled. In this case tonemapper applies a static display Inverse of Gamma which defaults to 2.2.
	// In the case when Both PostProcessing and ToneMapper are disabled we apply gamma manually. In every other case we apply inverse gamma before applying OCIO.
	const float DisplayGamma = (InViewportContext.RenderThreadData.EngineShowFlags.Tonemapper == 0) || (InViewportContext.RenderThreadData.EngineShowFlags.PostProcessing == 0) ? DefaultDisplayGamma : DefaultDisplayGamma / EngineDisplayGamma;

	return DisplayGamma;
}

bool FDisplayClusterViewport_OpenColorIO::AddPass_RenderThread(FRDGBuilder& GraphBuilder, const FDisplayClusterViewport_Context& InViewportContext,
	FRHITexture2D* InputTextureRHI, const FIntRect& InputRect, FRHITexture2D* OutputTextureRHI, const FIntRect& OutputRect, bool bUnpremultiply, bool bInvertAlpha) const

#Loc: <Workspace>/Engine/Source/Editor/LevelEditor/Private/SLevelViewport.cpp:3653

Scope (from outer to inner):

file
function     void SLevelViewport::PreviewActors

Source code excerpt:

				if (!bPreviewInDesktopViewport)
				{
					ActorPreviewLevelViewportClient->EngineShowFlags.Tonemapper = false;
				}

				// We don't use view modes for preview viewports
				ActorPreviewLevelViewportClient->SetViewMode(VMI_Unknown);

				// User should never be able to interact with this viewport

#Loc: <Workspace>/Engine/Source/Editor/PixelInspector/Private/PixelInspector.cpp:854

Scope (from outer to inner):

file
namespace    PixelInspector
function     void FPixelInspectorSceneViewExtension::BeginRenderViewFamily

Source code excerpt:

		const float DisplayGamma = InViewFamily.RenderTarget->GetDisplayGamma();
		// We need to apply gamma to the final color if the output is in HDR.
		FinalColorGamma = (InViewFamily.EngineShowFlags.Tonemapper == 0) ? DEFAULT_DISPLAY_GAMMA : DisplayGamma;
	}

	void FPixelInspectorSceneViewExtension::SubscribeToPostProcessingPass(EPostProcessingPass PassId, FAfterPassCallbackDelegateArray& InOutPassCallbacks, bool bIsPassEnabled)
	{
		if (PassId == EPostProcessingPass::FXAA)
		{

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/ShowFlags.cpp:644

Scope (from outer to inner):

file
function     void EngineShowFlagOverride

Source code excerpt:

			 DISABLE_ENGINE_SHOWFLAG(Bloom)
			 DISABLE_ENGINE_SHOWFLAG(ColorGrading)
			 DISABLE_ENGINE_SHOWFLAG(Tonemapper)
			 DISABLE_ENGINE_SHOWFLAG(Refraction)
			 DISABLE_ENGINE_SHOWFLAG(ReflectionEnvironment)
			 DISABLE_ENGINE_SHOWFLAG(AmbientCubemap)
			 DISABLE_ENGINE_SHOWFLAG(MotionBlur)
			 DISABLE_ENGINE_SHOWFLAG(DirectLighting)
			 DISABLE_ENGINE_SHOWFLAG(Lighting)

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

Scope: file

Source code excerpt:

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)"))
/** e.g. Ambient cube map, for now SHOWFLAG_ALWAYS_ACCESSIBLE because it's exposed in SceneCapture */
SHOWFLAG_ALWAYS_ACCESSIBLE(AmbientCubemap, SFG_LightingFeatures, NSLOCTEXT("UnrealEd", "AmbientCubemapSF", "Ambient Cubemap"))

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

Scope (from outer to inner):

file
namespace    anonymous
namespace    TonemapperPermutation
function     FCommonDomain BuildCommonPermutationDomain

Source code excerpt:

	// Gamma
	if (bGammaOnly ||
		(Family->EngineShowFlags.Tonemapper == 0) ||
		(Family->EngineShowFlags.PostProcessing == 0))
	{
		PermutationVector.Set<FTonemapperGammaOnlyDim>(true);
		return PermutationVector;
	}

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/RayTracing/RayTracingDebug.cpp:1506

Scope (from outer to inner):

file
function     void FDeferredShadingSceneRenderer::RenderRayTracingDebug

Source code excerpt:

	RayGenParameters->VisualizationMode = DebugVisualizationMode;
	RayGenParameters->PickerDomain = CVarRayTracingDebugPickerDomain.GetValueOnRenderThread();
	RayGenParameters->ShouldUsePreExposure = View.Family->EngineShowFlags.Tonemapper;
	RayGenParameters->TimingScale = CVarRayTracingDebugTimingScale.GetValueOnAnyThread() / 25000.0f;
	RayGenParameters->OpaqueOnly = CVarRayTracingDebugModeOpaqueOnly.GetValueOnRenderThread();
	RayGenParameters->TriangleHitCountMaxThreshold = FMath::Clamp((float)CVarRayTracingDebugHitCountMaxThreshold.GetValueOnRenderThread(), 1, 100000);
	RayGenParameters->TriangleHitCountPerInstanceMaxThreshold = FMath::Max(1, CVarRayTracingDebugHitCountPerInstanceMaxThreshold.GetValueOnRenderThread());
	RayGenParameters->RayTracingDebugHitStatsUniformBuffer = DebugHitStatsUniformBuffer;
	RayGenParameters->LightGridPacked = View.RayTracingLightGridUniformBuffer;

#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/RayTracing/RayTracingPrimaryRays.cpp:147

Scope (from outer to inner):

file
function     void FDeferredShadingSceneRenderer::RenderRayTracingPrimaryRaysView

Source code excerpt:

	PassParameters->TranslucencyRefraction = TranslucencyOptions.EnableRefraction >= 0 ? TranslucencyOptions.EnableRefraction : View.FinalPostProcessSettings.RayTracingTranslucencyRefraction;
	PassParameters->MaxNormalBias = GetRaytracingMaxNormalBias();
	PassParameters->ShouldUsePreExposure = View.Family->EngineShowFlags.Tonemapper;
	PassParameters->PrimaryRayFlags = (uint32)Flags;
	PassParameters->TLAS = View.GetRayTracingSceneLayerViewChecked(ERayTracingSceneLayer::Base);
	PassParameters->ViewUniformBuffer = View.ViewUniformBuffer;

	PassParameters->LightGridPacked = View.RayTracingLightGridUniformBuffer;