foliage.MaxEndCullDistance

foliage.MaxEndCullDistance

#Overview

name: foliage.MaxEndCullDistance

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

It is referenced in 4 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of foliage.MaxEndCullDistance is to control the maximum distance at which foliage instances are culled from rendering in Unreal Engine 5. This setting is primarily used in the rendering system, specifically for optimizing the rendering of hierarchical instanced static meshes, which are commonly used for foliage in game environments.

This setting variable is primarily relied upon by the Engine module, particularly within the HierarchicalInstancedStaticMesh component. It is used in the rendering pipeline to determine when to stop rendering foliage instances that are far away from the camera.

The value of this variable is set through a console variable (CVarFoliageMaxEndCullDistance) in the engine’s C++ code. It is initialized with a default value of 0, which means the feature is disabled by default.

The associated variable CVarFoliageMaxEndCullDistance interacts directly with foliage.MaxEndCullDistance. They share the same value and are used interchangeably in the code.

Developers must be aware that:

  1. Setting this value to 0 disables the end culling feature.
  2. This setting can significantly impact performance and visual quality, especially in scenes with large amounts of foliage.
  3. The actual culling distance is also influenced by other factors like the view distance scale and LOD settings.

Best practices when using this variable include:

  1. Carefully balancing between performance and visual quality. Higher values will render more distant foliage but may impact performance.
  2. Testing different values in various scenarios to find the optimal setting for your specific game environment.
  3. Considering this setting in conjunction with other LOD and culling settings for a comprehensive optimization strategy.

Regarding the associated variable CVarFoliageMaxEndCullDistance:

Developers should be aware that modifying CVarFoliageMaxEndCullDistance at runtime will directly affect the foliage rendering behavior, potentially causing visible changes in the game’s visual appearance.

#References in C++ code

#Callsites

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

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

Scope: file

Source code excerpt:


TAutoConsoleVariable<int32> CVarFoliageMaxEndCullDistance(
	TEXT("foliage.MaxEndCullDistance"),
	0,
	TEXT("Max distance for end culling (0 disabled)."));

TAutoConsoleVariable<float> CVarFoliageLODDistanceScale(
	TEXT("foliage.LODDistanceScale"),
	1.0f,

#Associated Variable and Callsites

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

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

Scope: file

Source code excerpt:

	ECVF_Scalability);

TAutoConsoleVariable<int32> CVarFoliageMaxEndCullDistance(
	TEXT("foliage.MaxEndCullDistance"),
	0,
	TEXT("Max distance for end culling (0 disabled)."));

TAutoConsoleVariable<float> CVarFoliageLODDistanceScale(
	TEXT("foliage.LODDistanceScale"),

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/HierarchicalInstancedStaticMesh.cpp:1629

Scope (from outer to inner):

file
function     void FHierarchicalStaticMeshSceneProxy::GetDynamicMeshElements

Source code excerpt:

				float MinSize = bIsOrtho ? 0.0f : CVarFoliageMinimumScreenSize.GetValueOnRenderThread();
				float LODScale = UserData_AllInstances.LODDistanceScale;
				int MaxEndCullDistance = CVarFoliageMaxEndCullDistance.GetValueOnRenderThread();
				float LODRandom = CVarRandomLODRange.GetValueOnRenderThread();
				float MaxDrawDistanceScale = GetCachedScalabilityCVars().ViewDistanceScale;
								
				FVector AverageScale(InstanceParams.Tree[0].MinInstanceScale + (InstanceParams.Tree[0].MaxInstanceScale - InstanceParams.Tree[0].MinInstanceScale) / 2.0f);
				FBoxSphereBounds ScaledBounds = RenderData->Bounds.TransformBy(FTransform(FRotator::ZeroRotator, FVector::ZeroVector, AverageScale));
				float SphereRadius = ScaledBounds.SphereRadius + InstanceParams.MaxWPODisplacement;

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/HierarchicalInstancedStaticMesh.cpp:1843

Scope (from outer to inner):

file
function     void FHierarchicalStaticMeshSceneProxy::GetDynamicMeshElements

Source code excerpt:

						const float MinSize = bIsOrtho ? 0.0f : CVarFoliageMinimumScreenSize.GetValueOnRenderThread();
						const float LODScale = UserData_AllInstances.LODDistanceScale;
						int MaxEndCullDistance = CVarFoliageMaxEndCullDistance.GetValueOnRenderThread();
						const float LODRandom = CVarRandomLODRange.GetValueOnRenderThread();
						const float MaxDrawDistanceScale = GetCachedScalabilityCVars().ViewDistanceScale;
						const float SphereRadius = RenderData->Bounds.SphereRadius + GetMaxWorldPositionOffsetExtent();

						checkSlow(NumLODs > 0);