DirectPhotonSearchDistance

DirectPhotonSearchDistance

#Overview

name: DirectPhotonSearchDistance

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

#Summary

#Usage in the C++ source code

The purpose of DirectPhotonSearchDistance is to define the search radius for direct photons in Unreal Engine 5’s lightmass system, which is part of the global illumination and static lighting solution.

This setting variable is primarily used by the Lightmass subsystem, which is responsible for precalculating static lighting in Unreal Engine. It’s specifically utilized in the photon mapping process, which is a technique for calculating global illumination.

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

DirectPhotonSearchDistance interacts with several other variables in the photon mapping system, such as DirectPhotonDensity, IndirectPhotonSearchDistance, and PhotonSearchAngleThreshold. It’s also scaled by DirectPhotonSearchDistanceScale, which allows for quality-based adjustments.

Developers should be aware that this variable directly affects the accuracy and performance of direct lighting calculations in static lighting. A larger search distance can result in more accurate lighting but at the cost of increased computation time.

Best practices when using this variable include:

  1. Balancing it with DirectPhotonDensity for optimal results.
  2. Adjusting it based on the scale of your scene - larger scenes may require larger search distances.
  3. Using it in conjunction with quality settings (via DirectPhotonSearchDistanceScale) to offer different performance/quality tradeoffs.
  4. Being cautious about setting it too high, as it can significantly increase lightmass baking times.
  5. Consider the relationship between this value and IndirectPhotonSearchDistance for consistent lighting results.

#Setting Variables

#References In INI files

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

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

Scope (from outer to inner):

file
function     void FLightmassExporter::WriteSceneSettings

Source code excerpt:

		VERIFYLIGHTMASSINI(GConfig->GetFloat(TEXT("DevOptions.PhotonMapping"), TEXT("DirectPhotonDensity"), Scene.PhotonMappingSettings.DirectPhotonDensity, GLightmassIni));
		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;

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

Scope (from outer to inner):

file
function     void FLightmassExporter::WriteSceneSettings

Source code excerpt:

		float DirectPhotonSearchDistanceScale;
		VERIFYLIGHTMASSINI(GConfig->GetFloat(QualitySectionNames[QualityLevel], TEXT("DirectPhotonSearchDistanceScale"), DirectPhotonSearchDistanceScale, GLightmassIni));
		Scene.PhotonMappingSettings.DirectPhotonSearchDistance = Scene.PhotonMappingSettings.DirectPhotonSearchDistance * DirectPhotonSearchDistanceScale;

		float NumIndirectPhotonPathsScale;
		VERIFYLIGHTMASSINI(GConfig->GetFloat(QualitySectionNames[QualityLevel], TEXT("NumIndirectPhotonPathsScale"), NumIndirectPhotonPathsScale, GLightmassIni));
		Scene.PhotonMappingSettings.IndirectPhotonPathDensity = Scene.PhotonMappingSettings.IndirectPhotonPathDensity * NumIndirectPhotonPathsScale;

		float NumIndirectPhotonsScale;

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

Scope (from outer to inner):

file
namespace    Lightmass
function     void FScene::ApplyStaticLightingScale

Source code excerpt:

	PhotonMappingSettings.DirectPhotonDensity /= ScaleSquared;
	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

#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/Lighting/PhotonMapping.cpp:1335

Scope (from outer to inner):

file
namespace    Lightmass
function     void FStaticLightingSystem::MarkIrradiancePhotonsWorkRange

