MaxVoxels

MaxVoxels

#Overview

name: MaxVoxels

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

It is referenced in 6 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of MaxVoxels is to control the maximum number of voxels used in various calculations and data structures within Unreal Engine 5, particularly in the context of mesh processing, distance field generation, and lighting calculations.

This setting variable is primarily used by the MeshUtilities module and the Lightmass system, which are part of Unreal Engine’s rendering and lighting subsystems. Specifically, it’s used in mesh card representation generation, surfel scene initialization, and volume distance field calculations.

The value of MaxVoxels is typically set in configuration files or passed as a parameter to functions that require it. In the Lightmass exporter, it’s read from the “DevOptions.VolumeDistanceField” section of the Lightmass configuration file.

MaxVoxels interacts with other variables such as VoxelSize, MeshCardsBounds, and various dimensions (SizeInVoxels, VolumeSizeX/Y/Z) to determine the resolution and extent of voxel-based representations.

Developers should be aware that:

  1. MaxVoxels acts as an upper limit to prevent excessive memory usage and computation time.
  2. It directly affects the level of detail in voxel-based representations, which can impact rendering quality and performance.
  3. Changing MaxVoxels may require adjustments to other related parameters to maintain the desired balance between quality and performance.

Best practices when using this variable include:

  1. Carefully consider the trade-off between detail and performance when setting MaxVoxels.
  2. Monitor memory usage and generation times when adjusting this value.
  3. Test different MaxVoxels values to find the optimal setting for your specific use case.
  4. Be prepared to adjust related parameters (like VoxelSize) when changing MaxVoxels to maintain consistent results.
  5. Consider scaling MaxVoxels based on the target hardware capabilities and the complexity of your scenes.

#Setting Variables

#References In INI files

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

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Source/Developer/MeshUtilities/Private/MeshCardRepresentationUtilities.cpp:554

Scope (from outer to inner):

file
function     void InitClusteringParams

Source code excerpt:

}

