foliage.MinimumScreenSize

foliage.MinimumScreenSize

#Overview

name: foliage.MinimumScreenSize

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

It is referenced in 6 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of foliage.MinimumScreenSize is to control the screen size threshold at which foliage instances are culled entirely. This setting is part of the rendering system, specifically for optimizing the rendering of foliage in Unreal Engine 5.

This setting variable is primarily used in the Engine module, particularly in the rendering of instanced static meshes and hierarchical instanced static meshes. It’s a crucial part of the foliage rendering optimization system.

The value of this variable is set using a console variable (CVar) system. It’s initialized with a default value of 0.000005f, but can be changed at runtime through console commands or configuration files.

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

Developers must be aware that this variable affects performance and visual quality. Setting it too high might cause foliage to disappear too early, while setting it too low might impact performance by rendering very small foliage instances.

Best practices when using this variable include:

  1. Adjusting it based on the specific needs of your project and target hardware.
  2. Testing different values to find the right balance between performance and visual quality.
  3. Considering it in conjunction with other foliage-related settings like LOD distance scales.

Regarding the associated variable CVarFoliageMinimumScreenSize:

#References in C++ code

#Callsites

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

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

Scope: file

Source code excerpt:


TAutoConsoleVariable<float> CVarFoliageMinimumScreenSize(
	TEXT("foliage.MinimumScreenSize"),
	0.000005f,
	TEXT("This controls the screen size at which we cull foliage instances entirely."),
	ECVF_Scalability);

TAutoConsoleVariable<int32> CVarFoliageMaxEndCullDistance(
	TEXT("foliage.MaxEndCullDistance"),

#Associated Variable and Callsites

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

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Engine/InstancedStaticMesh.h:35

Scope: file

Source code excerpt:

struct FInstancedStaticMeshSceneProxyDesc;

extern TAutoConsoleVariable<float> CVarFoliageMinimumScreenSize;
extern TAutoConsoleVariable<float> CVarRandomLODRange;
extern TAutoConsoleVariable<int32> CVarMinLOD;

BEGIN_GLOBAL_SHADER_PARAMETER_STRUCT(FInstancedStaticMeshVertexFactoryUniformShaderParameters, ENGINE_API)
	SHADER_PARAMETER_SRV(Buffer<float4>, VertexFetch_InstanceOriginBuffer)
	SHADER_PARAMETER_SRV(Buffer<float4>, VertexFetch_InstanceTransformBuffer)

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

Scope: file

Source code excerpt:

	TEXT("This is an absolute limit on the number of foliage triangles to render in one traversal. This is used to prevent a silly LOD parameter mistake from causing the OS to kill the GPU."));

TAutoConsoleVariable<float> CVarFoliageMinimumScreenSize(
	TEXT("foliage.MinimumScreenSize"),
	0.000005f,
	TEXT("This controls the screen size at which we cull foliage instances entirely."),
	ECVF_Scalability);

TAutoConsoleVariable<int32> CVarFoliageMaxEndCullDistance(

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

Scope (from outer to inner):

file
function     void FHierarchicalStaticMeshSceneProxy::GetDynamicMeshElements

Source code excerpt:

				InstanceParams.MaxWPODisplacement = GetMaxWorldPositionOffsetExtent();

				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);

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

Scope (from outer to inner):

file
function     void FHierarchicalStaticMeshSceneProxy::GetDynamicMeshElements

Source code excerpt:


						const bool bIsOrtho = !View->ViewMatrices.IsPerspectiveProjection();
						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();

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/InstancedStaticMesh.cpp:1160

Scope (from outer to inner):

file
function     FInstancedStaticMeshVFLooseUniformShaderParametersRef FInstancedStaticMeshSceneProxy::CreateLooseUniformBuffer

Source code excerpt:

			FBoxSphereBounds ScaledBounds = InstancingUserData->MeshRenderData->Bounds.TransformBy(FTransform(FRotator::ZeroRotator, FVector::ZeroVector, InstancingUserData->AverageInstancesScale));
			float SphereRadius = ScaledBounds.SphereRadius;
			float MinSize = View->ViewMatrices.IsPerspectiveProjection() ? CVarFoliageMinimumScreenSize.GetValueOnRenderThread() : 0.0f;
			float LODScale = InstancingUserData->LODDistanceScale;
			float LODRandom = CVarRandomLODRange.GetValueOnRenderThread();
			float MaxDrawDistanceScale = GetCachedScalabilityCVars().ViewDistanceScale;

			if (InstancedLODIndex)
			{