r.DetailMode

r.DetailMode

#Overview

name: r.DetailMode

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

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

It is referenced in 16 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of r.DetailMode is to control the level of detail for rendering and updating components in Unreal Engine. It determines which actors and components should be updated or ticked based on their detail mode setting.

This setting variable is primarily used by the rendering system and affects various Unreal Engine subsystems, including:

  1. Scene capture components
  2. Particle systems
  3. Landscape grass
  4. General actor and component rendering

The value of r.DetailMode is typically set through the console or configuration files. It can be modified at runtime using the console command system.

The r.DetailMode variable interacts with several other variables and systems:

  1. It is associated with CVarDetailMode, which shares the same value.
  2. It is used in conjunction with r.CookOutUnusedDetailModeComponents for asset cooking.
  3. It affects the behavior of scene capture components when used with r.SceneCapture.CullByDetailMode.

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

  1. The value ranges from 0 to 3, representing Low, Medium, High, and Epic detail modes.
  2. It can significantly impact performance and visual quality.
  3. It is used for both runtime rendering decisions and asset cooking.

Best practices when using this variable include:

  1. Set appropriate detail modes for components and actors to allow for proper scalability.
  2. Use it in combination with other scalability settings for a comprehensive performance management strategy.
  3. Consider platform-specific settings when deploying to multiple platforms.

Regarding the associated variable CVarDetailMode:

The purpose of CVarDetailMode is to provide a console variable interface for r.DetailMode. It allows for easy modification of the detail mode setting through the console command system.

CVarDetailMode is used in the same subsystems and modules as r.DetailMode, as they share the same value and purpose.

The value of CVarDetailMode is set through the console variable system, typically at engine initialization or runtime.

Developers should be aware that modifying CVarDetailMode will directly affect r.DetailMode and, consequently, the rendering and update behavior of the engine.

Best practices for using CVarDetailMode include:

  1. Use it for debugging and testing different detail mode settings during development.
  2. Consider exposing it in user-facing graphics settings for runtime adjustments.
  3. Be cautious when modifying it at runtime, as it can have significant performance implications.

#Setting Variables

#References In INI files

Location: <Workspace>/Engine/Config/BaseScalability.ini:616, section: [EffectsQuality@0]

Location: <Workspace>/Engine/Config/BaseScalability.ini:643, section: [EffectsQuality@1]

Location: <Workspace>/Engine/Config/BaseScalability.ini:670, section: [EffectsQuality@2]

Location: <Workspace>/Engine/Config/BaseScalability.ini:697, section: [EffectsQuality@3]

Location: <Workspace>/Engine/Config/BaseScalability.ini:725, section: [EffectsQuality@Cine]

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

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Source/Runtime/Core/Private/HAL/ConsoleManager.cpp:4032

Scope: file

Source code excerpt:


static TAutoConsoleVariable<int32> CVarDetailMode(
	TEXT("r.DetailMode"),
	3,
	TEXT("Current detail mode; determines whether components of actors should be updated/ ticked.\n"
		" 0: low, show objects with DetailMode low\n"
		" 1: medium, show objects with DetailMode medium or below\n"
		" 2: high, show objects with DetailMode high or below\n"
		" 3: epic, show all objects (default)"),

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/EditorServer.cpp:6567

Scope (from outer to inner):

file
function     bool UEditorEngine::HandleSetDetailModeViewCommand

Source code excerpt:


		// Detail mode was modified, so store in the CVar
		static IConsoleVariable* DetailModeCVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.DetailMode"));
		check (DetailMode);
		DetailModeCVar->Set(DetailMode);
	}

	RedrawLevelEditingViewports( true );
	return true;

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Components/SceneCaptureComponent2D.h:176

Scope (from outer to inner):

file
class        class USceneCaptureComponent2D : public USceneCaptureComponent

Source code excerpt:

	/**
	 * Render the scene to the texture the next time the main view is rendered.
	 * If r.SceneCapture.CullByDetailMode is set, nothing will happen if DetailMode is higher than r.DetailMode.
	 */
	ENGINE_API void CaptureSceneDeferred();

	// For backwards compatibility
	void UpdateContent() { CaptureSceneDeferred(); }

	/** 
	 * Render the scene to the texture target immediately.  
	 * This should not be used if bCaptureEveryFrame is enabled, or the scene capture will render redundantly. 
	 * If r.SceneCapture.CullByDetailMode is set, nothing will happen if DetailMode is higher than r.DetailMode.
	 */
	UFUNCTION(BlueprintCallable,Category = "Rendering|SceneCapture")
	ENGINE_API void CaptureScene();

	ENGINE_API void UpdateSceneCaptureContents(FSceneInterface* Scene) override;

	/* Return if orthographic tiling rendering is enabled or not */
	ENGINE_API bool GetEnableOrthographicTiling() const;

	/* Return number of X tiles to render (to be used when orthographic tiling rendering is enabled) */

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Components/SceneCaptureComponentCube.h:43