void InitClusteringParams(FClusteringParams& ClusteringParams, const FBox& MeshCardsBounds, int32 MaxVoxels, int32 MaxLumenMeshCards)
{
	const float TargetVoxelSize = 10.0f;

	const FVector3f MeshCardsBoundsSize = 2.0f * (FVector3f)MeshCardsBounds.GetExtent();
	const float MaxMeshCardsBounds = MeshCardsBoundsSize.GetMax();

	// Target object space detail size
	const float MaxSizeInVoxels = FMath::Clamp(MaxMeshCardsBounds / TargetVoxelSize + 0.5f, 1, MaxVoxels);
	const float VoxelSize = FMath::Max(TargetVoxelSize, MaxMeshCardsBounds / MaxSizeInVoxels);

	FIntVector SizeInVoxels;
	SizeInVoxels.X = FMath::Clamp(FMath::RoundToFloat(MeshCardsBoundsSize.X / VoxelSize), 1, MaxVoxels);
	SizeInVoxels.Y = FMath::Clamp(FMath::RoundToFloat(MeshCardsBoundsSize.Y / VoxelSize), 1, MaxVoxels);
	SizeInVoxels.Z = FMath::Clamp(FMath::RoundToFloat(MeshCardsBoundsSize.Z / VoxelSize), 1, MaxVoxels);

	const FVector3f VoxelBoundsCenter = (FVector3f)MeshCardsBounds.GetCenter();
	const FVector3f VoxelBoundsExtent = FVector3f(SizeInVoxels) * VoxelSize * 0.5f;
	const FVector3f VoxelBoundsMin = VoxelBoundsCenter - VoxelBoundsExtent;
	const FVector3f VoxelBoundsMax = VoxelBoundsCenter + VoxelBoundsExtent;

#Loc: <Workspace>/Engine/Source/Developer/MeshUtilities/Private/MeshCardRepresentationUtilities.cpp:674

Scope (from outer to inner):

file
function     void InitSurfelScene

Source code excerpt:

	// Limit max number of surfels to prevent generation time from exploding, as dense two sided meshes can generate many more surfels than simple walls
	int32 TargetNumSufels = 10000;
	float MaxVoxels = 64;

	do
	{
		InitClusteringParams(ClusteringParams, MeshCardsBounds, MaxVoxels, MaxLumenMeshCards);

		ParallelFor(TEXT("InitSurfelScene.PF"), MeshCardGen::NumAxisAlignedDirections, 1,
			[&](int32 AxisAlignedDirectionIndex)
			{
				if (DebugSurfelDirection < 0 || DebugSurfelDirection == AxisAlignedDirectionIndex)
				{

#Loc: <Workspace>/Engine/Source/Developer/MeshUtilities/Private/MeshCardRepresentationUtilities.cpp:704

Scope (from outer to inner):

file
function     void InitSurfelScene

Source code excerpt:

		}

		MaxVoxels = MaxVoxels / 2;
	} while (SurfelScene.NumSurfels > TargetNumSufels && MaxVoxels > 1);

	if (ClusteringParams.bDebug)
	{
		for (int32 AxisAlignedDirectionIndex = 0; AxisAlignedDirectionIndex < MeshCardGen::NumAxisAlignedDirections; ++AxisAlignedDirectionIndex)
		{
			FLumenCardBuildDebugData& MergedDebugData = Context.OutData.MeshCardsBuildData.DebugData;

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

Scope (from outer to inner):

file
function     void FLightmassExporter::WriteSceneSettings

Source code excerpt:

		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));
	}
	{
		VERIFYLIGHTMASSINI(GConfig->GetBool(TEXT("DevOptions.StaticShadows"), TEXT("bUseZeroAreaLightmapSpaceFilteredLights"), bConfigBool, GLightmassIni));
		Scene.ShadowSettings.bUseZeroAreaLightmapSpaceFilteredLights = bConfigBool;
		VERIFYLIGHTMASSINI(GConfig->GetInt(TEXT("DevOptions.StaticShadows"), TEXT("NumShadowRays"), Scene.ShadowSettings.NumShadowRays, GLightmassIni));
		VERIFYLIGHTMASSINI(GConfig->GetInt(TEXT("DevOptions.StaticShadows"), TEXT("NumPenumbraShadowRays"), Scene.ShadowSettings.NumPenumbraShadowRays, GLightmassIni));

#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/Lighting/VolumeDistanceField.cpp:33

Scope (from outer to inner):

file
namespace    Lightmass
function     void FStaticLightingSystem::BeginCalculateVolumeDistanceField

Source code excerpt:

	const float NumVoxels = VolumeSizeX * VolumeSizeY * VolumeSizeZ;

	if (NumVoxels > VolumeDistanceFieldSettings.MaxVoxels)
	{
		const int32 OldSizeX = VolumeSizeX;
		const int32 OldSizeY = VolumeSizeY;
		const int32 OldSizeZ = VolumeSizeZ;
		const float SingleDimensionScale = FMath::Pow(NumVoxels / VolumeDistanceFieldSettings.MaxVoxels, 1.0f / 3.0f);
		DistanceFieldVoxelSize = VolumeDistanceFieldSettings.VoxelSize * SingleDimensionScale;

		DoubleExtent = DistanceFieldVolumeBounds.GetExtent() * 2;
		DoubleExtent.X = DoubleExtent.X - FMath::Fmod(DoubleExtent.X, (FVector4f::FReal)DistanceFieldVoxelSize) + DistanceFieldVoxelSize;
		DoubleExtent.Y = DoubleExtent.Y - FMath::Fmod(DoubleExtent.Y, (FVector4f::FReal)DistanceFieldVoxelSize) + DistanceFieldVoxelSize;
		DoubleExtent.Z = DoubleExtent.Z - FMath::Fmod(DoubleExtent.Z, (FVector4f::FReal)DistanceFieldVoxelSize) + DistanceFieldVoxelSize;

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

Scope (from outer to inner):

file
namespace    Lightmass
class        class FVolumeDistanceFieldSettings

Source code excerpt:


	/** Upper limit on the number of voxels that can be generated. */
	int32 MaxVoxels;
};

/** Shadow settings */
class FStaticShadowSettings
{
public: