keywords: UE4, Scalability Settings, Graphics Quality

Scalability Command

Run follows in console command or execute UKismetSystemLibrary::ExecuteConsoleCommand() to modify graphics quality at run-time:

r.PostProcessAAQuality 4
sg.PostProcessQuality 3
sg.ShadowQuality 3
sg.TextureQuality 3
sg.EffectsQuality 3
foliage.DensityScale 1.0
grass.DensityScale 1.0

Blueprint function Execute Console Command (C++ interface is UKismetSystemLibrary::ExecuteConsoleCommand()) also works in shipping package.

Reference:
Scalability Reference
https://docs.unrealengine.com/en-us/Engine/Performance/Scalability/ScalabilityReference Unreal Engine 4 Save and Load Graphics Settings using Blueprints Tutorial
https://www.youtube.com/watch?v=5AXA2CrPwTo
Change Graphics Settings In-Game - Unreal Engine 4 Tutorial
https://www.youtube.com/watch?v=T90vqA9x5so

Scalability on mobile

Take Android device as example, graphics quality configuration on mobile:
Example in \Engine\Config\Android\AndroidScalability.ini

; ------------------------------------------------------------------------------
; Foliage settings
; ------------------------------------------------------------------------------

[FoliageQuality@0]
foliage.DensityScale=0.5
grass.DensityScale=0.5

[FoliageQuality@1]
grass.densityScale=0.8
grass.CullDistanceScale=0.8
foliage.DensityScale=0.8

Take high-end Android device an example, the default configuration for different device type:
Example in \Engine\Config\BaseDeviceProfiles.ini

[Android_High DeviceProfile]
DeviceType=Android
BaseProfileName=Android
+CVars=sg.ViewDistanceQuality=2
+CVars=sg.AntiAliasingQuality=2
+CVars=sg.ShadowQuality=2
+CVars=sg.PostProcessQuality=2
+CVars=sg.TextureQuality=2
+CVars=sg.EffectsQuality=2
+CVars=sg.FoliageQuality=2
+CVars=r.MobileContentScaleFactor=1.0
Scalability on PC & Console

Directory in PIE:
[UnrealEngine]/Engine/Config/BaseScalability.ini

Directory in shipped package:

  • Shipping Client: %localappdata%/[ProjectName]/Saved/Config/WindowsNoEditor/Engine.ini
  • Others: [ProjectName]/Saved/Config/WindowsNoEditor/Engine.ini

Example content in Engine\Config\BaseScalability.ini:

[ShadowQuality@0]
r.LightFunctionQuality=0
r.ShadowQuality=0
r.Shadow.CSM.MaxCascades=1
r.Shadow.MaxResolution=512
r.Shadow.MaxCSMResolution=512
r.Shadow.RadiusThreshold=0.06
r.Shadow.DistanceScale=0.6
r.Shadow.CSM.TransitionScale=0
r.Shadow.PreShadowResolutionFactor=0.5
r.DistanceFieldShadowing=0
r.DistanceFieldAO=0
r.VolumetricFog=0
r.LightMaxDrawDistanceScale=0
r.CapsuleShadows=0

Content in AndroidScalability.ini will be merged into Engine.ini automatically and override settings of Engine\Config\BaseScalability.ini while building package.

Screen Resolution on Mobile

iOS:

  • r.MobileContentScaleFactor 0.0:Native resolution.
  • r.MobileContentScaleFactor 1.0:Use non-Retina resolution on Retina devices.
  • r.MobileContentScaleFactor 2.0:Native resolution of iPhone 4 ~ iPhone 6.
  • r.MobileContentScaleFactor 3.0:Native resolution of iPhone 6+.

Android:

  • r.MobileContentScaleFactor 0.0:Native resolution.
  • r.MobileContentScaleFactor 1.0:720p (1280 x 720).
  • r.MobileContentScaleFactor 2.0:Scale of 1.0 (720p).

Origin:
https://www.jianshu.com/p/7ee6b5020767

Checking Scalability

The entry of setting scalability automatically on application startup:
in Engine\Source\Runtime\Engine\Private\DeviceProfiles\DeviceProfileManager.cpp

/**
 * Startup and select the active device profile
 * Then Init the CVars from this profile and it's Device profile parent tree.
 */
static void InitializeCVarsForActiveDeviceProfile(bool bPushSettings=false, bool bForceDeviceProfilePriority = false);

Gather device scalability detail and set graphics quality automatically:
Console command:

scalability auto

This command will also output details in log file.

C++ API:

if(UGameUserSettings* GameUserSettings = UGameUserSettings::GetGameUserSettings())
{
    GameUserSettings->RunHardwareBenchmark();
    GameUserSettings->ApplyHardwareBenchmarkResults();
}

Gather CPU and GPU benchmark data:

const Scalability::FQualityLevels State = Scalability::BenchmarkQualityLevels();
const float CPUIndex = State.CPUBenchmarkResults;
const float GPUIndex = State.GPUBenchmarkResults;

The return value corresponds to the configuration in Engine\Config\BaseScalability.ini

