sg.EffectsQuality

sg.EffectsQuality

#Overview

name: sg.EffectsQuality

The value of this variable can be defined or overridden in .ini config files. 14 .ini config files referencing this setting variable.

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

It is referenced in 15 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of sg.EffectsQuality is to control the quality level of visual effects in Unreal Engine 5. This setting is part of the scalability system, which allows adjusting various aspects of the game’s graphics to balance performance and visual fidelity.

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

  1. The Scalability system (Engine/Source/Runtime/Engine/Private/Scalability.cpp)
  2. The Niagara VFX system (Engine/Plugins/FX/Niagara)
  3. The Movie Render Pipeline (Engine/Plugins/MovieScene/MovieRenderPipeline)

The value of this variable is set in several ways:

  1. Through the engine’s configuration files (INI files)
  2. Via console commands
  3. Programmatically in C++ code
  4. Through the scalability system’s auto-detection and user settings

The associated variable CVarEffectsQuality interacts directly with sg.EffectsQuality. They share the same value and are used interchangeably in the codebase.

Developers should be aware of the following when using this variable:

  1. It affects the overall quality of visual effects in the game
  2. Changes to this variable can impact performance
  3. It’s part of the scalability system, so it should be considered alongside other quality settings

Best practices when using this variable include:

  1. Provide user options to adjust this setting for performance optimization
  2. Use it in conjunction with other scalability settings for a balanced approach to performance and visual quality
  3. Test the impact of different quality levels on various hardware configurations
  4. Consider platform-specific defaults and limitations

Regarding the associated variable CVarEffectsQuality:

When working with either sg.EffectsQuality or CVarEffectsQuality, developers should ensure they’re using the appropriate variable for their context (configuration files vs. C++ code) and be aware that changes to one will affect the other.

#Setting Variables

#References In INI files

Location: <Workspace>/Engine/Config/BaseDeviceProfiles.ini:312, section: [IOS DeviceProfile]

Location: <Workspace>/Engine/Config/BaseDeviceProfiles.ini:836, section: [Android_Low DeviceProfile]

Location: <Workspace>/Engine/Config/BaseDeviceProfiles.ini:851, section: [Android_Mid DeviceProfile]

Location: <Workspace>/Engine/Config/BaseDeviceProfiles.ini:865, section: [Android_High DeviceProfile]

Location: <Workspace>/Engine/Config/BaseDeviceProfiles.ini:890, section: [Android_Vulkan_SM5 DeviceProfile]

Location: <Workspace>/Projects/Lyra/Config/DefaultDeviceProfiles.ini:46, section: [Mobile DeviceProfile]

Location: <Workspace>/Projects/Lyra/Config/DefaultDeviceProfiles.ini:93, section: [IOS_Low DeviceProfile]

Location: <Workspace>/Projects/Lyra/Config/DefaultDeviceProfiles.ini:106, section: [IOS_Mid DeviceProfile]

Location: <Workspace>/Projects/Lyra/Config/DefaultDeviceProfiles.ini:133, section: [IOS_High DeviceProfile]

Location: <Workspace>/Projects/Lyra/Config/DefaultDeviceProfiles.ini:150, section: [IOS_Epic DeviceProfile]

Location: <Workspace>/Projects/Lyra/Config/DefaultDeviceProfiles.ini:506, section: [Android_Low DeviceProfile]

Location: <Workspace>/Projects/Lyra/Config/DefaultDeviceProfiles.ini:519, section: [Android_Mid DeviceProfile]

Location: <Workspace>/Projects/Lyra/Config/DefaultDeviceProfiles.ini:546, section: [Android_High DeviceProfile]

Location: <Workspace>/Projects/Lyra/Config/DefaultDeviceProfiles.ini:562, section: [Android_Epic DeviceProfile]

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Scalability.cpp:87

Scope: file

Source code excerpt:


static TAutoConsoleVariable<int32> CVarEffectsQuality(
	TEXT("sg.EffectsQuality"),
	Scalability::DefaultQualityLevel,
	TEXT("Scalability quality state (internally used by scalability system, ini load/save or using SCALABILITY console command)\n")
	TEXT(" 0:low, 1:med, 2:high, 3:epic, 4:cinematic, default: 3"),
	ECVF_ScalabilityGroup | ECVF_Preview);