Scope (from outer to inner):

file
class        class USceneCaptureComponentCube : public USceneCaptureComponent

Source code excerpt:

	/**
	 * Render the scene to the texture the next time the main view is rendered.
	 * If r.SceneCapture.CullByDetailMode is set, nothing will happen if DetailMode is higher than r.DetailMode.
	 */
	ENGINE_API void CaptureSceneDeferred();

	/** 
	 * Render the scene to the texture target immediately.  
	 * This should not be used if bCaptureEveryFrame is enabled, or the scene capture will render redundantly. 
	 * If r.SceneCapture.CullByDetailMode is set, nothing will happen if DetailMode is higher than r.DetailMode.
	 */
	UFUNCTION(BlueprintCallable,Category = "Rendering|SceneCapture")
	ENGINE_API void CaptureScene();

	// For backwards compatibility
	void UpdateContent() { CaptureSceneDeferred(); }

	ENGINE_API void UpdateSceneCaptureContents(FSceneInterface* Scene) override;

	/** Whether this component is a USceneCaptureComponentCube */

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Kismet/KismetSystemLibrary.h:1626

Scope: file

Source code excerpt:


	/**
	 * Get the clamped state of r.DetailMode, see console variable help (allows for scalability, cannot be used in construction scripts)
	 * 0: low, show objects with DetailMode low
	 * 1: medium, show objects with DetailMode medium or below
	 * 2: high, show objects with DetailMode high or below
	 * 3: epic, show all objects
	 */
	UFUNCTION(BlueprintPure, Category="Rendering", meta=(UnsafeDuringActorConstruction = "true"))
	static ENGINE_API int32 GetRenderingDetailMode();

	/**
	 * Get the clamped state of r.MaterialQualityLevel, see console variable help (allows for scalability, cannot be used in construction scripts)
	 * 0: low
	 * 1: high

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Actor.cpp:542

Scope (from outer to inner):

file
function     bool AActor::NeedsLoadForTargetPlatform

Source code excerpt:

		{
			int32 CVarDetailMode;
			if(DeviceProfile->GetConsolidatedCVarValue(TEXT("r.DetailMode"), CVarDetailMode))
			{
				// Check root component's detail mode.
				// If e.g. the component's detail mode is High and the platform detail is Medium,
				// then we should cull it.
				if((int32)RootComponent->DetailMode > CVarDetailMode)
				{

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/SceneComponent.cpp:442

Scope (from outer to inner):

file
function     static bool SceneComponentNeedsLoadForTarget

Source code excerpt:

		{
			int32 CVarDetailMode;
			if(DeviceProfile->GetConsolidatedCVarValue(TEXT("r.DetailMode"), CVarDetailMode))
			{
				// Check component's detail mode.
				// If e.g. the component's detail mode is High and the platform detail is Medium,
				// then we should cull it.
				if((int32)SceneComponentObject->DetailMode > CVarDetailMode)
				{

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/KismetSystemLibrary.cpp:2635

Scope (from outer to inner):

file
function     int32 UKismetSystemLibrary::GetRenderingDetailMode

Source code excerpt:

int32 UKismetSystemLibrary::GetRenderingDetailMode()
{
	static const IConsoleVariable* CVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.DetailMode"));

	// clamp range
	int32 Ret = FMath::Clamp(CVar->GetInt(), 0, DM_MAX - 1);

	return Ret;
}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Particles/ParticleComponents.cpp:2787

Scope (from outer to inner):

file
function     void UParticleSystem::Serialize

Source code excerpt:

				// get the detail mode from the device platform ini; if it's not there, we assume all detail modes
				int32 CVarDetailMode = PDM_DefaultValue;
				if (DeviceProfile->GetConsolidatedCVarValue(TEXT("r.DetailMode"), CVarDetailMode))
				{
					CookTargetPlatformDetailModeMask = (1 << CVarDetailMode);
				}
			}
		}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Particles/ParticleComponents.cpp:3846

Scope (from outer to inner):

file
function     void DetailModeSink

Source code excerpt:

	//This Cvar sink can happen before the one which primes the cached scalability cvars so we must grab this ourselves.
	IConsoleManager& ConsoleMan = IConsoleManager::Get();
	static const auto DetailMode = ConsoleMan.FindTConsoleVariableDataInt(TEXT("r.DetailMode"));
	int32 NewDetailMode = DetailMode->GetValueOnGameThread();
	static int32 CachedDetailMode = NewDetailMode;

	if (CachedDetailMode != NewDetailMode)
	{
		CachedDetailMode = NewDetailMode;

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/UnrealEngine.cpp:748

Scope (from outer to inner):

file
function     void ScalabilityCVarsSinkCallback

Source code excerpt:


	{
		static const auto DetailMode = ConsoleMan.FindTConsoleVariableDataInt(TEXT("r.DetailMode"));
		LocalScalabilityCVars.DetailMode = DetailMode->GetValueOnGameThread();
	}

	{
		static const auto* MaxAnisotropy = ConsoleMan.FindTConsoleVariableDataInt(TEXT("r.MaxAnisotropy"));
		LocalScalabilityCVars.MaxAnisotropy = MaxAnisotropy->GetValueOnGameThread();

#Loc: <Workspace>/Engine/Source/Runtime/Landscape/Private/LandscapeGrass.cpp:835

Scope (from outer to inner):

file
function     static void GrassCVarSinkFunction

Source code excerpt:

	float GrassCullDistanceScale = GGrassCullDistanceScale;

	static const IConsoleVariable* DetailModeCVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.DetailMode"));
	static int32 CachedDetailMode = DetailModeCVar ? DetailModeCVar->GetInt() : 0;
	int32 DetailMode = DetailModeCVar ? DetailModeCVar->GetInt() : 0;

	static const IConsoleVariable* NaniteEnabledCVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.Nanite"));
	static int32 CachedNaniteEnabled = NaniteEnabledCVar ? NaniteEnabledCVar->GetInt() : 0;
	int32 NaniteEnabled = NaniteEnabledCVar ? NaniteEnabledCVar->GetInt() : 0;

#Associated Variable and Callsites

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

#Loc: <Workspace>/Engine/Source/Runtime/Core/Private/HAL/ConsoleManager.cpp:4031

Scope: file

Source code excerpt:

	ECVF_RenderThreadSafe);

static TAutoConsoleVariable<int32> CVarDetailMode(
	TEXT("r.DetailMode"),
	3,
	TEXT("Current detail mode; determines whether components of actors should be updated/ ticked.\n"
		" 0: low, show objects with DetailMode low\n"
		" 1: medium, show objects with DetailMode medium or below\n"
		" 2: high, show objects with DetailMode high or below\n"

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Actor.cpp:541

Scope (from outer to inner):

file
function     bool AActor::NeedsLoadForTargetPlatform

Source code excerpt:

		if(DeviceProfile->GetConsolidatedCVarValue(TEXT("r.CookOutUnusedDetailModeComponents"), CVarCullBasedOnDetailLevel) && CVarCullBasedOnDetailLevel == 1)
		{
			int32 CVarDetailMode;
			if(DeviceProfile->GetConsolidatedCVarValue(TEXT("r.DetailMode"), CVarDetailMode))
			{
				// Check root component's detail mode.
				// If e.g. the component's detail mode is High and the platform detail is Medium,
				// then we should cull it.
				if((int32)RootComponent->DetailMode > CVarDetailMode)
				{
					return false;
				}
			}
		}
	}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/SceneComponent.cpp:441

Scope (from outer to inner):

file
function     static bool SceneComponentNeedsLoadForTarget

Source code excerpt:

		if(DeviceProfile->GetConsolidatedCVarValue(TEXT("r.CookOutUnusedDetailModeComponents"), CVarCullBasedOnDetailLevel) && CVarCullBasedOnDetailLevel == 1)
		{
			int32 CVarDetailMode;
			if(DeviceProfile->GetConsolidatedCVarValue(TEXT("r.DetailMode"), CVarDetailMode))
			{
				// Check component's detail mode.
				// If e.g. the component's detail mode is High and the platform detail is Medium,
				// then we should cull it.
				if((int32)SceneComponentObject->DetailMode > CVarDetailMode)
				{
					return false;
				}
			}
		}
	}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Particles/ParticleComponents.cpp:2786

Scope (from outer to inner):

file
function     void UParticleSystem::Serialize

Source code excerpt:

			{
				// get the detail mode from the device platform ini; if it's not there, we assume all detail modes
				int32 CVarDetailMode = PDM_DefaultValue;
				if (DeviceProfile->GetConsolidatedCVarValue(TEXT("r.DetailMode"), CVarDetailMode))
				{
					CookTargetPlatformDetailModeMask = (1 << CVarDetailMode);
				}
			}
		}

		// if we're cooking, save only emitters with matching detail modes
		for (int32 EmitterIdx = 0; EmitterIdx<Emitters.Num(); EmitterIdx++)