SurfaceSampleLayerHeightSpacing

SurfaceSampleLayerHeightSpacing

#Overview

name: SurfaceSampleLayerHeightSpacing

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 5 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of SurfaceSampleLayerHeightSpacing is to control the vertical spacing between successive layers of surface samples in Unreal Engine’s dynamic object lighting system. This setting is part of the precomputed dynamic object lighting configuration, which is used to generate lighting data for movable objects in the scene.

This setting variable is primarily used by the Lightmass subsystem, which is responsible for global illumination and precomputed lighting in Unreal Engine. It is specifically utilized in the dynamic object lighting calculations.

The value of this variable is typically set in the Lightmass configuration file (GLightmassIni). It is read from the config file in the FLightmassExporter::WriteSceneSettings function and stored in the Scene.DynamicObjectSettings structure.

SurfaceSampleLayerHeightSpacing interacts with other related variables such as FirstSurfaceSampleLayerHeight and NumSurfaceSampleLayers. Together, these variables define the vertical distribution of surface samples used for dynamic object lighting calculations.

Developers should be aware that this variable directly affects the density and distribution of lighting samples in the vertical direction above surfaces. A smaller value will result in more closely spaced layers, potentially providing more detailed lighting information at the cost of increased computation time and memory usage.

Best practices when using this variable include:

  1. Balancing the value with performance considerations. Smaller values provide more detail but increase computation requirements.
  2. Considering the scale of your scene when setting this value. Larger scenes may require larger spacing to maintain reasonable performance.
  3. Adjusting this value in conjunction with related settings like FirstSurfaceSampleLayerHeight and NumSurfaceSampleLayers for optimal results.
  4. Testing different values to find the best balance between lighting quality and performance for your specific project.
  5. Be aware that this value is scaled by the StaticLightingLevelScale, so consider this when setting the value or adjusting the overall lighting scale of your scene.

#Setting Variables

#References In INI files

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

#References in C++ code

#Callsites

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

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

Scope (from outer to inner):

file
function     void FLightmassExporter::WriteSceneSettings

Source code excerpt:

		VERIFYLIGHTMASSINI(GConfig->GetFloat(TEXT("DevOptions.PrecomputedDynamicObjectLighting"), TEXT("SurfaceLightSampleSpacing"), Scene.DynamicObjectSettings.SurfaceLightSampleSpacing, GLightmassIni));
		VERIFYLIGHTMASSINI(GConfig->GetFloat(TEXT("DevOptions.PrecomputedDynamicObjectLighting"), TEXT("FirstSurfaceSampleLayerHeight"), Scene.DynamicObjectSettings.FirstSurfaceSampleLayerHeight, GLightmassIni));
		VERIFYLIGHTMASSINI(GConfig->GetFloat(TEXT("DevOptions.PrecomputedDynamicObjectLighting"), TEXT("SurfaceSampleLayerHeightSpacing"), Scene.DynamicObjectSettings.SurfaceSampleLayerHeightSpacing, GLightmassIni));
		VERIFYLIGHTMASSINI(GConfig->GetInt(TEXT("DevOptions.PrecomputedDynamicObjectLighting"), TEXT("NumSurfaceSampleLayers"), Scene.DynamicObjectSettings.NumSurfaceSampleLayers, GLightmassIni));
		VERIFYLIGHTMASSINI(GConfig->GetFloat(TEXT("DevOptions.PrecomputedDynamicObjectLighting"), TEXT("DetailVolumeSampleSpacing"), Scene.DynamicObjectSettings.DetailVolumeSampleSpacing, GLightmassIni));
		VERIFYLIGHTMASSINI(GConfig->GetFloat(TEXT("DevOptions.PrecomputedDynamicObjectLighting"), TEXT("VolumeLightSampleSpacing"), Scene.DynamicObjectSettings.VolumeLightSampleSpacing, GLightmassIni));
		VERIFYLIGHTMASSINI(GConfig->GetInt(TEXT("DevOptions.PrecomputedDynamicObjectLighting"), TEXT("MaxVolumeSamples"), Scene.DynamicObjectSettings.MaxVolumeSamples, GLightmassIni));
		VERIFYLIGHTMASSINI(GConfig->GetBool(TEXT("DevOptions.PrecomputedDynamicObjectLighting"), TEXT("bUseMaxSurfaceSampleNum"), bConfigBool, GLightmassIni));
		Scene.DynamicObjectSettings.bUseMaxSurfaceSampleNum = bConfigBool;