static TAutoConsoleVariable<int32> CVarFoliageQuality(

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/Niagara/Private/NiagaraPlatformSet.cpp:490

Scope (from outer to inner):

file
function     int32 FNiagaraPlatformSet::GetActiveQualityMaskForDeviceProfile

Source code excerpt:

			int32 EffectsQuality = INDEX_NONE;
			//See if this profile overrides effects quality.
			if (!Profile->GetConsolidatedCVarValue(TEXT("sg.EffectsQuality"), EffectsQuality))
			{
				EffectsQuality = PlatformSettings.EffectsQuality;
			}
			check(EffectsQuality != INDEX_NONE);

			QualityLevel = PlatformSettings.QualityLevelsPerEffectsQuality[EffectsQuality];

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/Niagara/Private/NiagaraPlatformSet.cpp:1296

Scope (from outer to inner):

file
function     FNiagaraPlatformSet::FPlatformIniSettings& FNiagaraPlatformSet::GetPlatformIniSettings

Source code excerpt:

	FindCVarValue(TEXT("SystemSettings"), NiagaraMaxQualityLevelName, MaxQualityLevel);

	if (!FindCVarValue(TEXT("ScalabilityGroups"), TEXT("sg.EffectsQuality"), EffectsQuality))
	{
		FindCVarValue(TEXT("SystemSettings"), TEXT("sg.EffectsQuality"), EffectsQuality);
	}

	//Get the platforms default quality level setting.
	//This can be overridden directly in a device profile or indirectly by overriding effects quality.

	int32 PruneEmittersOnCook = GbPruneEmittersOnCook;

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/Niagara/Private/NiagaraPlatformSet.cpp:1407

Scope (from outer to inner):

file
function     const FNiagaraCVarValues& FDeviceProfileValueCache::GetValues

Source code excerpt:

		int32 EffectsQuality = INDEX_NONE;
		//See if this profile overrides effects quality.
		if (!DeviceProfile->GetConsolidatedCVarValue(TEXT("sg.EffectsQuality"), EffectsQuality))
		{
			EffectsQuality = PlatformIniSettings.EffectsQuality;
		}
		check(EffectsQuality != INDEX_NONE && EffectsQuality < NumEffectsQualities);
		FString DefaultEffectsQualitySectionName = Scalability::GetScalabilitySectionString(TEXT("EffectsQuality"), EffectsQuality, NumEffectsQualities);

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/Niagara/Private/NiagaraSystemSimulation.cpp:523

Scope (from outer to inner):

file
function     FNiagaraSystemSimulationTickContext::FNiagaraSystemSimulationTickContext

Source code excerpt:

	, SpawnNum(InSpawnNum)
{
	static const auto EffectsQualityCVar = IConsoleManager::Get().FindConsoleVariable(TEXT("sg.EffectsQuality"));
	check(EffectsQualityCVar != nullptr);
	EffectsQuality = EffectsQualityCVar->GetInt();

	bRunningAsync = bAllowAsync && GNiagaraSystemSimulationAllowASync && FApp::ShouldUseThreadingForPerformance();

#if NIAGARA_SYSTEM_CAPTURE

#Loc: <Workspace>/Engine/Plugins/MovieScene/MovieRenderPipeline/Source/MovieRenderPipelineCore/Private/Graph/Nodes/MovieGraphGlobalGameOverrides.cpp:37

Scope (from outer to inner):

file
function     void UMovieGraphGlobalGameOverridesNode::BuildNewProcessCommandLineArgsImpl

Source code excerpt:

		InOutDeviceProfileCvars.Add(FString::Format(TEXT("sg.PostProcessQuality={0}"), {QualityLevels.PostProcessQuality}));
		InOutDeviceProfileCvars.Add(FString::Format(TEXT("sg.TextureQuality={0}"), {QualityLevels.TextureQuality}));
		InOutDeviceProfileCvars.Add(FString::Format(TEXT("sg.EffectsQuality={0}"), {QualityLevels.EffectsQuality}));
		InOutDeviceProfileCvars.Add(FString::Format(TEXT("sg.FoliageQuality={0}"), {QualityLevels.FoliageQuality}));
		InOutDeviceProfileCvars.Add(FString::Format(TEXT("sg.ShadingQuality={0}"), {QualityLevels.ShadingQuality}));
		InOutDeviceProfileCvars.Add(FString::Format(TEXT("sg.LandscapeQuality={0}"), {QualityLevels.LandscapeQuality}));
	}

	if (bDisableTextureStreaming)

#Loc: <Workspace>/Engine/Plugins/MovieScene/MovieRenderPipeline/Source/MovieRenderPipelineCore/Private/MoviePipelineGameOverrideSetting.cpp:169

Scope (from outer to inner):

file
function     void UMoviePipelineGameOverrideSetting::BuildNewProcessCommandLineArgsImpl

Source code excerpt:

		InOutDeviceProfileCvars.Add(TEXT("sg.PostProcessQuality=4"));
		InOutDeviceProfileCvars.Add(TEXT("sg.TextureQuality=4"));
		InOutDeviceProfileCvars.Add(TEXT("sg.EffectsQuality=4"));
		InOutDeviceProfileCvars.Add(TEXT("sg.FoliageQuality=4"));
		InOutDeviceProfileCvars.Add(TEXT("sg.ShadingQuality=4"));
	}

	switch (TextureStreaming)
	{

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Scalability.cpp:1135

Scope (from outer to inner):

file
namespace    Scalability
function     void LoadState

Source code excerpt:

	GConfig->GetInt(Section, TEXT("sg.PostProcessQuality"), State.PostProcessQuality, IniName);
	GConfig->GetInt(Section, TEXT("sg.TextureQuality"), State.TextureQuality, IniName);
	GConfig->GetInt(Section, TEXT("sg.EffectsQuality"), State.EffectsQuality, IniName);
	GConfig->GetInt(Section, TEXT("sg.FoliageQuality"), State.FoliageQuality, IniName);
	GConfig->GetInt(Section, TEXT("sg.ShadingQuality"), State.ShadingQuality, IniName);
	GConfig->GetInt(Section, TEXT("sg.LandscapeQuality"), State.LandscapeQuality, IniName);

	// If possible apply immediately, else store in backup so we can re-apply later
	if (!GScalabilityUsingTemporaryQualityLevels)

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Scalability.cpp:1169

Scope (from outer to inner):

file
namespace    Scalability
function     void SaveState

Source code excerpt:

	GConfig->SetInt(Section, TEXT("sg.PostProcessQuality"), State.PostProcessQuality, IniName);
	GConfig->SetInt(Section, TEXT("sg.TextureQuality"), State.TextureQuality, IniName);
	GConfig->SetInt(Section, TEXT("sg.EffectsQuality"), State.EffectsQuality, IniName);
	GConfig->SetInt(Section, TEXT("sg.FoliageQuality"), State.FoliageQuality, IniName);
	GConfig->SetInt(Section, TEXT("sg.ShadingQuality"), State.ShadingQuality, IniName);
	GConfig->SetInt(Section, TEXT("sg.LandscapeQuality"), State.LandscapeQuality, IniName);
}

