r.EyeAdaptation.PreExposureOverride
r.EyeAdaptation.PreExposureOverride
#Overview
name: r.EyeAdaptation.PreExposureOverride
This variable is created as a Console Variable (cvar).
- type:
Var
- help:
Overide the scene pre-exposure by a custom value. \n= 0 : No override\n> 0 : Override PreExposure\n
It is referenced in 4
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of r.EyeAdaptation.PreExposureOverride is to override the scene pre-exposure with a custom value in Unreal Engine’s rendering system. This setting is part of the eye adaptation and exposure control mechanism, which is crucial for managing the overall brightness and contrast of the rendered scene.
This setting variable is primarily used in the Renderer module, specifically within the post-processing system for eye adaptation. It’s referenced in files related to post-processing (PostProcessEyeAdaptation.cpp) and temporal upscaling visualization (VisualizeTemporalUpscaler.cpp).
The value of this variable is set through the console variable system. It’s defined as a TAutoConsoleVariable with a default value of 0, which means no override by default.
The associated variable CVarEyeAdaptationPreExposureOverride interacts directly with r.EyeAdaptation.PreExposureOverride. They share the same value and are used interchangeably in the code.
Developers must be aware that:
- A value of 0 means no override is applied.
- Any value greater than 0 will override the PreExposure value.
- This setting affects the rendering thread, so changes may not be immediately visible.
Best practices when using this variable include:
- Use it sparingly and mainly for debugging or specific artistic needs.
- Be cautious when overriding the pre-exposure, as it can significantly affect the overall look of the scene.
- Remember to reset it to 0 when the override is no longer needed to ensure normal automatic exposure behavior.
Regarding the associated variable CVarEyeAdaptationPreExposureOverride:
- It’s the actual console variable that controls the pre-exposure override.
- It’s used in the UpdatePreExposure() function of the FViewInfo class to determine whether to apply a custom pre-exposure value.
- The value is retrieved using GetValueOnRenderThread(), ensuring thread-safe access.
- When using this variable, developers should consider the impact on different platforms, as the code checks for mobile platforms and different auto-exposure methods.
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/PostProcess/PostProcessEyeAdaptation.cpp:24
Scope (from outer to inner):
file
namespace anonymous
Source code excerpt:
{
TAutoConsoleVariable<float> CVarEyeAdaptationPreExposureOverride(
TEXT("r.EyeAdaptation.PreExposureOverride"),
0,
TEXT("Overide the scene pre-exposure by a custom value. \n")
TEXT("= 0 : No override\n")
TEXT("> 0 : Override PreExposure\n"),
ECVF_RenderThreadSafe);
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/PostProcess/VisualizeTemporalUpscaler.cpp:265
Scope (from outer to inner):
file
function FScreenPassTexture AddVisualizeTemporalUpscalerPass
lambda-function
Source code excerpt:
// Display the pre-exposure being used
{
static auto CVarPreExposureOverride = IConsoleManager::Get().FindConsoleVariable(TEXT("r.EyeAdaptation.PreExposureOverride"));
check(CVarPreExposureOverride);
FString Text = FString::Printf(TEXT("PreExposure: %f"), View.PreExposure);
if (CVarPreExposureOverride->GetFloat() > 0.0f)
{
Text += TEXT(" (r.EyeAdaptation.PreExposureOverride)");
}
QuickDrawSummary(/* Location = */ 3, Text);
}
// Display alpha support
{
FString Text = bSupportsAlpha ? TEXT("r.PostProcessing.PropagateAlpha=true") : TEXT("r.PostProcessing.PropagateAlpha=false");
if (Inputs.TAAConfig == EMainTAAPassConfig::ThirdParty)
{
Text = TEXT("Unknown");
}
QuickDrawSummary(/* Location = */ 4, TEXT("Support Alpha: ") + Text);
}
// Display memory size of the history.
{
static auto CVarAntiAliasingQuality = IConsoleManager::Get().FindConsoleVariable(TEXT("sg.AntiAliasingQuality"));
check(CVarAntiAliasingQuality);
const uint64 PingPongHistorySizeMultiplier = 2;
uint64 HistorySize = 0;
if (Inputs.TAAConfig == EMainTAAPassConfig::TAA)
{
HistorySize = View.PrevViewInfo.TemporalAAHistory.GetGPUSizeBytes(/* bLogSizes = */ false) * PingPongHistorySizeMultiplier;
}
else if (Inputs.TAAConfig == EMainTAAPassConfig::TSR && View.PrevViewInfo.TSRHistory.IsValid())
{
HistorySize = View.PrevViewInfo.TSRHistory.GetGPUSizeBytes(/* bLogSizes = */ false);
bool bHasTSRHistoryResurrection = View.PrevViewInfo.TSRHistory.MetadataArray->GetDesc().ArraySize > 1;
bool bHasTSRPingPongHistory = !bHasTSRHistoryResurrection;
if (bHasTSRPingPongHistory)
{
HistorySize *= PingPongHistorySizeMultiplier;
}
}
else if (Inputs.TAAConfig == EMainTAAPassConfig::ThirdParty && View.PrevViewInfo.ThirdPartyTemporalUpscalerHistory.IsValid())
{
HistorySize = View.PrevViewInfo.ThirdPartyTemporalUpscalerHistory->GetGPUSizeBytes();
}
QuickDrawSummary(/* Location = */ 5, FString::Printf(TEXT("History VRAM footprint: %.1f MB"), float(HistorySize) / float(1024 * 1024)));
}
// Display if any additional sharpening is happening
{
static auto CVarSharpen = IConsoleManager::Get().FindConsoleVariable(TEXT("r.Tonemapper.Sharpen"));
check(CVarSharpen);
float Sharpen = CVarSharpen->GetFloat();
Sharpen = (Sharpen < 0) ? View.FinalPostProcessSettings.Sharpen : Sharpen;
QuickDrawSummary(/* Location = */ 6, Sharpen > 0 ? FString::Printf(TEXT("Tonemapper Sharpen: %f"), Sharpen) : TEXT("Tonemapper Sharpen: Off"));
}
});
}
else
{
check(Inputs.TAAConfig == EMainTAAPassConfig::Disabled);
AddDrawCanvasPass(GraphBuilder, RDG_EVENT_NAME("VisualizeTemporalUpscaler Text"), View, FScreenPassRenderTarget(Output, ERenderTargetLoadAction::ELoad),
[&ViewRect = Output.ViewRect](FCanvas& Canvas)
{
const float DPIScale = Canvas.GetDPIScale();
Canvas.SetBaseTransform(FMatrix(FScaleMatrix(DPIScale) * Canvas.CalcBaseTransform2D(Canvas.GetViewRect().Width(), Canvas.GetViewRect().Height())));
FIntPoint LabelLocation(60, 60);
Canvas.DrawShadowedString(LabelLocation.X / DPIScale, LabelLocation.Y / DPIScale, TEXT("No temporal upscaler used"), GetStatsFont(), FLinearColor::Red);
});
}
return MoveTemp(Output);
}
#Associated Variable and Callsites
This variable is associated with another variable named CVarEyeAdaptationPreExposureOverride
. They share the same value. See the following C++ source code.
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/PostProcess/PostProcessEyeAdaptation.cpp:23
Scope (from outer to inner):
file
namespace anonymous
Source code excerpt:
namespace
{
TAutoConsoleVariable<float> CVarEyeAdaptationPreExposureOverride(
TEXT("r.EyeAdaptation.PreExposureOverride"),
0,
TEXT("Overide the scene pre-exposure by a custom value. \n")
TEXT("= 0 : No override\n")
TEXT("> 0 : Override PreExposure\n"),
ECVF_RenderThreadSafe);
#Loc: <Workspace>/Engine/Source/Runtime/Renderer/Private/PostProcess/PostProcessEyeAdaptation.cpp:1179
Scope (from outer to inner):
file
function void FViewInfo::UpdatePreExposure
Source code excerpt:
const bool bMobilePlatform = IsMobilePlatform(GetShaderPlatform());
const bool bEnableAutoExposure = !bMobilePlatform || IsMobileEyeAdaptationEnabled(*this);
const float PreExposureOverride = CVarEyeAdaptationPreExposureOverride.GetValueOnRenderThread();
const EAutoExposureMethod ExposureMethod = GetAutoExposureMethod(*this);
const float FixedExposure = GetEyeAdaptationFixedExposure(*this);
/** Whether PreExposure is supported at all for a output code path.
* Mobile LDR renders directly into low bitdepth back buffer. So there the final exposure is directly applied in
* BasePassPixelShader.usf, and ruse the View.PreExposure code path for code maintenance reason.