#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/ImportExport/LightmassScene.cpp:518

Scope (from outer to inner):

file
namespace    Lightmass
function     void FScene::ApplyStaticLightingScale

Source code excerpt:

	DynamicObjectSettings.FirstSurfaceSampleLayerHeight *= SceneConstants.StaticLightingLevelScale;
	DynamicObjectSettings.SurfaceLightSampleSpacing *= SceneConstants.StaticLightingLevelScale;
	DynamicObjectSettings.SurfaceSampleLayerHeightSpacing *= SceneConstants.StaticLightingLevelScale;
	DynamicObjectSettings.DetailVolumeSampleSpacing *= SceneConstants.StaticLightingLevelScale;
	DynamicObjectSettings.VolumeLightSampleSpacing *= SceneConstants.StaticLightingLevelScale;
	VolumeDistanceFieldSettings.VoxelSize *= SceneConstants.StaticLightingLevelScale;
	VolumeDistanceFieldSettings.VolumeMaxDistance *= SceneConstants.StaticLightingLevelScale;
	ShadowSettings.MaxTransitionDistanceWorldSpace *= SceneConstants.StaticLightingLevelScale;
	ShadowSettings.StaticShadowDepthMapTransitionSampleDistanceX *= SceneConstants.StaticLightingLevelScale;

#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/Lighting/SampleVolume.cpp:121

Scope (from outer to inner):

file
namespace    Lightmass
class        class FVolumeSamplePlacementRasterPolicy
function     FVolumeSamplePlacementRasterPolicy

Source code excerpt:

		for (int32 i = 1; i < System.DynamicObjectSettings.NumSurfaceSampleLayers; i++)
		{
			LayerHeightOffsets.Add(System.DynamicObjectSettings.FirstSurfaceSampleLayerHeight + i * System.DynamicObjectSettings.SurfaceSampleLayerHeightSpacing);
		}

		
		TArray<FVector2f> UniformHemisphereSampleUniforms;
		const int32 NumUpperVolumeSamples = 16;
		const float NumThetaStepsFloat = FMath::Sqrt(NumUpperVolumeSamples / (float)PI);

#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/Lighting/SampleVolume.cpp:293

Scope (from outer to inner):

file
namespace    Lightmass
function     void FStaticLightingSystem::BeginCalculateVolumeSamples

Source code excerpt:

		const float DiagonalRadius = DynamicObjectSettings.SurfaceLightSampleSpacing * FMath::Sqrt(2.0f);
		// Make sure the space between layers is covered
		const float SampleRadius = FMath::Max(DiagonalRadius, DynamicObjectSettings.SurfaceSampleLayerHeightSpacing * FMath::Sqrt(2.0f));

		FTriangleRasterizer<FVolumeSamplePlacementRasterPolicy> Rasterizer(
			FVolumeSamplePlacementRasterPolicy(
			RasterSizeX, 
			RasterSizeY, 
			// Use a minimum sample distance slightly less than the SurfaceLightSampleSpacing
			0.9f * FMath::Min(DynamicObjectSettings.SurfaceLightSampleSpacing, DynamicObjectSettings.SurfaceSampleLayerHeightSpacing), 
			FBoxSphereBounds3f(AggregateMesh->GetBounds()).SphereRadius,
			SampleRadius,
			*this,
			MappingContext.RayCache,
			VolumeLightingOctree));

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

Scope (from outer to inner):

file
namespace    Lightmass
class        class FDynamicObjectSettings

Source code excerpt:

	float FirstSurfaceSampleLayerHeight;
	/** Height difference of successive layers. */
	float SurfaceSampleLayerHeightSpacing;
	/** Number of layers to place above surfaces. */
	int32 NumSurfaceSampleLayers;
	/** Distance between samples placed in a 3d uniform grid inside detail volumes. */ 
	float DetailVolumeSampleSpacing;
	/** Distance between samples placed in a 3d uniform grid inside the importance volume. */
	float VolumeLightSampleSpacing;