[ScalabilitySettings]
; PerfIndexThresholds define the thresholds that determine what the autodetected quality should be for each group.
; When you auto detect performance, both a CPUIndex and GPUIndex are calculated on the machine.
; Use the console command "scalability auto" to print these values for a machine.
; The type of perfindex used to determine the quality for a group is either the GPU, CPU or Min.
; GPU means the quality is based on the speed of the graphics card. CPU means the quality is based on the processor, and Min means the group quality is based on the slower of either the CPU or GPU.
; Each group has a type followed by three numbers.
; The first number is the perfindex threshold that changes quality from 0 to 1. The second is the threshold from 1 to 2, the third is the threshold from 2 to 3.
PerfIndexThresholds_ResolutionQuality="GPU 18 42 115"
PerfIndexThresholds_ViewDistanceQuality="Min 18 42 105"
PerfIndexThresholds_AntiAliasingQuality="GPU 18 42 115"
PerfIndexThresholds_ShadowQuality="Min 18 42 105"
PerfIndexThresholds_PostProcessQuality="GPU 18 42 115"
PerfIndexThresholds_TextureQuality="GPU 18 42 115"
PerfIndexThresholds_EffectsQuality="Min 18 42 105"
PerfIndexThresholds_FoliageQuality="GPU 18 42 115"
PerfIndexThresholds_ShadingQuality="GPU 18 42 115"

; This is the screen percentage for the resolution quality, corresponding to 25% pixels, 50% pixels, 75% pixels, and 100% pixels
PerfIndexValues_ResolutionQuality="50 71 87 100 100"

Output log:

Cmd: scalability auto
LogSynthBenchmark: Display: FSynthBenchmark (V0.95):  requested WorkScale=10.00
LogSynthBenchmark: Display: ===============
LogSynthBenchmark: Display: Main Processor:
LogSynthBenchmark: Display:          ... 0.049066 s/Run 'RayIntersect'
LogSynthBenchmark: Display:          ... 0.030856 s/Run 'Fractal'
LogSynthBenchmark: Display: 
LogSynthBenchmark: Display:   CompiledTarget_x_Bits: 64
LogSynthBenchmark: Display:   UE_BUILD_SHIPPING: 0
LogSynthBenchmark: Display:   UE_BUILD_TEST: 0
LogSynthBenchmark: Display:   UE_BUILD_DEBUG: 0
LogSynthBenchmark: Display:   TotalPhysicalGBRam: 32
LogSynthBenchmark: Display:   NumberOfCores (physical): 8
LogSynthBenchmark: Display:   NumberOfCores (logical): 8
LogSynthBenchmark: Display:   CPU Perf Index 0: 52.2 (weight 1.00)
LogSynthBenchmark: Display:   CPU Perf Index 1: 92.7 (weight 1.50)
LogSynthBenchmark: Display:  
LogSynthBenchmark: Display: Graphics:
LogSynthBenchmark: Display:   Adapter Name: 'Radeon RX 470 Series'
LogSynthBenchmark: Display:   (On Optimus the name might be wrong, memory should be ok)
LogSynthBenchmark: Display:   Vendor Id: 0x1002
LogSynthBenchmark: Display:   Device Id: 0x67DF
LogSynthBenchmark: Display:   Device Revision: 0xFF
LogSynthBenchmark: Display:   GPU Memory: 4076/0/16351 MB
LogSynthBenchmark: Display:   GPU first test: 0.05s
LogSynthBenchmark: Display:          ... 7.508 s/GigaPix, Confidence=89% 'ALUHeavyNoise' (likely to be very inaccurate)
LogSynthBenchmark: Display:          ... 5.685 s/GigaPix, Confidence=89% 'TexHeavy' (likely to be very inaccurate)
LogSynthBenchmark: Display:          ... 5.209 s/GigaPix, Confidence=89% 'DepTexHeavy' (likely to be very inaccurate)
LogSynthBenchmark: Display:          ... 15.020 s/GigaPix, Confidence=40% 'FillOnly' (likely to be very inaccurate)
LogSynthBenchmark: Display:          ... 0.629 s/GigaPix, Confidence=100% 'Bandwidth' (likely to be very inaccurate)
LogSynthBenchmark: Display:          ... 2.354 s/GigaVert, Confidence=51% 'VertThroughPut1' (likely to be very inaccurate)
LogSynthBenchmark: Display:          ... 4.441 s/GigaVert, Confidence=100% 'VertThroughPut2' (likely to be very inaccurate)
LogSynthBenchmark: Display:   GPU second test: 0.29s
LogSynthBenchmark: Display:          ... 11.496 s/GigaPix, Confidence=70% 'ALUHeavyNoise' (likely to be inaccurate)
LogSynthBenchmark: Display:          ... 8.107 s/GigaPix, Confidence=89% 'TexHeavy' (likely to be inaccurate)
LogSynthBenchmark: Display:          ... 7.910 s/GigaPix, Confidence=100% 'DepTexHeavy' (likely to be inaccurate)
LogSynthBenchmark: Display:          ... 32.663 s/GigaPix, Confidence=100% 'FillOnly' (likely to be inaccurate)
LogSynthBenchmark: Display:          ... 0.672 s/GigaPix, Confidence=100% 'Bandwidth' (likely to be inaccurate)
LogSynthBenchmark: Display:          ... 2.340 s/GigaVert, Confidence=100% 'VertThroughPut1' (likely to be inaccurate)
LogSynthBenchmark: Display:          ... 4.447 s/GigaVert, Confidence=100% 'VertThroughPut2' (likely to be inaccurate)
LogSynthBenchmark: Display:   GPU Final Results:
LogSynthBenchmark: Display:          ... 11.496 s/GigaPix, Confidence=70% 'ALUHeavyNoise'
LogSynthBenchmark: Display:          ... 8.107 s/GigaPix, Confidence=89% 'TexHeavy'
LogSynthBenchmark: Display:          ... 7.910 s/GigaPix, Confidence=100% 'DepTexHeavy'
LogSynthBenchmark: Display:          ... 32.663 s/GigaPix, Confidence=100% 'FillOnly'
LogSynthBenchmark: Display:          ... 0.672 s/GigaPix, Confidence=100% 'Bandwidth'
LogSynthBenchmark: Display:          ... 2.340 s/GigaVert, Confidence=100% 'VertThroughPut1'
LogSynthBenchmark: Display:          ... 4.447 s/GigaVert, Confidence=100% 'VertThroughPut2'
LogSynthBenchmark: Display: 
LogSynthBenchmark: Display:   GPU Perf Index 0: 249.9 (weight 1.00)
LogSynthBenchmark: Display:   GPU Perf Index 1: 108.9 (weight 0.10)
LogSynthBenchmark: Display:   GPU Perf Index 2: 205.6 (weight 0.10)
LogSynthBenchmark: Display:   GPU Perf Index 3: 128.3 (weight 3.00)
LogSynthBenchmark: Display:   GPU Perf Index 4: 62.7 (weight 1.00)
LogSynthBenchmark: Display:   GPU Perf Index 5: 152.2 (weight 0.00)
LogSynthBenchmark: Display:   GPU Perf Index 6: 251.7 (weight 0.00)
LogSynthBenchmark: Display:   GPUIndex: 140.2
LogSynthBenchmark: Display:   CPUIndex: 76.5
LogSynthBenchmark: Display: 
LogSynthBenchmark: Display:          ... Total Time: 2.228119 sec