void RecordQualityLevelsAnalytics(bool bAutoApplied)

#Loc: <Workspace>/Projects/Lyra/Source/LyraGame/Settings/LyraSettingsLocal.cpp:275

Scope (from outer to inner):

file
namespace    LyraSettingsHelpers
function     void FillScalabilitySettingsFromDeviceProfile

Source code excerpt:

		Mode.bHasOverrides |= UDeviceProfileManager::GetScalabilityCVar(FString::Printf(TEXT("sg.PostProcessQuality%s"), *Suffix), Mode.Qualities.PostProcessQuality);
		Mode.bHasOverrides |= UDeviceProfileManager::GetScalabilityCVar(FString::Printf(TEXT("sg.TextureQuality%s"), *Suffix), Mode.Qualities.TextureQuality);
		Mode.bHasOverrides |= UDeviceProfileManager::GetScalabilityCVar(FString::Printf(TEXT("sg.EffectsQuality%s"), *Suffix), Mode.Qualities.EffectsQuality);
		Mode.bHasOverrides |= UDeviceProfileManager::GetScalabilityCVar(FString::Printf(TEXT("sg.FoliageQuality%s"), *Suffix), Mode.Qualities.FoliageQuality);
		Mode.bHasOverrides |= UDeviceProfileManager::GetScalabilityCVar(FString::Printf(TEXT("sg.ShadingQuality%s"), *Suffix), Mode.Qualities.ShadingQuality);
	}

	TMobileQualityWrapper<int32> OverallQualityLimits(-1, CVarMobileQualityLimits);
	TMobileQualityWrapper<float> ResolutionQualityLimits(100.0f, CVarMobileResolutionQualityLimits);

