VisibilityRayOffsetDistance
VisibilityRayOffsetDistance
#Overview
name: VisibilityRayOffsetDistance
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 13
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of VisibilityRayOffsetDistance is to prevent incorrect self-shadowing due to floating-point precision in Unreal Engine’s static lighting system.
This setting variable is primarily used in the Lightmass subsystem, which is responsible for generating static lighting in Unreal Engine. It is referenced in various parts of the lighting calculation process, including direct and indirect lighting, photon mapping, and shadow calculations.
The value of this variable is typically set in the Lightmass configuration file (GLightmassIni) under the “DevOptions.StaticLightingSceneConstants” section. It is read and applied in the FLightmassExporter::WriteSceneSettings function.
VisibilityRayOffsetDistance interacts closely with other visibility-related variables, such as VisibilityNormalOffsetDistance and VisibilityNormalOffsetSampleRadiusScale. These variables work together to fine-tune the ray tracing process for visibility calculations.
Developers must be aware that this variable directly affects the accuracy and quality of static lighting calculations. Adjusting this value can help resolve self-shadowing artifacts, but setting it too high might introduce other visual issues.
Best practices when using this variable include:
- Keep the value as low as possible while still preventing self-shadowing artifacts.
- Test thoroughly after making changes, as it can affect the overall lighting quality.
- Consider the scale of your scene when adjusting this value, as it is in world space units.
- Use in conjunction with other visibility-related settings for optimal results.
- Document any custom values used in your project for consistency across the development team.
#Setting Variables
#References In INI files
Location: <Workspace>/Engine/Config/BaseLightmass.ini:41, section: [DevOptions.StaticLightingSceneConstants]
- INI Section:
DevOptions.StaticLightingSceneConstants
- Raw value:
.1
- 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:2181
Scope (from outer to inner):
file
function void FLightmassExporter::WriteSceneSettings
Source code excerpt:
VERIFYLIGHTMASSINI(GConfig->GetFloat(TEXT("DevOptions.StaticLightingSceneConstants"), TEXT("StaticLightingLevelScale"), GlobalLevelScale, GLightmassIni));
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:511
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;
#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/Lighting/Collision.cpp:389
Scope (from outer to inner):
file
namespace Lightmass
function bool FDefaultAggregateMesh::IntersectLightRay
Source code excerpt:
NumIterativeIntersections++;
// Clip the ray so it is now from the intersection point (plus some amount to avoid intersecting the same triangle again) to the original end of the ray
ClippedLightRay.ClipAgainstIntersectionFromEnd(ClosestIntersection.IntersectionVertex.WorldPosition + Scene.SceneConstants.VisibilityRayOffsetDistance * ClippedLightRay.Direction.GetUnsafeNormal3());
if ((ClosestIntersection.Mesh == LightRay.Mesh && ((ClosestIntersection.Mesh->LightingFlags & GI_INSTANCE_SELFSHADOWDISABLE) || (LightRay.TraceFlags & LIGHTRAY_SELFSHADOWDISABLE)))
|| (bDirectShadowingRay && ClosestIntersection.Mesh->IsIndirectlyShadowedOnly(ClosestIntersection.ElementIndex))
|| (ClosestIntersection.Mesh != LightRay.Mesh && (ClosestIntersection.Mesh->LightingFlags & GI_INSTANCE_SELFSHADOWONLY))
|| !ClosestIntersection.Mesh->IsSurfaceDomain(ClosestIntersection.ElementIndex))
{
#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/Lighting/FinalGather.cpp:343
Scope (from outer to inner):
file
namespace Lightmass
function void FStaticLightingSystem::IntersectLightRays
Source code excerpt:
// The offset along the normal is to push self-intersection patterns (like triangle shape) on highly curved surfaces onto the backfaces.
FVector3f RayStart = Vertex.WorldPosition
+ WorldPathDirection * SceneConstants.VisibilityRayOffsetDistance
+ Vertex.WorldTangentZ * RayStartNormalBiasScale * SampleRadius
+ SampleOffset;
OutLightRays[RayIndex] = FLightRay(
RayStart,
Vertex.WorldPosition + WorldPathDirection * MaxRayDistance,
#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/Lighting/LightingSystem.cpp:2400
Scope (from outer to inner):
file
namespace Lightmass
function void FStaticLightingSystem::ValidateSettings
function bool FStaticLightingSystem::CalculatePointShadowing
Source code excerpt:
const FVector4f LightVector = LightPosition - WorldSurfacePoint * Light->Position.W;
const FLightRay LightRay(
WorldSurfacePoint + LightVector.GetSafeNormal() * SceneConstants.VisibilityRayOffsetDistance,
WorldSurfacePoint + LightVector,
Mapping,
Light
);
// Check the line segment for intersection with the static lighting meshes.
#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/Lighting/LightingSystem.cpp:2502
Scope (from outer to inner):
file
namespace Lightmass
function void FStaticLightingSystem::ValidateSettings
function FVector2f FStaticLightingSystem::CalculatePointAreaShadowing
Source code excerpt:
// Offset the start of the ray by some fraction along the direction of the ray and some fraction along the vertex normal.
Vertex.WorldPosition
+ LightVector.GetSafeNormal() * SceneConstants.VisibilityRayOffsetDistance
+ NormalForOffset * SampleRadius * SceneConstants.VisibilityNormalOffsetSampleRadiusScale
+ SampleOffset,
Vertex.WorldPosition + LightVector,
Mapping,
Light
);
#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/Lighting/LightingSystem.inl:140
Scope (from outer to inner):
file
function void FStaticLightingSystem::CalculateApproximateDirectLighting
Source code excerpt:
FVector4f NormalForOffset = Vertex.WorldTangentZ;
const FVector4f StartOffset = LightVector.GetSafeNormal() * SceneConstants.VisibilityRayOffsetDistance
+ NormalForOffset * SampleRadius * SceneConstants.VisibilityNormalOffsetSampleRadiusScale;
const FLightRay LightRay(
// Offset the start of the ray by some fraction along the direction of the ray and some fraction along the vertex normal.
Vertex.WorldPosition
+ StartOffset,
#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/Lighting/PhotonMapping.cpp:621
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,
#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/Lighting/PhotonMapping.cpp:1162
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;
#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++;
#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/Lighting/TextureMapping.cpp:1984
Scope (from outer to inner):
file
namespace Lightmass
function void FStaticLightingSystem::CalculateDirectSignedDistanceFieldLightingTextureMappingTextureSpace
Source code excerpt:
// Offset the start of the ray by some fraction along the direction of the ray and some fraction along the vertex normal.
TexelToVertex.WorldPosition
+ LightVector * SceneConstants.VisibilityRayOffsetDistance
+ NormalForOffset * SceneConstants.VisibilityNormalOffsetDistance,
LightPosition,
TextureMapping,
Light
);
#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Private/Lighting/TextureMapping.cpp:2214
Scope: file
Source code excerpt:
// Offset the start of the ray by some fraction along the direction of the ray and some fraction along the vertex normal.
HighResSample.GetPosition()
+ LightVector * SceneConstants.VisibilityRayOffsetDistance
+ NormalForOffset * SceneConstants.VisibilityNormalOffsetDistance,
LightPosition,
TextureMapping,
Light
);
#Loc: <Workspace>/Engine/Source/Programs/UnrealLightmass/Public/SceneExport.h:145
Scope (from outer to inner):
file
namespace Lightmass
class class FStaticLightingSceneConstants
Source code excerpt:
* This is used to prevent incorrect self shadowing due to floating point precision.
*/
float VisibilityRayOffsetDistance;
/**
* World space distance to offset the origin of the ray along the direction of the normal.
* This is used to push triangle shaped self shadowing artifacts onto the backfaces of curved objects.
*/
float VisibilityNormalOffsetDistance;