Source code excerpt:

		{
			// Find a nearby direct photon
			const bool bHasDirectContribution = FindAnyNearbyPhoton(DirectPhotonMap, CurrentIrradiancePhoton.GetPosition(), PhotonMappingSettings.DirectPhotonSearchDistance, false);
			if (bHasDirectContribution)
			{
				// Mark the irradiance photon has having direct contribution, which will be used to reduce the search radius for this irradiance photon,
				// In order to get more accurate direct shadow transitions using the photon map.
				CurrentIrradiancePhoton.SetHasDirectContribution();
			}

#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/Lighting/PhotonMapping.cpp:1522

Scope (from outer to inner):

file
namespace    Lightmass
function     void FStaticLightingSystem::CalculateIrradiancePhotonsWorkRange

Source code excerpt:

				NumPhotonsEmittedDirect, 
				PhotonMappingSettings.NumIrradianceCalculationPhotons, 
				PhotonMappingSettings.DirectPhotonSearchDistance, 
				CurrentIrradiancePhoton,
				bDebugThisPhoton && GeneralSettings.ViewSingleBounceNumber == 0,
				TempFoundPhotons,
				OutStats);

			checkSlow(FLinearColorUtils::AreFloatsValid(DirectPhotonIrradiance));

#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/Lighting/PhotonMapping.cpp:2224

Scope (from outer to inner):

file
namespace    Lightmass
function     FIrradiancePhoton* FStaticLightingSystem::FindNearestIrradiancePhoton

Source code excerpt:

	FIrradiancePhoton* ClosestPhoton = NULL;
	// Traverse the octree with the maximum distance required
	const float SearchDistance = FMath::Max(PhotonMappingSettings.DirectPhotonSearchDistance, PhotonMappingSettings.IndirectPhotonSearchDistance);
	float ClosestDistanceSquared = FMath::Square(SearchDistance);

	// Empty the temporary array without reallocating
	TempIrradiancePhotons.Empty(TempIrradiancePhotons.Num() + TempIrradiancePhotons.GetSlack());
	const FBox3f SearchBox = FBox3f::BuildAABB(Vertex.WorldPosition, FVector4f(SearchDistance, SearchDistance, SearchDistance));
	{

#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/Lighting/PhotonMapping.cpp:2265

Scope (from outer to inner):

file
function     FIrradiancePhoton* FStaticLightingSystem::FindNearestIrradiancePhoton

Source code excerpt:

				if (CosTheta > PhotonMappingSettings.PhotonSearchAngleThreshold
					// And closer to the search position than the max search distance.
					&& ((CurrentPhoton.HasDirectContribution() && (DistanceSquared < FMath::Square(PhotonMappingSettings.DirectPhotonSearchDistance)))
					|| (!CurrentPhoton.HasDirectContribution() && (DistanceSquared < FMath::Square(PhotonMappingSettings.IndirectPhotonSearchDistance)))))
				{
					// Only accept irradiance photons within an angle of the plane defined by the vertex normal
					// This avoids expensive visibility traces to photons that are probably not on the same surface
					const float DirectionDotNormal = Dot3(CurrentPhoton.GetSurfaceNormal(), PhotonToVertexVector.GetSafeNormal());
					if (FMath::Abs(DirectionDotNormal) < PhotonMappingSettings.MinCosIrradiancePhotonSearchCone)

#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/Lighting/TextureMapping.cpp:2836

Scope (from outer to inner):

file
namespace    Lightmass
function     void FStaticLightingSystem::CalculateDirectLightingTextureMappingPhotonMap

Source code excerpt:

				{
					// Estimate incident radiance from the photons in the direct photon map
					const FGatheredLightSample PhotonIncidentRadiance = CalculatePhotonIncidentRadiance(DirectPhotonMap, NumPhotonsEmittedDirect, PhotonMappingSettings.DirectPhotonSearchDistance, CurrentVertex, bDebugThisTexel);
					if (GeneralSettings.ViewSingleBounceNumber < 1)
					{
						CurrentLightSample.AddWeighted(PhotonIncidentRadiance, 1.0f);
					}
				}
			}

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

Scope (from outer to inner):

file
namespace    Lightmass
class        class FPhotonMappingSettings

Source code excerpt:


	/** Distance to use when searching for direct photons. */
	float DirectPhotonSearchDistance;

	/**
	 * Target density of indirect photon paths to gather, in number of paths per million surface area units. 
	 * Densities too small will result in indirect lighting not making it into small pockets.
	 */
	float IndirectPhotonPathDensity;