MeshBoundsScale

MeshBoundsScale

#Overview

name: MeshBoundsScale

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

It is referenced in 10 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of MeshBoundsScale is to adjust the bounding box of meshes in Unreal Engine 5’s rendering and visibility systems. It is primarily used for scaling the bounds of meshes when calculating precomputed visibility and for rendering purposes in the Niagara particle system.

This setting variable is relied upon by the following Unreal Engine subsystems and modules:

  1. Niagara particle system (FX plugin)
  2. Lightmass (lighting and visibility calculations)
  3. Precomputed Visibility system

The value of this variable is typically set in different contexts:

  1. In Niagara, it’s set through the UNiagaraMeshRendererProperties class.
  2. For Lightmass, it’s read from the Lightmass.ini configuration file.
  3. For precomputed visibility, it’s part of the FPrecomputedVisibilitySettings structure.

MeshBoundsScale interacts with other variables related to mesh bounds, rendering, and visibility calculations. It’s often used in conjunction with the original mesh bounds to create a scaled version of the bounding box.

Developers should be aware that:

  1. Increasing MeshBoundsScale can reduce visibility errors but may result in less effective culling.
  2. It affects performance and accuracy in visibility calculations and particle rendering.
  3. Different subsystems may use this variable independently, so changes in one area may not affect others.

Best practices when using this variable include:

  1. Keep the scale as close to 1.0 as possible while still achieving desired results to maintain optimal performance.
  2. Test thoroughly when adjusting this value, as it can impact both visual quality and performance.
  3. Consider the trade-off between visibility accuracy and culling efficiency when modifying this value.
  4. Document any non-default values used in specific scenarios to aid in future maintenance and optimization efforts.

#Setting Variables

#References In INI files

Location: <Workspace>/Engine/Config/BaseLightmass.ini:112, section: [DevOptions.PrecomputedVisibility]

Location: <Workspace>/Engine/Config/BaseLightmass.ini:120, section: [DevOptions.PrecomputedVisibilityModeratelyAggressive]

Location: <Workspace>/Engine/Config/BaseLightmass.ini:124, section: [DevOptions.PrecomputedVisibilityMostAggressive]

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/Niagara/Private/NiagaraRendererMeshes.cpp:102

Scope (from outer to inner):

file
function     FNiagaraRendererMeshes::FNiagaraRendererMeshes

Source code excerpt:

	SourceMode = Properties->SourceMode;
	FacingMode = Properties->FacingMode;
	MeshBoundsScale = FVector3f(Properties->MeshBoundsScale);
	bLockedAxisEnable = Properties->bLockedAxisEnable;
	LockedAxis = FVector3f(Properties->LockedAxis);
	LockedAxisSpace = Properties->LockedAxisSpace;
	SortMode = Properties->SortMode;
	bSortHighPrecision = UNiagaraRendererProperties::IsSortHighPrecision(Properties->SortPrecision);
	bSortOnlyWhenTranslucent = Properties->bSortOnlyWhenTranslucent;

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/Niagara/Private/NiagaraRendererMeshes.cpp:747

Scope (from outer to inner):

file
function     void FNiagaraRendererMeshes::PreparePerMeshData

Source code excerpt:

{
	// Calculate pivot offset / culling sphere
	const FBox MeshLocalBounds = ScaleFBox(MeshData.RenderableMesh->GetLocalBounds(), MeshData.Scale, MeshBoundsScale);
	ParticleMeshRenderData.CullingSphere.Center = MeshLocalBounds.GetCenter();
	ParticleMeshRenderData.CullingSphere.W = MeshLocalBounds.GetExtent().Length();

	if (MeshData.PivotOffsetSpace == ENiagaraMeshPivotOffsetSpace::Mesh)
	{
		ParticleMeshRenderData.WorldSpacePivotOffset = FVector::ZeroVector;

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/Niagara/Private/NiagaraRendererMeshes.cpp:1141

Scope (from outer to inner):

file
function     void FNiagaraRendererMeshes::SetupElementForGPUScene

Source code excerpt:

		FMemory::Memzero(&GPUSceneRes.GPUWriteParams, sizeof(GPUSceneRes.GPUWriteParams));

		const FBox LocalBounds = ScaleFBox(MeshData.RenderableMesh->GetLocalBounds(), MeshData.Scale, MeshBoundsScale);

		GPUSceneRes.GPUWriteParams.Common 					= CommonParameters;
		GPUSceneRes.GPUWriteParams.ParticleCount 			= NumInstances;
		GPUSceneRes.GPUWriteParams.GPUParticleCountBuffer 	= GetSrvOrDefaultUInt(ComputeDispatchInterface->GetGPUInstanceCounterManager().GetInstanceCountBuffer());
		GPUSceneRes.GPUWriteParams.GPUParticleCountOffset 	= ParticleMeshRenderData.SourceParticleData->GetGPUInstanceCountBufferOffset();
		GPUSceneRes.GPUWriteParams.MeshIndex 				= MeshData.SourceMeshIndex;

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/Niagara/Private/NiagaraRendererMeshes.cpp:1287

Scope (from outer to inner):

file
function     void FNiagaraRendererMeshes::CreateMeshBatchForSection

Source code excerpt:

	MeshBatch.DepthPriorityGroup = (ESceneDepthPriorityGroup)SceneProxy.GetDepthPriorityGroup(&View);

	const FBox LocalBounds = ScaleFBox(MeshData.RenderableMesh->GetLocalBounds(), FVector3f::OneVector, MeshBoundsScale);

	FMeshBatchElement& BatchElement = MeshBatch.Elements[0];
	if (ParticleMeshRenderData.bUseGPUScene)
	{
		BatchElement.PrimitiveUniformBufferResource = SceneProxy.GetCustomUniformBufferResource(RHICmdList, IsMotionBlurEnabled(), LocalBounds);
	}

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/Niagara/Public/NiagaraMeshRendererProperties.h:390

Scope (from outer to inner):

file
class        class UNiagaraMeshRendererProperties : public UNiagaraRendererProperties

Source code excerpt:

	*/
	UPROPERTY(EditAnywhere, Category = "Mesh Rendering", AdvancedDisplay)
	FVector MeshBoundsScale = FVector::OneVector;

	/** Determines how the mesh orients itself relative to the camera. */
	UPROPERTY(EditAnywhere, Category = "Mesh Rendering")
	ENiagaraMeshFacingMode FacingMode = ENiagaraMeshFacingMode::Default;

	/** Specifies what space the locked axis is in */

#Loc: <Workspace>/Engine/Plugins/FX/Niagara/Source/Niagara/Public/NiagaraRendererMeshes.h:193

Scope (from outer to inner):

file
class        class FNiagaraRendererMeshes : public FNiagaraRenderer

Source code excerpt:

	FVector2f SubImageSize = FVector2f::ZeroVector;

	FVector3f MeshBoundsScale = FVector3f::OneVector;

	FVector3f LockedAxis = FVector3f::ZeroVector;
	ENiagaraMeshLockedAxisSpace LockedAxisSpace;

	FVector2f DistanceCullRange = FVector2f::ZeroVector;
	FVector2f DistanceCullRangeSquared = FVector2f::ZeroVector;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Lightmass/Lightmass.cpp:2283

Scope (from outer to inner):

file
function     void FLightmassExporter::WriteSceneSettings

Source code excerpt:

		VERIFYLIGHTMASSINI(GConfig->GetInt(TEXT("DevOptions.PrecomputedVisibility"), TEXT("NumCellDistributionBuckets"), Scene.PrecomputedVisibilitySettings.NumCellDistributionBuckets, GLightmassIni));
		VERIFYLIGHTMASSINI(GConfig->GetFloat(TEXT("DevOptions.PrecomputedVisibility"), TEXT("PlayAreaHeight"), Scene.PrecomputedVisibilitySettings.PlayAreaHeight, GLightmassIni));
		VERIFYLIGHTMASSINI(GConfig->GetFloat(TEXT("DevOptions.PrecomputedVisibility"), TEXT("MeshBoundsScale"), Scene.PrecomputedVisibilitySettings.MeshBoundsScale, GLightmassIni));
		VERIFYLIGHTMASSINI(GConfig->GetInt(TEXT("DevOptions.PrecomputedVisibility"), TEXT("MinMeshSamples"), Scene.PrecomputedVisibilitySettings.MinMeshSamples, GLightmassIni));
		VERIFYLIGHTMASSINI(GConfig->GetInt(TEXT("DevOptions.PrecomputedVisibility"), TEXT("MaxMeshSamples"), Scene.PrecomputedVisibilitySettings.MaxMeshSamples, GLightmassIni));
		VERIFYLIGHTMASSINI(GConfig->GetInt(TEXT("DevOptions.PrecomputedVisibility"), TEXT("NumCellSamples"), Scene.PrecomputedVisibilitySettings.NumCellSamples, GLightmassIni));
		VERIFYLIGHTMASSINI(GConfig->GetInt(TEXT("DevOptions.PrecomputedVisibility"), TEXT("NumImportanceSamples"), Scene.PrecomputedVisibilitySettings.NumImportanceSamples, GLightmassIni));
	}
	if (World->GetWorldSettings()->VisibilityAggressiveness != VIS_LeastAggressive)

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Lightmass/Lightmass.cpp:2296

Scope (from outer to inner):

file
function     void FLightmassExporter::WriteSceneSettings

Source code excerpt:

			TEXT("DevOptions.PrecomputedVisibilityMostAggressive")};
		const TCHAR* ActiveSection = AggressivenessSectionNames[FMath::Clamp((int32)World->GetWorldSettings()->VisibilityAggressiveness, 0, VIS_Max - 1)];
		VERIFYLIGHTMASSINI(GConfig->GetFloat(ActiveSection, TEXT("MeshBoundsScale"), Scene.PrecomputedVisibilitySettings.MeshBoundsScale, GLightmassIni));
	}
	{
		VERIFYLIGHTMASSINI(GConfig->GetFloat(TEXT("DevOptions.VolumeDistanceField"), TEXT("VoxelSize"), Scene.VolumeDistanceFieldSettings.VoxelSize, GLightmassIni));
		VERIFYLIGHTMASSINI(GConfig->GetFloat(TEXT("DevOptions.VolumeDistanceField"), TEXT("VolumeMaxDistance"), Scene.VolumeDistanceFieldSettings.VolumeMaxDistance, GLightmassIni));
		VERIFYLIGHTMASSINI(GConfig->GetInt(TEXT("DevOptions.VolumeDistanceField"), TEXT("NumVoxelDistanceSamples"), Scene.VolumeDistanceFieldSettings.NumVoxelDistanceSamples, GLightmassIni));
		VERIFYLIGHTMASSINI(GConfig->GetInt(TEXT("DevOptions.VolumeDistanceField"), TEXT("MaxVoxels"), Scene.VolumeDistanceFieldSettings.MaxVoxels, GLightmassIni));

#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/Lighting/PrecomputedVisibility.cpp:1141

Scope (from outer to inner):

file
namespace    Lightmass
function     void FStaticLightingSystem::CalculatePrecomputedVisibility

Source code excerpt:


			const FBox3f MeshBox(
				OriginalMeshBounds.GetCenter() - OriginalMeshBounds.GetExtent() * PrecomputedVisibilitySettings.MeshBoundsScale,
				OriginalMeshBounds.GetCenter() + OriginalMeshBounds.GetExtent() * PrecomputedVisibilitySettings.MeshBoundsScale);

			const bool bDebugThisMesh = VisibilityMeshIndex == Scene.DebugInput.DebugVisibilityId && bDebugThisCell;

			if (bDebugThisMesh)
			{
				AddMeshDebugLines(DataLink->Element.DebugVisibilityRays, VisibilityMesh.Meshes, MeshBox);

#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Public/SceneExport.h:400

Scope (from outer to inner):

file
namespace    Lightmass
class        class FPrecomputedVisibilitySettings

Source code excerpt:


	/** Amount to increase the bounds of meshes when querying their visibility.  Larger scales reduce visibility errors at the cost of less effective culling. */
	float MeshBoundsScale;

	/** Minimum number of samples on the mesh for each cell - mesh query.  Small meshes use less samples. */
	int32 MinMeshSamples;

	/** Maximum number of samples on the mesh for each cell - mesh query.  Small meshes use less samples. */
	int32 MaxMeshSamples;