IndirectPhotonPathDensity
IndirectPhotonPathDensity
#Overview
name: IndirectPhotonPathDensity
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 IndirectPhotonPathDensity is to control the density of indirect photon paths in the photon mapping process for global illumination calculations in Unreal Engine’s lighting system.
This setting variable is primarily used by the lighting and rendering subsystems of Unreal Engine, specifically within the Lightmass module, which handles global illumination calculations.
The value of this variable is set in the Lightmass configuration file (GLightmassIni) under the “DevOptions.PhotonMapping” section. It is read during the scene export process for Lightmass calculations.
IndirectPhotonPathDensity interacts with several other variables:
- NumIndirectPhotonPathsScale: Used to scale the IndirectPhotonPathDensity value based on quality settings.
- OutsideImportanceVolumeDensityScale: Used to adjust the density outside the importance volume.
- StaticLightingLevelScale: Used to scale the density based on the level’s static lighting scale.
Developers should be aware that:
- This variable directly affects the number of indirect photon paths generated, which impacts both lighting quality and computation time.
- The actual number of photon paths is capped at a maximum value (20,000 in the provided code) to prevent excessive computation.
- The density is applied differently depending on whether an importance volume is used and its size relative to the entire scene.
Best practices when using this variable include:
- Adjusting it in conjunction with other photon mapping settings for optimal balance between quality and performance.
- Using importance volumes to focus photon path generation in areas where it’s most needed.
- Considering the scale of your scene when setting this value, as it’s based on surface area units.
- Monitoring the impact on build times and memory usage when increasing this value, especially for large scenes.
#Setting Variables
#References In INI files
Location: <Workspace>/Engine/Config/BaseLightmass.ini:195, section: [DevOptions.PhotonMapping]
- INI Section:
DevOptions.PhotonMapping
- Raw value:
5
- Is Array:
False
#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:2384
Scope (from outer to inner):
file
function void FLightmassExporter::WriteSceneSettings
Source code excerpt:
VERIFYLIGHTMASSINI(GConfig->GetFloat(TEXT("DevOptions.PhotonMapping"), TEXT("DirectIrradiancePhotonDensity"), Scene.PhotonMappingSettings.DirectIrradiancePhotonDensity, GLightmassIni));
VERIFYLIGHTMASSINI(GConfig->GetFloat(TEXT("DevOptions.PhotonMapping"), TEXT("DirectPhotonSearchDistance"), Scene.PhotonMappingSettings.DirectPhotonSearchDistance, GLightmassIni));
VERIFYLIGHTMASSINI(GConfig->GetFloat(TEXT("DevOptions.PhotonMapping"), TEXT("IndirectPhotonPathDensity"), Scene.PhotonMappingSettings.IndirectPhotonPathDensity, GLightmassIni));
VERIFYLIGHTMASSINI(GConfig->GetFloat(TEXT("DevOptions.PhotonMapping"), TEXT("IndirectPhotonDensity"), Scene.PhotonMappingSettings.IndirectPhotonDensity, GLightmassIni));
VERIFYLIGHTMASSINI(GConfig->GetFloat(TEXT("DevOptions.PhotonMapping"), TEXT("IndirectIrradiancePhotonDensity"), Scene.PhotonMappingSettings.IndirectIrradiancePhotonDensity, GLightmassIni));
VERIFYLIGHTMASSINI(GConfig->GetFloat(TEXT("DevOptions.PhotonMapping"), TEXT("IndirectPhotonSearchDistance"), Scene.PhotonMappingSettings.IndirectPhotonSearchDistance, GLightmassIni));
VERIFYLIGHTMASSINI(GConfig->GetFloat(TEXT("DevOptions.PhotonMapping"), TEXT("PhotonSearchAngleThreshold"), Scene.PhotonMappingSettings.PhotonSearchAngleThreshold, GLightmassIni));
float IrradiancePhotonSearchConeAngle;
VERIFYLIGHTMASSINI(GConfig->GetFloat(TEXT("DevOptions.PhotonMapping"), TEXT("IrradiancePhotonSearchConeAngle"), IrradiancePhotonSearchConeAngle, GLightmassIni));
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Lightmass/Lightmass.cpp:2459
Scope (from outer to inner):
file
function void FLightmassExporter::WriteSceneSettings
Source code excerpt:
float NumIndirectPhotonPathsScale;
VERIFYLIGHTMASSINI(GConfig->GetFloat(QualitySectionNames[QualityLevel], TEXT("NumIndirectPhotonPathsScale"), NumIndirectPhotonPathsScale, GLightmassIni));
Scene.PhotonMappingSettings.IndirectPhotonPathDensity = Scene.PhotonMappingSettings.IndirectPhotonPathDensity * NumIndirectPhotonPathsScale;
float NumIndirectPhotonsScale;
VERIFYLIGHTMASSINI(GConfig->GetFloat(QualitySectionNames[QualityLevel], TEXT("NumIndirectPhotonsScale"), NumIndirectPhotonsScale, GLightmassIni));
Scene.PhotonMappingSettings.IndirectPhotonDensity = Scene.PhotonMappingSettings.IndirectPhotonDensity * NumIndirectPhotonsScale;
float NumIndirectIrradiancePhotonsScale;
#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/ImportExport/LightmassScene.cpp:539
Scope (from outer to inner):
file
namespace Lightmass
function void FScene::ApplyStaticLightingScale
Source code excerpt:
PhotonMappingSettings.DirectIrradiancePhotonDensity /= ScaleSquared;
PhotonMappingSettings.DirectPhotonSearchDistance *= SceneConstants.StaticLightingLevelScale;
PhotonMappingSettings.IndirectPhotonPathDensity /= ScaleSquared;
PhotonMappingSettings.IndirectPhotonDensity /= ScaleSquared;
PhotonMappingSettings.IndirectIrradiancePhotonDensity /= ScaleSquared;
PhotonMappingSettings.IndirectPhotonSearchDistance *= SceneConstants.StaticLightingLevelScale;
*/
}
//----------------------------------------------------------------------------
// Light base class
//----------------------------------------------------------------------------
void FLight::Import( FLightmassImporter& Importer )
{
Importer.ImportData( (FLightData*)this );
Importer.ImportArray( LightTextureProfileData, FLightData::LightProfileTextureDataSize );
// The read above stomps on CachedLightSurfaceSamples since that memory is padding in FLightData
FMemory::Memzero(&CachedLightSurfaceSamples, sizeof(CachedLightSurfaceSamples));
// Precalculate the light's indirect color
IndirectColor = FLinearColorUtils::AdjustSaturation(FLinearColor(Color), IndirectLightingSaturation) * IndirectLightingScale;
#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/Lighting/PhotonMapping.cpp:70
Scope (from outer to inner):
file
namespace Lightmass
function void FStaticLightingSystem::InitializePhotonSettings
Source code excerpt:
const int32 MaxNumIndirectPhotonPaths = 20000;
#endif
// If the importance volume is valid, only gather enough indirect photon paths to meet IndirectPhotonPathDensity inside the importance volume
if (!PhotonMappingSettings.bEmitPhotonsOutsideImportanceVolume && ImportanceBounds.SphereRadius > DELTA)
{
NumIndirectPhotonPaths = FMath::TruncToInt(Scene.PhotonMappingSettings.IndirectPhotonPathDensity * ImportanceSurfaceAreaMillionUnits);
}
else if (ImportanceBounds.SphereRadius > DELTA)
{
NumIndirectPhotonPaths = FMath::TruncToInt(Scene.PhotonMappingSettings.IndirectPhotonPathDensity * ImportanceSurfaceAreaMillionUnits
+ Scene.PhotonMappingSettings.OutsideImportanceVolumeDensityScale * Scene.PhotonMappingSettings.IndirectPhotonPathDensity * SceneSurfaceAreaMillionUnits);
}
else
{
NumIndirectPhotonPaths = FMath::TruncToInt(Scene.PhotonMappingSettings.IndirectPhotonPathDensity * SceneSurfaceAreaMillionUnits);
}
NumIndirectPhotonPaths = NumIndirectPhotonPaths == appTruncErrorCode ? MaxNumIndirectPhotonPaths : NumIndirectPhotonPaths;
NumIndirectPhotonPaths = FMath::Min(NumIndirectPhotonPaths, MaxNumIndirectPhotonPaths);
if (NumIndirectPhotonPaths == MaxNumIndirectPhotonPaths)
{
LogSolverMessage(FString::Printf(TEXT("Clamped the number of indirect photon paths to %u."), MaxNumIndirectPhotonPaths));
#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Public/SceneExport.h:679
Scope (from outer to inner):
file
namespace Lightmass
class class FPhotonMappingSettings
Source code excerpt:
* Densities too small will result in indirect lighting not making it into small pockets.
*/
float IndirectPhotonPathDensity;
/**
* Density of indirect photons to emit, in number of photons per million surface area units.
* This should be high because first bounce photons are used to guide the final gather.
*/
float IndirectPhotonDensity;