r.ScreenPercentage
r.ScreenPercentage
#Overview
name: r.ScreenPercentage
This variable is created as a Console Variable (cvar).
- type:
Var
- help:
To render in lower resolution and upscale for better performance (combined up with the blenable post process setting).\n70 is a good value for low aliasing and performance, can be verified with \'show TestImage\'\nin percent, >0 and <=100, larger numbers are possible (supersampling) but the downsampling quality is improvable.<=0 compute the screen percentage is determined by r.ScreenPercentage.Default cvars.
It is referenced in 26
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of r.ScreenPercentage is to control the rendering resolution relative to the display resolution, allowing for performance optimization or supersampling in Unreal Engine’s rendering system.
This setting variable is primarily used in the rendering system, particularly for managing screen resolution and performance. It is relied upon by several Unreal Engine subsystems and modules, including:
- The core Engine module
- The DisplayCluster plugin
- The ConsoleVariablesEditor plugin
- The UnrealEd module (for editor viewport rendering)
- The FunctionalTesting module
The value of r.ScreenPercentage is typically set through the console variable system. It can be set manually, through scalability settings, or dynamically adjusted by the engine based on performance requirements.
Several other variables interact with r.ScreenPercentage:
- CVarScreenPercentage: This is the associated console variable that directly represents r.ScreenPercentage.
- r.DynamicRes.TestScreenPercentage: Used for testing dynamic resolution.
- r.SecondaryScreenPercentage.GameViewport: Controls secondary screen percentage for the game viewport.
Developers should be aware of the following when using this variable:
- Values are in percentages, with 100 being the native resolution.
- Values below 100 render at lower resolution and upscale, improving performance.
- Values above 100 enable supersampling but may impact performance.
- Setting the value to 0 or below uses the default screen percentage determined by other CVars.
- It interacts with dynamic resolution systems and can be overridden by them.
Best practices for using r.ScreenPercentage include:
- Use it as part of a broader performance optimization strategy.
- Test thoroughly to find the right balance between performance and visual quality.
- Consider using dynamic resolution systems for more adaptive performance management.
- Be aware of its interaction with other rendering settings and resolution-related variables.
Regarding the associated variable CVarScreenPercentage:
The purpose of CVarScreenPercentage is to provide a console variable interface for r.ScreenPercentage. It allows for runtime modification and querying of the screen percentage value.
CVarScreenPercentage is used in the same subsystems as r.ScreenPercentage, primarily in the rendering and scalability systems.
Its value is set through the console variable system, either programmatically or via console commands.
CVarScreenPercentage directly interacts with r.ScreenPercentage, essentially serving as its console variable representation.
Developers should be aware that changes to CVarScreenPercentage will affect r.ScreenPercentage and vice versa. It’s subject to the same considerations and best practices as r.ScreenPercentage.
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/LegacyScreenPercentageDriver.cpp:33
Scope: file
Source code excerpt:
static TAutoConsoleVariable<float> CVarScreenPercentage(
TEXT("r.ScreenPercentage"), 0.0f,
TEXT("To render in lower resolution and upscale for better performance (combined up with the blenable post process setting).\n")
TEXT("70 is a good value for low aliasing and performance, can be verified with 'show TestImage'\n")
TEXT("in percent, >0 and <=100, larger numbers are possible (supersampling) but the downsampling quality is improvable.")
TEXT("<=0 compute the screen percentage is determined by r.ScreenPercentage.Default cvars."),
ECVF_Scalability | ECVF_Default);
#Loc: <Workspace>/Engine/Plugins/Editor/ConsoleVariablesEditor/Source/ConsoleVariablesEditor/Private/Views/MainPanel/ConsoleVariablesEditorMainPanel.cpp:116
Scope (from outer to inner):
file
function FReply FConsoleVariablesEditorMainPanel::ValidateConsoleInputAndAddToCurrentPreset
Source code excerpt:
}
FString CommandKey; // The actual variable name, like r.ScreenPercentage
FString ValueString; // The variable value, usually after the CommandKey and a single space
FString AdditionalParams; // Some variables have multiple parameters between the CommandKey and ValueString
if (CommandString.Contains(" "))
{
// We want to treat the last string after the last space as the value
#Loc: <Workspace>/Engine/Plugins/Editor/ConsoleVariablesEditor/Source/ConsoleVariablesEditor/Public/ConsoleVariablesEditorCommandInfo.h:19
Scope (from outer to inner):
file
function struct CONSOLEVARIABLESEDITOR_API FConsoleVariablesEditorCommandInfo { enum class EConsoleObjectType { // A console command that has no associated console object but is parsed externally, e.g. 'st
Source code excerpt:
// A console command with an associated console object, like 'r.SetNearClipPlane'
Command,
// A console variable such as 'r.ScreenPercentage'
Variable
};
struct FStaticConsoleVariableFlagInfo
{
EConsoleVariableFlags Flag;
#Loc: <Workspace>/Engine/Plugins/Editor/DisplayClusterLaunch/Source/DisplayClusterLaunchEditor/Public/DisplayClusterLaunchEditorProjectSettings.h:114
Scope (from outer to inner):
file
function class DISPLAYCLUSTERLAUNCHEDITOR_API UDisplayClusterLaunchEditorProjectSettings : public UObject { GENERATED_BODY
Source code excerpt:
* You can specify additional console variables here to be executed after those of the Console Variable Preset are executed.
* This is useful for overriding variables in your defined Console Variables Asset.
* Console Variables generally have a name and a value, like "r.ScreenPercentage 50"
*/
UPROPERTY(Config, EditAnywhere, Category="nDisplay Launch Settings|Console", meta = (Keywords = "DPCvars"))
TSet<FString> AdditionalConsoleVariables;
/**
* You can specify additional console commands here to be executed after those of the Console Variable Preset are executed.
* This is useful for overriding commands in your defined Console Variables Asset.
* Console Commands generally have a name and no value (i.e. 'stat unit') though some have a value too (i.e. "r.SetNearClipPlane 500")
*/
UPROPERTY(Config, EditAnywhere, Category="nDisplay Launch Settings|Console")
TSet<FString> AdditionalConsoleCommands;
#Loc: <Workspace>/Engine/Plugins/Runtime/nDisplay/Source/DisplayCluster/Private/Game/EngineClasses/Basics/DisplayClusterViewportClient.cpp:800
Scope (from outer to inner):
file
function void UDisplayClusterViewportClient::Draw
Source code excerpt:
if (ViewFamily.EngineShowFlags.ScreenPercentage)
{
// Get global view fraction set by r.ScreenPercentage.
GlobalResolutionFraction = CustomBufferRatio;
// We need to split the screen percentage if below 0.5 because TAA upscaling only works well up to 2x.
if (GlobalResolutionFraction < 0.5f)
{
SecondaryScreenPercentage = 2.0f * GlobalResolutionFraction;
#Loc: <Workspace>/Engine/Plugins/Runtime/nDisplay/Source/DisplayCluster/Private/Render/Viewport/DisplayClusterViewport.cpp:704
Scope (from outer to inner):
file
function bool FDisplayClusterViewport::UpdateFrameContexts
Source code excerpt:
Context.ContextSize = ContextSize;
// r.ScreenPercentage
switch (RenderSettings.CaptureMode)
{
case EDisplayClusterViewportCaptureMode::Chromakey:
case EDisplayClusterViewportCaptureMode::Lightcard:
// we should not change the size of the Chromakey\Lighcards due to the way copy\resolve works for RT's
// if the viewfamily resolves to RenderTarget it will remove alpha channel
#Loc: <Workspace>/Engine/Plugins/Runtime/nDisplay/Source/DisplayClusterLightCardEditor/Private/Viewport/DisplayClusterLightCardEditorViewportClient.cpp:306
Scope (from outer to inner):
file
function void FDisplayClusterLightCardEditorViewportClient::Draw
Source code excerpt:
}
// In editor viewport, we ignore r.ScreenPercentage and FPostProcessSettings::ScreenPercentage by design.
ViewFamily.SetScreenPercentageInterface(new FLegacyScreenPercentageDriver(ViewFamily, GlobalResolutionFraction));
}
check(ViewFamily.GetScreenPercentageInterface() != nullptr);
}
#Loc: <Workspace>/Engine/Plugins/VirtualProduction/ICVFXTesting/Source/ICVFXTesting/Public/ICVFXTestControllerBase.h:74
Scope (from outer to inner):
file
class class UICVFXTestControllerBase : public UGauntletTestController
Source code excerpt:
TEXT("ICVFXTest"),
TEXT("r.nanite"),
TEXT("r.ScreenPercentage"),
TEXT("r.RayTracing"),
TEXT("r.DynamicGlobalIlluminationMethod"),
TEXT("r.ReflectionMethod"),
TEXT("r.Lumen"),
TEXT("FX.AllowGPUParticles"),
TEXT("r.Shadow.Virtual.Enable")};
#Loc: <Workspace>/Engine/Source/Developer/FunctionalTesting/Private/AutomationBlueprintFunctionLibrary.cpp:248
Scope (from outer to inner):
file
function FAutomationTestScreenshotEnvSetup::FAutomationTestScreenshotEnvSetup
Source code excerpt:
, TonemapperGamma(TEXT("r.TonemapperGamma"))
, TonemapperSharpen(TEXT("r.Tonemapper.Sharpen"))
, ScreenPercentage(TEXT("r.ScreenPercentage"))
, DynamicResTestScreenPercentage(TEXT("r.DynamicRes.TestScreenPercentage"))
, DynamicResOperationMode(TEXT("r.DynamicRes.OperationMode"))
, SecondaryScreenPercentage(TEXT("r.SecondaryScreenPercentage.GameViewport"))
{
}
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Classes/Editor/EditorPerformanceSettings.h:17
Scope: file
Source code excerpt:
ProjectDefault,
// Directly controls the screen percentage with the r.ScreenPercentage cvar
Manual UMETA(DisplayName = "Manual"),
// Automatic control the screen percentage based on the display resolution, r.ScreenPercentage.Auto.*
BasedOnDisplayResolution UMETA(DisplayName = "Based on display resolution"),
// Based on DPI scale.
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/EditorViewportClient.cpp:4274
Scope (from outer to inner):
file
function void FEditorViewportClient::Draw
Source code excerpt:
}
// In editor viewport, we ignore r.ScreenPercentage and FPostProcessSettings::ScreenPercentage by design.
ViewFamily.SetScreenPercentageInterface(new FLegacyScreenPercentageDriver(
ViewFamily, GlobalResolutionFraction));
}
check(ViewFamily.GetScreenPercentageInterface() != nullptr);
}
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/SScalabilitySettings.cpp:123
Scope (from outer to inner):
file
function bool SScalabilitySettings::IsResolutionScaleEditable
Source code excerpt:
}
static IConsoleVariable* CVarScreenPercentage = IConsoleManager::Get().FindConsoleVariable(TEXT("r.ScreenPercentage"));
if ((uint32(CVarScreenPercentage->GetFlags()) & uint32(ECVF_SetByMask)) > uint32(ECVF_SetByScalability))
{
return false;
}
return true;
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/SScalabilitySettings.cpp:272
Scope (from outer to inner):
file
function FFormatNamedArguments SScalabilitySettings::GetScreenPercentageFormatArguments
Source code excerpt:
FormatArguments.Add(TEXT("ViewportMode"), UEnum::GetDisplayValueAsText(ViewportRenderingMode));
static IConsoleVariable* CVarScreenPercentage = IConsoleManager::Get().FindConsoleVariable(TEXT("r.ScreenPercentage"));
const TCHAR* CVarScreenPercentageSetBy = GetConsoleVariableSetByName(CVarScreenPercentage->GetFlags());
float CVarScreenPercentageValue = CVarScreenPercentage->GetFloat();
if (EConsoleVariableFlags(uint32(CVarScreenPercentage->GetFlags()) & uint32(ECVF_SetByMask)) > ECVF_SetByScalability)
{
if (CVarScreenPercentageValue > 0.0f)
{
FormatArguments.Add(TEXT("SettingSource"), FText::Format(
LOCTEXT("ScreenPercentageCVarSetBy", "r.ScreenPercentage={0} set by {1}"),
FText::AsNumber(CVarScreenPercentageValue),
FText::FromString(CVarScreenPercentageSetBy)));
}
else
{
FormatArguments.Add(TEXT("SettingSource"), FText::Format(
LOCTEXT("ScreenPercentageCVarSetByUsesProjectDefaults", "Project Settings' default due to r.ScreenPercentage={0} set by {1}"),
FText::AsNumber(CVarScreenPercentageValue),
FText::FromString(CVarScreenPercentageSetBy)));
}
}
else
{
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/LegacyScreenPercentageDriver.cpp:71
Scope (from outer to inner):
file
function void OnScreenPercentageChange
Source code excerpt:
}
// Check whether dynamic resolution is overriding r.ScreenPercentage.
{
FDynamicResolutionStateInfos DynResInfo;
GEngine->GetDynamicResolutionCurrentStateInfos(/* out */ DynResInfo);
if (DynResInfo.Status == EDynamicResolutionStatus::Enabled)
{
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/LegacyScreenPercentageDriver.cpp:175
Scope (from outer to inner):
file
function float FLegacyScreenPercentageDriver::GetCVarResolutionFraction
Source code excerpt:
{
check(IsInGameThread());
static const auto ScreenPercentageCVar = IConsoleManager::Get().FindTConsoleVariableDataFloat(TEXT("r.ScreenPercentage"));
float GlobalFraction = GetResolutionFraction(CVarScreenPercentage.GetValueOnGameThread());
if (GlobalFraction <= GetResolutionFraction(Scalability::MinResolutionScale))
{
GlobalFraction = 1.0f;
}
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Scalability.cpp:456
Scope (from outer to inner):
file
namespace Scalability
function float GetResolutionScreenPercentage
Source code excerpt:
float GetResolutionScreenPercentage()
{
static IConsoleVariable* CVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.ScreenPercentage"));
return FMath::Clamp(CVar->GetFloat(), MinResolutionScale, MaxResolutionScale);
}
FText GetScalabilityNameFromQualityLevel(int32 QualityLevel)
{
#define LOCTEXT_NAMESPACE "EngineScalabiltySettings"
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Scalability.cpp:502
Scope (from outer to inner):
file
namespace Scalability
function static void SetResolutionQualityLevel
Source code excerpt:
// UE_LOG(LogConsoleResponse, Display, TEXT(" ResolutionQuality %.2f"), "", InResolutionQualityLevel);
static IConsoleVariable* CVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.ScreenPercentage"));
// if it wasn't created yet we either need to change the order or store like we do for ini loading
check(CVar);
CVar->Set(InResolutionQualityLevel, ECVF_SetByScalability);
}
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Public/LegacyScreenPercentageDriver.h:21
Scope (from outer to inner):
file
class class FLegacyScreenPercentageDriver : public ISceneViewFamilyScreenPercentage
Source code excerpt:
float InGlobalResolutionFractionUpperBound);
/** Gets the view rect fraction from the r.ScreenPercentage cvar. */
static ENGINE_API float GetCVarResolutionFraction();
private:
// View family to take care of.
const FSceneViewFamily& ViewFamily;
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Public/LegacyScreenPercentageDriver.h:90
Scope: file
Source code excerpt:
EScreenPercentageMode Mode = EScreenPercentageMode::Manual;
// r.ScreenPercentage when Mode = EMode::Manual.
float GlobalResolutionFraction = 1.0f;
// r.ScreenPercentage.{Min,Max}Resolution
float MinRenderingResolution = 0.0f;
float MaxRenderingResolution = 0.0f;
// r.ScreenPercentage.Auto.* Mode = EMode::BasedOnDisplayResolution.
float AutoPixelCountMultiplier = 1.0f;
#Associated Variable and Callsites
This variable is associated with another variable named CVarScreenPercentage
. They share the same value. See the following C++ source code.
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/SScalabilitySettings.cpp:123
Scope (from outer to inner):
file
function bool SScalabilitySettings::IsResolutionScaleEditable
Source code excerpt:
}
static IConsoleVariable* CVarScreenPercentage = IConsoleManager::Get().FindConsoleVariable(TEXT("r.ScreenPercentage"));
if ((uint32(CVarScreenPercentage->GetFlags()) & uint32(ECVF_SetByMask)) > uint32(ECVF_SetByScalability))
{
return false;
}
return true;
}
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/SScalabilitySettings.cpp:272
Scope (from outer to inner):
file
function FFormatNamedArguments SScalabilitySettings::GetScreenPercentageFormatArguments
Source code excerpt:
FormatArguments.Add(TEXT("ViewportMode"), UEnum::GetDisplayValueAsText(ViewportRenderingMode));
static IConsoleVariable* CVarScreenPercentage = IConsoleManager::Get().FindConsoleVariable(TEXT("r.ScreenPercentage"));
const TCHAR* CVarScreenPercentageSetBy = GetConsoleVariableSetByName(CVarScreenPercentage->GetFlags());
float CVarScreenPercentageValue = CVarScreenPercentage->GetFloat();
if (EConsoleVariableFlags(uint32(CVarScreenPercentage->GetFlags()) & uint32(ECVF_SetByMask)) > ECVF_SetByScalability)
{
if (CVarScreenPercentageValue > 0.0f)
{
FormatArguments.Add(TEXT("SettingSource"), FText::Format(
LOCTEXT("ScreenPercentageCVarSetBy", "r.ScreenPercentage={0} set by {1}"),
FText::AsNumber(CVarScreenPercentageValue),
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/LegacyScreenPercentageDriver.cpp:32
Scope: file
Source code excerpt:
ECVF_Scalability | ECVF_Default);
static TAutoConsoleVariable<float> CVarScreenPercentage(
TEXT("r.ScreenPercentage"), 0.0f,
TEXT("To render in lower resolution and upscale for better performance (combined up with the blenable post process setting).\n")
TEXT("70 is a good value for low aliasing and performance, can be verified with 'show TestImage'\n")
TEXT("in percent, >0 and <=100, larger numbers are possible (supersampling) but the downsampling quality is improvable.")
TEXT("<=0 compute the screen percentage is determined by r.ScreenPercentage.Default cvars."),
ECVF_Scalability | ECVF_Default);
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/LegacyScreenPercentageDriver.cpp:94
Scope (from outer to inner):
file
function void InitScreenPercentage
Source code excerpt:
{
#if !UE_BUILD_SHIPPING
CVarScreenPercentage.AsVariable()->SetOnChangedCallback(FConsoleVariableDelegate::CreateStatic(&OnScreenPercentageChange));
#endif
}
static float GetRenderingPixelCount(float Rendering169Height)
{
return Rendering169Height * FMath::Abs(Rendering169Height) * (1920.0f / 1080.0f);
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/LegacyScreenPercentageDriver.cpp:177
Scope (from outer to inner):
file
function float FLegacyScreenPercentageDriver::GetCVarResolutionFraction
Source code excerpt:
static const auto ScreenPercentageCVar = IConsoleManager::Get().FindTConsoleVariableDataFloat(TEXT("r.ScreenPercentage"));
float GlobalFraction = GetResolutionFraction(CVarScreenPercentage.GetValueOnGameThread());
if (GlobalFraction <= GetResolutionFraction(Scalability::MinResolutionScale))
{
GlobalFraction = 1.0f;
}
return GlobalFraction;
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/LegacyScreenPercentageDriver.cpp:212
Scope (from outer to inner):
file
function void FStaticResolutionFractionHeuristic::FUserSettings::PullRunTimeRenderingSettings
Source code excerpt:
void FStaticResolutionFractionHeuristic::FUserSettings::PullRunTimeRenderingSettings(EViewStatusForScreenPercentage ViewStatus)
{
float GlobalResolutionFractionOverride = GetResolutionFraction(CVarScreenPercentage.GetValueOnGameThread());
MinRenderingResolution = CVarScreenPercentageMinResolution.GetValueOnGameThread();
MaxRenderingResolution = CVarScreenPercentageMaxResolution.GetValueOnGameThread();
if (GlobalResolutionFractionOverride > 0.0)
{
Mode = EScreenPercentageMode::Manual;
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/LegacyScreenPercentageDriver.cpp:258
Scope (from outer to inner):
file
function void FStaticResolutionFractionHeuristic::FUserSettings::PullRunTimeRenderingSettings
Source code excerpt:
{
Mode = EScreenPercentageMode::Manual;
GlobalResolutionFraction = GetResolutionFraction(CVarScreenPercentage.GetValueOnGameThread());
MinRenderingResolution = CVarScreenPercentageMinResolution.GetValueOnGameThread();
MaxRenderingResolution = CVarScreenPercentageMaxResolution.GetValueOnGameThread();
AutoPixelCountMultiplier = CVarAutoPixelCountMultiplier.GetValueOnGameThread();
if (GlobalResolutionFraction <= 0.0)
{