Auto-detect Optimal Graphics Settings for Unreal
https://www.tomlooman.com/auto-detect-graphics-settings-ue4/

GameUserSettings->RunHardwareBenchmark(); and Scalability::BenchmarkQualityLevels(); only work on PC and console. The mobile device fluctuates inaccurately, and may be greatly affected by temperature.

How to read config file (.ini)

config file path: [Project]/Config/DefaultMyGameSettings.ini

[/Script/MyGame.MyGameSettings]
+AssetList=/Game/Assets/Textures/T_Diffuse
+AssetList=/Game/Assets/Textures/T_Normal

Reading example:

TArray<FString> AssetList;
FString Path = FPaths::SourceConfigDir() + TEXT("DefaultMyGameSettings.ini");
GConfig->GetArray(TEXT("/Script/MyGame.MyGameSettings"), TEXT("+AssetList"), AssetList, Path);

Example from Engine\Source\Runtime\Engine\Private\Scalability.cpp:

const FString ArrayKey = FString(TEXT("PerfIndexThresholds_")) + GroupName;
TArray<FString> PerfIndexThresholds;
GConfig->GetSingleLineArray(TEXT("ScalabilitySettings"), *ArrayKey, PerfIndexThresholds, GScalabilityIni);
How to get device profile name
FString DefaultDeviceProfileName = FPlatformMisc::GetDefaultDeviceProfileName();
UE_LOG(LogTemp, Display, TEXT("DeviceProfile+++++ %s"), *DefaultDeviceProfileName);

UDeviceProfile* DeviceProfile = UDeviceProfileManager::Get().GetActiveProfile();
FString ProfileName = "";
if (DeviceProfile != nullptr)
{
    if (DeviceProfile->BaseProfileName.IsEmpty())
    {
        ProfileName = DeviceProfile->GetName();
    }
    else
    {
        ProfileName = DeviceProfile->BaseProfileName;
    }
}
How to get scalability value using C++
int32 PostProcessQuality = UKismetSystemLibrary::GetConsoleVariableIntValue(TEXT("sg.PostProcessQuality"))

Or

int Value = 0;
IConsoleVariable* Variable = IConsoleManager::Get().FindConsoleVariable(TEXT("sg.PostProcessQuality"));
if (Variable)
{
    Value = Variable->GetInt();
}
How to run game in fixed frame rate

Append follows in Engine.ini.
Fixed frame rate:

[/Script/Engine.Engine]
bUseFixedFrameRate=True
FixedFrameRate=60.000000

Unlimited frame rate:

[/Script/Engine.Engine]
bUseFixedFrameRate=False

A man who cannot tolerate small misfortunes can never accomplish great things. -Chinese Proverbs