NumHemisphereSamplesScale

NumHemisphereSamplesScale

#Overview

name: NumHemisphereSamplesScale

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

It is referenced in 5 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of NumHemisphereSamplesScale is to control the number of hemisphere samples used for lighting volume samples in Unreal Engine 5’s lighting system, specifically for precomputed dynamic object lighting.

This setting variable is primarily used in the Lightmass subsystem, which is responsible for precomputed lighting calculations in Unreal Engine. It is part of the FDynamicObjectSettings structure, which suggests it’s specifically tailored for dynamic object lighting.

The value of this variable is set in the Lightmass configuration file (GLightmassIni). It is read from the “DevOptions.PrecomputedDynamicObjectLighting” section of this configuration file.

NumHemisphereSamplesScale interacts with ImportanceTracingSettings.NumHemisphereSamples. The product of these two values determines the actual number of hemisphere samples used for volume lighting calculations.

Developers should be aware that increasing this value will result in more accurate lighting calculations for dynamic objects, but at the cost of increased computation time and memory usage. It’s a trade-off between quality and performance.

Best practices when using this variable include:

  1. Adjust it based on the specific needs of your project. Higher values for more detailed lighting, lower values for better performance.
  2. Test different values to find the optimal balance between lighting quality and performance for your specific scene.
  3. Consider using different values for different quality settings in your game, allowing players to adjust based on their hardware capabilities.
  4. Be mindful of its impact on build times and runtime performance, especially for large scenes or scenes with many dynamic objects.

#Setting Variables

#References In INI files

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

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

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

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

#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:2255

Scope (from outer to inner):

file
function     void FLightmassExporter::WriteSceneSettings

Source code excerpt:

		VERIFYLIGHTMASSINI(GConfig->GetBool(TEXT("DevOptions.PrecomputedDynamicObjectLighting"), TEXT("bVisualizeVolumeLightInterpolation"), bConfigBool, GLightmassIni));
		Scene.DynamicObjectSettings.bVisualizeVolumeLightInterpolation = bConfigBool;
		VERIFYLIGHTMASSINI(GConfig->GetFloat(TEXT("DevOptions.PrecomputedDynamicObjectLighting"), TEXT("NumHemisphereSamplesScale"), Scene.DynamicObjectSettings.NumHemisphereSamplesScale, GLightmassIni));
		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));

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

Scope (from outer to inner):

file
function     void FLightmassExporter::WriteSceneSettings

Source code excerpt:

		VERIFYLIGHTMASSINI(GConfig->GetInt(QualitySectionNames[QualityLevel], TEXT("MinDistanceFieldUpsampleFactor"), Scene.ShadowSettings.MinDistanceFieldUpsampleFactor, GLightmassIni));

		float NumHemisphereSamplesScale;
		VERIFYLIGHTMASSINI(GConfig->GetFloat(QualitySectionNames[QualityLevel], TEXT("NumHemisphereSamplesScale"), NumHemisphereSamplesScale, GLightmassIni));
		Scene.ImportanceTracingSettings.NumHemisphereSamples = FMath::TruncToInt(Scene.ImportanceTracingSettings.NumHemisphereSamples * NumHemisphereSamplesScale);

		float NumImportanceSearchPhotonsScale;
		VERIFYLIGHTMASSINI(GConfig->GetFloat(QualitySectionNames[QualityLevel], TEXT("NumImportanceSearchPhotonsScale"), NumImportanceSearchPhotonsScale, GLightmassIni));
		Scene.PhotonMappingSettings.NumImportanceSearchPhotons = FMath::TruncToInt(Scene.PhotonMappingSettings.NumImportanceSearchPhotons * NumImportanceSearchPhotonsScale);

		float NumDirectPhotonsScale;

#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/Lighting/LightingSystem.cpp:1430

Scope (from outer to inner):

file
namespace    Lightmass
function     void FStaticLightingSystem::ValidateSettings
function     void FStaticLightingSystem::CacheSamples

Source code excerpt:


	{
		const int32 NumUpperVolumeSamples = ImportanceTracingSettings.NumHemisphereSamples * DynamicObjectSettings.NumHemisphereSamplesScale;
		const float NumThetaStepsFloat = FMath::Sqrt(NumUpperVolumeSamples / (float)PI);
		const int32 NumThetaSteps = FMath::TruncToInt(NumThetaStepsFloat);
		const int32 NumPhiSteps = FMath::TruncToInt(NumThetaStepsFloat * (float)PI);

		GenerateStratifiedUniformHemisphereSamples(NumThetaSteps, NumPhiSteps, RandomStream, CachedVolumetricLightmapUniformHemisphereSamples, CachedVolumetricLightmapUniformHemisphereSampleUniforms);

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

Scope (from outer to inner):

file
namespace    Lightmass
function     void FStaticLightingSystem::ProcessVolumeSamplesTask

Source code excerpt:

	TArray<FVector4f> UniformHemisphereSamples;
	TArray<FVector2f> UniformHemisphereSampleUniforms;
	const int32 NumUpperVolumeSamples = ImportanceTracingSettings.NumHemisphereSamples * DynamicObjectSettings.NumHemisphereSamplesScale;
	// Volume samples don't do any importance sampling so they need more samples for the same amount of variance as surface samples
	const float NumThetaStepsFloat = FMath::Sqrt(NumUpperVolumeSamples / (float)PI);
	const int32 NumThetaSteps = FMath::TruncToInt(NumThetaStepsFloat);
	const int32 NumPhiSteps = FMath::TruncToInt(NumThetaStepsFloat * (float)PI);

	GenerateStratifiedUniformHemisphereSamples(NumThetaSteps, NumPhiSteps, RandomStream, UniformHemisphereSamples, UniformHemisphereSampleUniforms);

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

Scope (from outer to inner):

file
namespace    Lightmass
class        class FDynamicObjectSettings

Source code excerpt:


	/** Scales the number of hemisphere samples that should be used for lighting volume samples. */
	float NumHemisphereSamplesScale;
	/** World space distance between samples placed on upward facing surfaces. */
	float SurfaceLightSampleSpacing;
	/** Height of the first sample layer above the surface. */
	float FirstSurfaceSampleLayerHeight;
	/** Height difference of successive layers. */
	float SurfaceSampleLayerHeightSpacing;