r.GenerateMeshDistanceFields

r.GenerateMeshDistanceFields

#Overview

name: r.GenerateMeshDistanceFields

The value of this variable can be defined or overridden in .ini config files. 1 .ini config file 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 r.GenerateMeshDistanceFields is to control the generation of distance fields for static meshes in Unreal Engine. Distance fields are used for various rendering techniques, including software ray tracing in Lumen, distance field ambient occlusion, movable skylight shadows, and ray-traced distance field shadows on directional lights.

This setting variable is primarily used by the rendering system and is crucial for several advanced lighting and shadowing techniques. The following Unreal Engine subsystems and modules rely on this variable:

  1. Rendering system
  2. Lumen Global Illumination
  3. Niagara particle system
  4. Static mesh processing
  5. Lighting components (Directional Light and Sky Light)

The value of this variable is typically set in the project’s renderer settings (URendererSettings class) or through the console. It can also be modified programmatically, but changing it requires restarting the editor.

The associated variable bGenerateMeshDistanceFields interacts closely with r.GenerateMeshDistanceFields. They share the same value and are used interchangeably in different parts of the engine.

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

  1. Enabling distance field generation increases build times, memory usage, and disk size of static meshes.
  2. Changing this setting requires restarting the editor.
  3. It affects the behavior of various lighting and shadowing techniques, particularly those related to Lumen and distance field-based effects.

Best practices when using this variable include:

  1. Enable it when using Lumen Global Illumination or other distance field-based rendering techniques.
  2. Consider the performance impact on build times and resource usage when enabling this feature.
  3. Ensure that the project’s hardware requirements are met, as distance field generation can be resource-intensive.
  4. Use it in conjunction with other related settings, such as those for Lumen and ray tracing, to achieve the desired visual quality and performance balance.

Regarding the associated variable bGenerateMeshDistanceFields:

The purpose of bGenerateMeshDistanceFields is the same as r.GenerateMeshDistanceFields, serving as a project-level setting to control distance field generation for static meshes.

This variable is primarily used in the renderer settings and static mesh processing. It is set in the URendererSettings class and is used in various parts of the engine to determine whether distance fields should be generated.

The value of this variable is typically set through the project settings interface or programmatically in the URendererSettings class.

Developers should be aware that changing this variable has the same implications as changing r.GenerateMeshDistanceFields, including increased build times and resource usage.

Best practices for using bGenerateMeshDistanceFields are similar to those for r.GenerateMeshDistanceFields, focusing on balancing visual quality with performance and resource usage.

#Setting Variables

#References In INI files

Location: <Workspace>/Projects/Lyra/Config/DefaultEngine.ini:109, section: [/Script/Engine.RendererSettings]

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Engine/RendererSettings.h:560

Scope (from outer to inner):

file
class        class URendererSettings : public UDeveloperSettings

