IndirectPhotonDensity
IndirectPhotonDensity
#Overview
name: IndirectPhotonDensity
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 IndirectPhotonDensity is to control the density of indirect photons in the photon mapping system used for global illumination calculations in Unreal Engine’s Lightmass.
This setting variable is primarily used in the Lightmass subsystem, which is responsible for precomputed lighting in Unreal Engine. It is part of the photon mapping settings that control how indirect lighting is calculated and stored.
The value of this variable is typically set in the Lightmass configuration file (GLightmassIni). It’s read from the “DevOptions.PhotonMapping” section of this configuration file.
IndirectPhotonDensity interacts with several other variables in the photon mapping system:
- It’s scaled by NumIndirectPhotonsScale, which allows for quality-based adjustments.
- It’s used in conjunction with IndirectIrradiancePhotonDensity to determine the fraction of indirect photons that should store irradiance information.
- It’s affected by the StaticLightingLevelScale, which adjusts the density based on the overall scale of the level.
Developers should be aware that:
- This variable directly affects the number of indirect photons emitted during the lighting build process. Higher values will result in more accurate indirect lighting but will increase build times and memory usage.
- The actual number of photons emitted is capped to prevent excessive memory usage.
- The density is applied differently depending on whether an importance volume is used in the scene.
Best practices when using this variable include:
- Adjust it based on the scale and complexity of your scene. Larger scenes may require lower densities to keep build times reasonable.
- Use it in conjunction with importance volumes to focus photon density in areas where it’s most needed.
- Be prepared to experiment with different values to find the right balance between lighting quality and build performance for your specific project.
- Consider the relationship between this value and other photon mapping settings for optimal results.
#Setting Variables
#References In INI files
Location: <Workspace>/Engine/Config/BaseLightmass.ini:197, section: [DevOptions.PhotonMapping]
- INI Section:
DevOptions.PhotonMapping
- Raw value:
600
- 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:2385
Scope (from outer to inner):
file
function void FLightmassExporter::WriteSceneSettings
Source code excerpt:
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));
Scene.PhotonMappingSettings.MinCosIrradiancePhotonSearchCone = FMath::Cos((90.0f - FMath::Clamp(IrradiancePhotonSearchConeAngle, 1.0f, 90.0f)) * (float)PI / 180.0f);
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Lightmass/Lightmass.cpp:2463
Scope (from outer to inner):
file
function void FLightmassExporter::WriteSceneSettings
Source code excerpt:
float NumIndirectPhotonsScale;
VERIFYLIGHTMASSINI(GConfig->GetFloat(QualitySectionNames[QualityLevel], TEXT("NumIndirectPhotonsScale"), NumIndirectPhotonsScale, GLightmassIni));
Scene.PhotonMappingSettings.IndirectPhotonDensity = Scene.PhotonMappingSettings.IndirectPhotonDensity * NumIndirectPhotonsScale;
float NumIndirectIrradiancePhotonsScale;
VERIFYLIGHTMASSINI(GConfig->GetFloat(QualitySectionNames[QualityLevel], TEXT("NumIndirectIrradiancePhotonsScale"), NumIndirectIrradiancePhotonsScale, GLightmassIni));
Scene.PhotonMappingSettings.IndirectIrradiancePhotonDensity = Scene.PhotonMappingSettings.IndirectIrradiancePhotonDensity * NumIndirectIrradiancePhotonsScale;
float RecordRadiusScaleScale;
#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/ImportExport/LightmassScene.cpp:540
Scope (from outer to inner):
file
namespace Lightmass
function void FScene::ApplyStaticLightingScale
Source code excerpt:
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/LightingSystem.cpp:900
Scope (from outer to inner):
file
namespace Lightmass
function void FStaticLightingSystem::ValidateSettings
Source code excerpt:
InScene.GeneralSettings.ViewSingleBounceNumber = FMath::Min(InScene.GeneralSettings.ViewSingleBounceNumber, InScene.GeneralSettings.NumIndirectLightingBounces);
if (FMath::IsNearlyEqual(InScene.PhotonMappingSettings.IndirectPhotonDensity, 0.0f))
{
// Allocate all samples toward uniform sampling if there are no indirect photons
InScene.PhotonMappingSettings.FinalGatherImportanceSampleFraction = 0;
}
#if LIGHTMASS_DO_PROCESSING
if (!InScene.PhotonMappingSettings.bUseIrradiancePhotons)
#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/Lighting/PhotonMapping.cpp:97
Scope (from outer to inner):
file
namespace Lightmass
function void FStaticLightingSystem::InitializePhotonSettings
Source code excerpt:
#endif
Stats.NumSecondPassPhotonsRequested = 0;
// If the importance volume is valid, only emit enough indirect photons to meet IndirectPhotonDensity inside the importance volume
if (!PhotonMappingSettings.bEmitPhotonsOutsideImportanceVolume && ImportanceBounds.SphereRadius > DELTA)
{
Stats.NumSecondPassPhotonsRequested = Scene.PhotonMappingSettings.IndirectPhotonDensity * ImportanceSurfaceAreaMillionUnits;
}
else if (ImportanceBounds.SphereRadius > DELTA)
{
Stats.NumSecondPassPhotonsRequested = Scene.PhotonMappingSettings.IndirectPhotonDensity * ImportanceSurfaceAreaMillionUnits
+ Scene.PhotonMappingSettings.OutsideImportanceVolumeDensityScale * Scene.PhotonMappingSettings.IndirectPhotonDensity * SceneSurfaceAreaMillionUnits;
}
else
{
Stats.NumSecondPassPhotonsRequested = Scene.PhotonMappingSettings.IndirectPhotonDensity * SceneSurfaceAreaMillionUnits;
}
NumIndirectPhotonsToEmit = FMath::Min<uint64>(Stats.NumSecondPassPhotonsRequested, (uint64)MaxNumIndirectPhotons);
if (NumIndirectPhotonsToEmit == MaxNumIndirectPhotons)
{
LogSolverMessage(FString::Printf(TEXT("Clamped the number of indirect photons to emit to %.3f million, from %.3f million requested."), MaxNumIndirectPhotons / 1000000.0f, Stats.NumSecondPassPhotonsRequested / 1000000.0f));
}
IndirectIrradiancePhotonFraction = FMath::Clamp(Scene.PhotonMappingSettings.IndirectIrradiancePhotonDensity / Scene.PhotonMappingSettings.IndirectPhotonDensity, 0.0f, 1.0f);
}
/** Emits photons, builds data structures to accelerate photon map lookups, and does any other photon preprocessing required. */
void FStaticLightingSystem::EmitPhotons()
{
const FBoxSphereBounds3f SceneSphereBounds = FBoxSphereBounds3f(AggregateMesh->GetBounds());
#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Public/SceneExport.h:685
Scope (from outer to inner):
file
namespace Lightmass
class class FPhotonMappingSettings
Source code excerpt:
* This should be high because first bounce photons are used to guide the final gather.
*/
float IndirectPhotonDensity;
/** Density of indirect photons which have irradiance cached at their position, in number of photons per million surface area units. */
float IndirectIrradiancePhotonDensity;
/** Distance to use when searching for indirect photons. */
float IndirectPhotonSearchDistance;