#Associated Variable and Callsites

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

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Scalability.cpp:86

Scope: file

Source code excerpt:

	ECVF_ScalabilityGroup | ECVF_Preview);

static TAutoConsoleVariable<int32> CVarEffectsQuality(
	TEXT("sg.EffectsQuality"),
	Scalability::DefaultQualityLevel,
	TEXT("Scalability quality state (internally used by scalability system, ini load/save or using SCALABILITY console command)\n")
	TEXT(" 0:low, 1:med, 2:high, 3:epic, 4:cinematic, default: 3"),
	ECVF_ScalabilityGroup | ECVF_Preview);

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Scalability.cpp:592

Scope (from outer to inner):

file
namespace    Scalability
function     void InitScalabilitySystem

Source code excerpt:

	CVarPostProcessQuality.AsVariable()->SetOnChangedCallback(FConsoleVariableDelegate::CreateStatic(&OnChangePostProcessQuality));
	CVarTextureQuality.AsVariable()->SetOnChangedCallback(FConsoleVariableDelegate::CreateStatic(&OnChangeTextureQuality));
	CVarEffectsQuality.AsVariable()->SetOnChangedCallback(FConsoleVariableDelegate::CreateStatic(&OnChangeEffectsQuality));
	CVarFoliageQuality.AsVariable()->SetOnChangedCallback(FConsoleVariableDelegate::CreateStatic(&OnChangeFoliageQuality));
	CVarShadingQuality.AsVariable()->SetOnChangedCallback(FConsoleVariableDelegate::CreateStatic(&OnChangeShadingQuality));
	CVarLandscapeQuality.AsVariable()->SetOnChangedCallback(FConsoleVariableDelegate::CreateStatic(&OnChangeLandscapeQuality));

#if WITH_EDITOR
	ScalabilityShaderPlatform = GMaxRHIShaderPlatform;

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Scalability.cpp:894

Scope (from outer to inner):

file
namespace    Scalability
function     void SetQualityLevels

Source code excerpt:

		SetQualityLevelCVar(CVarPostProcessQuality, ClampedLevels.PostProcessQuality, GScalabilityQualityLevelsOverride.PostProcessQuality, bForce);
		SetQualityLevelCVar(CVarTextureQuality, ClampedLevels.TextureQuality, GScalabilityQualityLevelsOverride.TextureQuality, bForce);
		SetQualityLevelCVar(CVarEffectsQuality, ClampedLevels.EffectsQuality, GScalabilityQualityLevelsOverride.EffectsQuality, bForce);
		SetQualityLevelCVar(CVarFoliageQuality, ClampedLevels.FoliageQuality, GScalabilityQualityLevelsOverride.FoliageQuality, bForce);
		SetQualityLevelCVar(CVarShadingQuality, ClampedLevels.ShadingQuality, GScalabilityQualityLevelsOverride.ShadingQuality, bForce);
		SetQualityLevelCVar(CVarLandscapeQuality, ClampedLevels.LandscapeQuality, GScalabilityQualityLevelsOverride.LandscapeQuality, bForce);

		OnScalabilitySettingsChanged.Broadcast(ClampedLevels);
	}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Scalability.cpp:926

Scope (from outer to inner):

file
namespace    Scalability
function     FQualityLevels GetQualityLevels

Source code excerpt:

		Ret.PostProcessQuality = CVarPostProcessQuality.GetValueOnGameThread();
		Ret.TextureQuality = CVarTextureQuality.GetValueOnGameThread();
		Ret.EffectsQuality = CVarEffectsQuality.GetValueOnGameThread();
		Ret.FoliageQuality = CVarFoliageQuality.GetValueOnGameThread();
		Ret.ShadingQuality = CVarShadingQuality.GetValueOnGameThread();
		Ret.LandscapeQuality = CVarLandscapeQuality.GetValueOnGameThread();
	}
	else
	{

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Scalability.cpp:967

Scope (from outer to inner):

file
namespace    Scalability
function     int32 GetEffectsQualityDirect

Source code excerpt:

	if (bGameThread)
	{
		return CVarEffectsQuality.GetValueOnAnyThread(true);
	}
	else
	{
		return CVarEffectsQuality.GetValueOnRenderThread();
	}
}

void FQualityLevels::SetBenchmarkFallback()
{
	ResolutionQuality = 100.0f;