Source code excerpt:


	UPROPERTY(config, EditAnywhere, Category=SoftwareRayTracing, meta=(
		ConsoleVariable="r.GenerateMeshDistanceFields",
		ToolTip="Whether to build distance fields of static meshes, needed for Software Ray Tracing in Lumen, and distance field AO, which is used to implement Movable SkyLight shadows, and ray traced distance field shadows on directional lights.  Enabling will increase the build times, memory usage and disk size of static meshes.  Changing this setting requires restarting the editor.",
		ConfigRestartRequired=true))
	uint32 bGenerateMeshDistanceFields:1;

	UPROPERTY(config, EditAnywhere, Category=SoftwareRayTracing, meta=(
		EditCondition = "bGenerateMeshDistanceFields",

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/DistanceFieldAtlas.cpp:51

Scope: file

Source code excerpt:


static TAutoConsoleVariable<int32> CVarDistField(
	TEXT("r.GenerateMeshDistanceFields"),
	0,	
	TEXT("Whether to build distance fields of static meshes, needed for Lumen Software Ray Tracing and Distance Field AO, which is used to implement Movable SkyLight shadows.\n")
	TEXT("Enabling will increase mesh build times and memory usage.  Changing this value will cause a rebuild of all static meshes."),
	ECVF_ReadOnly);

static TAutoConsoleVariable<int32> CVarDistFieldSupportWhenHardwareRayTracingEnabled(

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/Niagara/Private/NiagaraDataInterfaceCollisionQuery.cpp:457

Scope (from outer to inner):

file
function     bool IsDistanceFieldEnabled

Source code excerpt:

bool IsDistanceFieldEnabled()
{
	static const auto* CVarGenerateMeshDistanceFields = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.GenerateMeshDistanceFields"));
	return CVarGenerateMeshDistanceFields != nullptr && CVarGenerateMeshDistanceFields->GetValueOnAnyThread() > 0;
}

#if WITH_EDITOR
void UNiagaraDataInterfaceCollisionQuery::ValidateFunction(const FNiagaraFunctionSignature& Function, TArray<FText>& OutValidationErrors)
{

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/Niagara/Private/NiagaraDataInterfaceRigidMeshCollisionQuery.cpp:133

Scope (from outer to inner):

file
namespace    NDIRigidMeshCollisionLocal
function     bool IsMeshDistanceFieldEnabled

Source code excerpt:

bool IsMeshDistanceFieldEnabled()
{
	static const auto* CVarGenerateMeshDistanceFields = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.GenerateMeshDistanceFields"));
	return CVarGenerateMeshDistanceFields != nullptr && CVarGenerateMeshDistanceFields->GetValueOnAnyThread() > 0;
}

//------------------------------------------------------------------------------------------------------------

template<typename BufferType, EPixelFormat PixelFormat>

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/NiagaraEditor/Private/NiagaraValidationRules.cpp:1108

Scope: file

Source code excerpt:

								
								//Add autofix to switch to distance field collisions if possible
								static const auto* CVarGenerateMeshDistanceFields = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.GenerateMeshDistanceFields"));
								if (CVarGenerateMeshDistanceFields != nullptr && CVarGenerateMeshDistanceFields->GetValueOnGameThread() > 0)
								{
									FNiagaraValidationFix& DisableRendererFix = Result.Fixes.AddDefaulted_GetRef();
									DisableRendererFix.Description = LOCTEXT("SwitchCollisionFix", "Change collision type to distance fields");
									TWeakObjectPtr<UNiagaraStackModuleItem> WeakSourceModule = SourceModule;
								

#Loc: <Workspace>/Engine/Source/Editor/GameProjectGeneration/Private/GameProjectUtils.cpp:101

Scope (from outer to inner):

file
namespace    anonymous
function     void AddLumenConfigValues

Source code excerpt:

		ConfigValues.Emplace(TEXT("DefaultEngine.ini"),
			TEXT("/Script/Engine.RendererSettings"),
			TEXT("r.GenerateMeshDistanceFields"),
			TEXT("True"),
			true /* ShouldReplaceExistingValue */);

		// Enable Lumen Global Illumination by default
		ConfigValues.Emplace(TEXT("DefaultEngine.ini"),
			TEXT("/Script/Engine.RendererSettings"),
			TEXT("r.DynamicGlobalIlluminationMethod"),
			TEXT("1"),
			true /* ShouldReplaceExistingValue */);

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxStaticMeshImport.cpp:2319

Scope (from outer to inner):

file
function     void UnFbx::FFbxImporter::PostImportStaticMesh

Source code excerpt:

	}

	static const auto CVarDistanceField = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.GenerateMeshDistanceFields"));
	int32 OriginalCVarDistanceFieldValue = CVarDistanceField->GetValueOnGameThread();
	IConsoleVariable* CVarDistanceFieldInterface = IConsoleManager::Get().FindConsoleVariable(TEXT("r.GenerateMeshDistanceFields"));
	bool bOriginalGenerateMeshDistanceField = StaticMesh->bGenerateMeshDistanceField;
	
	//Prebuild the static mesh when we use LodGroup and we want to modify the LodNumber
	if (!ImportOptions->bImportScene)
	{
		//Set the minimum LOD

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/DirectionalLightComponent.cpp:1117

Scope (from outer to inner):

file
function     bool UDirectionalLightComponent::CanEditChange

Source code excerpt:

			|| PropertyName == GET_MEMBER_NAME_STRING_CHECKED(UDirectionalLightComponent, TraceDistance))
		{
			static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.GenerateMeshDistanceFields"));
			bool bCanEdit = CastShadows && CastDynamicShadows && bUseRayTracedDistanceFieldShadows && Mobility != EComponentMobility::Static && CVar->GetValueOnGameThread() != 0;
			return bCanEdit;
		}

		if (PropertyName == GET_MEMBER_NAME_STRING_CHECKED(UDirectionalLightComponent, OcclusionMaskDarkness)
			|| PropertyName == GET_MEMBER_NAME_STRING_CHECKED(UDirectionalLightComponent, OcclusionDepthRange))

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Components/SkyLightComponent.cpp:599

Scope (from outer to inner):

file
function     bool USkyLightComponent::CanEditChange

Source code excerpt:

			|| FCString::Strcmp(*PropertyName, TEXT("OcclusionTint")) == 0)
		{
			static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.GenerateMeshDistanceFields"));
			return Mobility == EComponentMobility::Movable && CastShadows && CVar->GetValueOnGameThread() != 0;
		}

		if (FCString::Strcmp(*PropertyName, TEXT("CastRaytracedShadow")) == 0)
		{
			return IsRayTracingEnabled();

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/SceneManagement.cpp:52

Scope (from outer to inner):

file
function     bool DoesProjectSupportDistanceFields

Source code excerpt:

bool DoesProjectSupportDistanceFields()
{
	static const auto CVarGenerateDF = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.GenerateMeshDistanceFields"));
	static const auto CVarDFIfNoHWRT = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.DistanceFields.SupportEvenIfHardwareRayTracingSupported"));

	return DoesPlatformSupportDistanceFields(GMaxRHIShaderPlatform)
		&& CVarGenerateDF->GetValueOnAnyThread() != 0
		&& (CVarDFIfNoHWRT->GetValueOnAnyThread() != 0 || !IsRayTracingAllowed());
}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/StaticMesh.cpp:3273

Scope (from outer to inner):

file
function     void FStaticMeshRenderData::Cache

Source code excerpt:

	}

	static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.GenerateMeshDistanceFields"));

	if (CVar->GetValueOnAnyThread(true) != 0 || Owner->bGenerateMeshDistanceField)
	{
		if (LODResources.IsValidIndex(0))
		{
			if (!LODResources[0].DistanceFieldData)

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/StaticMesh.cpp:6191

Scope (from outer to inner):

file
function     void UStaticMesh::BeginPostLoadInternal

Source code excerpt:

	if (GetNumSourceModels() > 0)
	{
		static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.GenerateMeshDistanceFields"));

		if (CVar->GetValueOnAnyThread(true) != 0 || bGenerateMeshDistanceField)
		{
			for (int32 MaterialIndex = 0; MaterialIndex < GetStaticMaterials().Num(); MaterialIndex++)
			{
				UMaterialInterface* MaterialInterface = GetStaticMaterials()[MaterialIndex].MaterialInterface;

#Associated Variable and Callsites

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

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Components/LightComponent.h:223

Scope: file

Source code excerpt:


	/** 
	 * Whether to use ray traced distance field area shadows.  The project setting bGenerateMeshDistanceFields must be enabled for this to have effect.
	 * Distance field shadows support area lights so they create soft shadows with sharp contacts.  
	 * They have less aliasing artifacts than standard shadowmaps, but inherit all the limitations of distance field representations (only uniform scale, no deformation).
	 * These shadows have a low per-object cost (and don't depend on triangle count) so they are effective for distant shadows from a dynamic sun.
	 */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=DistanceFieldShadows, meta=(DisplayName = "Distance Field Shadows"))
	bool bUseRayTracedDistanceFieldShadows;

	/** 
	 * Controls how large of an offset ray traced shadows have from the receiving surface as the camera gets further away.  
	 * This can be useful to hide self-shadowing artifacts from low resolution distance fields on huge static meshes.
	 */

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Engine/RendererSettings.h:563

Scope (from outer to inner):

file
class        class URendererSettings : public UDeveloperSettings

Source code excerpt:

		ToolTip="Whether to build distance fields of static meshes, needed for Software Ray Tracing in Lumen, and distance field AO, which is used to implement Movable SkyLight shadows, and ray traced distance field shadows on directional lights.  Enabling will increase the build times, memory usage and disk size of static meshes.  Changing this setting requires restarting the editor.",
		ConfigRestartRequired=true))
	uint32 bGenerateMeshDistanceFields:1;

	UPROPERTY(config, EditAnywhere, Category=SoftwareRayTracing, meta=(
		EditCondition = "bGenerateMeshDistanceFields",
		ConsoleVariable="r.DistanceFields.DefaultVoxelDensity",
		ClampMin = ".05", ClampMax = ".4",
		ToolTip="Determines how the default scale of a mesh converts into distance field voxel dimensions. Changing this will cause all distance fields to be rebuilt.  Large values can consume memory very quickly!  Changing this setting requires restarting the editor.",

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/RendererSettings.cpp:224

Scope (from outer to inner):

file
function     void URendererSettings::PostEditChangeProperty

Source code excerpt:

			}

			if (!bGenerateMeshDistanceFields)
			{
				FMessageDialog::Open(EAppMsgType::Ok, LOCTEXT("'Generate Mesh Distance Fields' automatically enabled", "Lumen Global Illumination requires 'Generate Mesh Distance Fields'.  This has been enabled automatically, and requires an editor restart."));

				bGenerateMeshDistanceFields = true;

				UpdateDependentPropertyInConfigFile(this, GET_MEMBER_NAME_CHECKED(URendererSettings, bGenerateMeshDistanceFields));
			}
		}

		if (PropertyChangedEvent.Property->GetFName() == GET_MEMBER_NAME_CHECKED(URendererSettings, SubstrateDebugAdvancedVisualizationShaders)
			&& SubstrateDebugAdvancedVisualizationShaders)
		{