VisibilityNormalOffsetDistance
VisibilityNormalOffsetDistance
#Overview
name: VisibilityNormalOffsetDistance
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 8
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of VisibilityNormalOffsetDistance is to prevent self-shadowing artifacts in static lighting calculations within Unreal Engine 5’s Lightmass system. It’s used to offset the starting point of visibility rays along the surface normal direction when performing shadow and visibility tests.
This setting variable is primarily used in the lighting and shadow mapping subsystems of Unreal Engine, specifically within the Lightmass global illumination solver. It’s referenced in modules related to static lighting, photon mapping, and texture mapping for lightmaps.
The value of this variable is typically set in the Lightmass configuration file (Lightmass.ini) under the [DevOptions.StaticLightingSceneConstants] section. It’s read into the engine during the static lighting build process.
VisibilityNormalOffsetDistance often interacts with other visibility-related variables like VisibilityRayOffsetDistance and VisibilityNormalOffsetSampleRadiusScale. These variables work together to fine-tune the positioning of visibility rays for more accurate lighting calculations.
Developers should be aware that this variable directly affects the accuracy and quality of static lighting. Setting it too low might result in self-shadowing artifacts, while setting it too high could lead to light leaking or loss of detail in shadows.
Best practices when using this variable include:
- Adjusting it in small increments and rebuilding lighting to observe the effects.
- Considering the scale of your scene, as the appropriate value may vary depending on scene size.
- Balancing it with other visibility offset variables for optimal results.
- Documenting any changes made to this setting, as it can significantly impact lighting quality across the project.
#Setting Variables
#References In INI files
Location: <Workspace>/Engine/Config/BaseLightmass.ini:42, section: [DevOptions.StaticLightingSceneConstants]
- INI Section:
DevOptions.StaticLightingSceneConstants
- Raw value:
3
- 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:2182
Scope (from outer to inner):
file
function void FLightmassExporter::WriteSceneSettings
Source code excerpt:
Scene.SceneConstants.StaticLightingLevelScale = GlobalLevelScale * LevelSettings.StaticLightingLevelScale;
VERIFYLIGHTMASSINI(GConfig->GetFloat(TEXT("DevOptions.StaticLightingSceneConstants"), TEXT("VisibilityRayOffsetDistance"), Scene.SceneConstants.VisibilityRayOffsetDistance, GLightmassIni));
VERIFYLIGHTMASSINI(GConfig->GetFloat(TEXT("DevOptions.StaticLightingSceneConstants"), TEXT("VisibilityNormalOffsetDistance"), Scene.SceneConstants.VisibilityNormalOffsetDistance, GLightmassIni));
VERIFYLIGHTMASSINI(GConfig->GetFloat(TEXT("DevOptions.StaticLightingSceneConstants"), TEXT("VisibilityNormalOffsetSampleRadiusScale"), Scene.SceneConstants.VisibilityNormalOffsetSampleRadiusScale, GLightmassIni));
VERIFYLIGHTMASSINI(GConfig->GetFloat(TEXT("DevOptions.StaticLightingSceneConstants"), TEXT("VisibilityTangentOffsetSampleRadiusScale"), Scene.SceneConstants.VisibilityTangentOffsetSampleRadiusScale, GLightmassIni));
VERIFYLIGHTMASSINI(GConfig->GetFloat(TEXT("DevOptions.StaticLightingSceneConstants"), TEXT("SmallestTexelRadius"), Scene.SceneConstants.SmallestTexelRadius, GLightmassIni));
VERIFYLIGHTMASSINI(GConfig->GetInt(TEXT("DevOptions.StaticLightingSceneConstants"), TEXT("LightGridSize"), Scene.SceneConstants.LightGridSize, GLightmassIni));
}
{
#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/ImportExport/LightmassScene.cpp:512
Scope (from outer to inner):
file
namespace Lightmass
function void FScene::ApplyStaticLightingScale
Source code excerpt:
// Scale world space distances directly
SceneConstants.VisibilityRayOffsetDistance *= SceneConstants.StaticLightingLevelScale;
SceneConstants.VisibilityNormalOffsetDistance *= SceneConstants.StaticLightingLevelScale;
SceneConstants.SmallestTexelRadius *= SceneConstants.StaticLightingLevelScale;
MeshAreaLightSettings.MeshAreaLightSimplifyCornerDistanceThreshold *= SceneConstants.StaticLightingLevelScale;
MeshAreaLightSettings.MeshAreaLightGeneratedDynamicLightSurfaceOffset *= SceneConstants.StaticLightingLevelScale;
DynamicObjectSettings.FirstSurfaceSampleLayerHeight *= SceneConstants.StaticLightingLevelScale;
DynamicObjectSettings.SurfaceLightSampleSpacing *= SceneConstants.StaticLightingLevelScale;
DynamicObjectSettings.SurfaceSampleLayerHeightSpacing *= SceneConstants.StaticLightingLevelScale;
#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/Lighting/PhotonMapping.cpp:622
Scope (from outer to inner):
file
namespace Lightmass
function void FStaticLightingSystem::EmitDirectPhotonsWorkRange
Source code excerpt:
const FVector4f RayStart = IntersectionVertexWithTangents.WorldPosition
+ NewWorldPathDirection * SceneConstants.VisibilityRayOffsetDistance
+ IntersectionVertexWithTangents.WorldTangentZ * SceneConstants.VisibilityNormalOffsetDistance;
const FVector4f RayEnd = IntersectionVertexWithTangents.WorldPosition + NewWorldPathDirection * MaxRayDistance;
FLightRay IndirectSampleRay(
RayStart,
RayEnd,
NULL,
#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/Lighting/PhotonMapping.cpp:1163
Scope (from outer to inner):
file
namespace Lightmass
function void FStaticLightingSystem::EmitIndirectPhotonsWorkRange
Source code excerpt:
const FVector4f RayStart = IntersectionVertexWithTangents.WorldPosition
+ NewWorldPathDirection * SceneConstants.VisibilityRayOffsetDistance
+ IntersectionVertexWithTangents.WorldTangentZ * SceneConstants.VisibilityNormalOffsetDistance;
FVector4f RayEnd = IntersectionVertexWithTangents.WorldPosition + NewWorldPathDirection * MaxRayDistance;
// Clip photon path end points to the importance volume, so we do not bother tracing rays outside the area that photons can be deposited.
// If the photon path does not intersect the importance volume at all, it did not originate from inside the volume, so skip to the next photon.
FVector4f ClippedStart, ClippedEnd;
if (!ClipLineWithBox(Input.ImportanceBounds.GetBox(), RayStart, RayEnd, ClippedStart, ClippedEnd))
#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/Lighting/PhotonMapping.cpp:2302
Scope (from outer to inner):
file
namespace Lightmass
function FIrradiancePhoton* FStaticLightingSystem::FindNearestIrradiancePhoton
Source code excerpt:
const FVector4f VertexToPhoton = CurrentPhoton->GetPosition() - Vertex.WorldPosition;
const FLightRay VertexToPhotonRay(
Vertex.WorldPosition + VertexToPhoton.GetSafeNormal() * SceneConstants.VisibilityRayOffsetDistance + Vertex.WorldTangentZ * SceneConstants.VisibilityNormalOffsetDistance,
CurrentPhoton->GetPosition() + CurrentPhoton->GetSurfaceNormal() * SceneConstants.VisibilityNormalOffsetDistance,
NULL,
NULL
);
MappingContext.Stats.NumIrradiancePhotonSearchRays++;
const float PreviousShadowTraceTime = MappingContext.RayCache.BooleanRayTraceTime;
#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/Lighting/TextureMapping.cpp:1985
Scope (from outer to inner):
file
namespace Lightmass
function void FStaticLightingSystem::CalculateDirectSignedDistanceFieldLightingTextureMappingTextureSpace
Source code excerpt:
TexelToVertex.WorldPosition
+ LightVector * SceneConstants.VisibilityRayOffsetDistance
+ NormalForOffset * SceneConstants.VisibilityNormalOffsetDistance,
LightPosition,
TextureMapping,
Light
);
FLightRayIntersection Intersection;
#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/Lighting/TextureMapping.cpp:2215
Scope: file
Source code excerpt:
HighResSample.GetPosition()
+ LightVector * SceneConstants.VisibilityRayOffsetDistance
+ NormalForOffset * SceneConstants.VisibilityNormalOffsetDistance,
LightPosition,
TextureMapping,
Light
);
FLightRayIntersection Intersection;
#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Public/SceneExport.h:151
Scope (from outer to inner):
file
namespace Lightmass
class class FStaticLightingSceneConstants
Source code excerpt:
* This is used to push triangle shaped self shadowing artifacts onto the backfaces of curved objects.
*/
float VisibilityNormalOffsetDistance;
/**
* Fraction of the sample radius to offset the origin of the ray along the sample normal.
* This is applied instead of VisibilityNormalOffsetDistance whenever sample radius is known as it adapts to differently sized texels.
*/
float VisibilityNormalOffsetSampleRadiusScale;
/**
* Fraction of the sample radius to offset the origin of the ray in the tangent XY plane, based on the direction of the ray.
* This is only used when bAccountForTexelSize is true.
*/
float VisibilityTangentOffsetSampleRadiusScale;