TraceVoxels:
[numthreads( 64 , 1, 1)]
void ScreenProbeTraceVoxelsCS(
uint3 GroupId : SV_GroupID,
uint3 DispatchThreadId : SV_DispatchThreadID,
uint3 GroupThreadId : SV_GroupThreadID)
{
uint AllocatorIndex = 0 ? 1 : 0;
if (DispatchThreadId.x < CompactedTraceTexelAllocator[AllocatorIndex])
{
uint ScreenProbeIndex;
uint2 TraceTexelCoord;
float TraceHitDistance;
ReadTraceTexel(DispatchThreadId.x, ScreenProbeIndex, TraceTexelCoord, TraceHitDistance);
uint2 ScreenProbeAtlasCoord = uint2(ScreenProbeIndex % ScreenProbeAtlasViewSize.x, ScreenProbeIndex / ScreenProbeAtlasViewSize.x);
TraceVoxels(ScreenProbeAtlasCoord, TraceTexelCoord, ScreenProbeIndex, TraceHitDistance);
}
}
void ReadTraceTexel(uint DispatchThreadId, out uint ScreenProbeIndex, out uint2 TraceTexelCoord, out float TraceHitDistance)
{
DecodeTraceTexel(CompactedTraceTexelData[DispatchThreadId], ScreenProbeIndex, TraceTexelCoord, TraceHitDistance);
}
void DecodeTraceTexel(uint2 TraceTexelData, inout uint ScreenProbeIndex, inout uint2 TraceTexelCoord, inout float TraceHitDistance)
{
ScreenProbeIndex = TraceTexelData.x & 0xFFFFF;
TraceTexelCoord.x = (TraceTexelData.x >> 20) & 0x1F;
TraceTexelCoord.y = (TraceTexelData.x >> 25) & 0x1F;
TraceHitDistance = asfloat(TraceTexelData.y);
}
void TraceVoxels(
uint2 ScreenProbeAtlasCoord,
uint2 TraceTexelCoord,
uint ScreenProbeIndex,
float TraceHitDistance)
{
uint2 ScreenProbeScreenPosition = GetScreenProbeScreenPosition(ScreenProbeIndex);
uint2 ScreenTileCoord = GetScreenTileCoord(ScreenProbeScreenPosition);
uint ProbeTracingResolution = 0 ? ScreenProbeLightSampleResolutionXY : ScreenProbeTracingOctahedronResolution;
uint2 TraceBufferCoord = GetTraceBufferCoord(ScreenProbeAtlasCoord, TraceTexelCoord);
{
float2 ScreenUV = GetScreenUVFromScreenProbePosition(ScreenProbeScreenPosition);
float SceneDepth = GetScreenProbeDepth(ScreenProbeAtlasCoord);
bool bHit = false;
{
float3 TranslatedWorldPosition = GetTranslatedWorldPositionFromScreenUV(ScreenUV, SceneDepth);
float3 WorldPosition = TranslatedWorldPosition - LWCToFloat( GetPrimaryView() .PreViewTranslation) ;
float3 RayWorldDirection = 0;
float TraceDistance = MaxTraceDistance;
float ConeHalfAngle = 0;
GetScreenProbeTexelRay(
TraceBufferCoord,
TraceTexelCoord,
ScreenTileCoord,
TranslatedWorldPosition,
RayWorldDirection,
TraceDistance,
ConeHalfAngle);
float3 TranslatedSamplePosition = TranslatedWorldPosition + SurfaceBias * RayWorldDirection;
TranslatedSamplePosition += SurfaceBias * GetScreenProbeNormalForBiasing(ScreenProbeAtlasCoord, RayWorldDirection);
float3 SamplePosition = TranslatedSamplePosition - LWCToFloat( GetPrimaryView() .PreViewTranslation) ;
FRadianceCacheCoverage Coverage;
Coverage.bValid = false;
Coverage = GetRadianceCacheCoverage(WorldPosition, RayWorldDirection, InterleavedGradientNoise(ScreenTileCoord, (FixedJitterIndex < 0 ? View_StateFrameIndexMod8 : FixedJitterIndex) ));
if (Coverage.bValid)
{
TraceDistance = min(TraceDistance, Coverage.MinTraceDistanceBeforeInterpolation);
}
FConeTraceInput TraceInput;
TraceInput.Setup(SamplePosition, TranslatedSamplePosition, RayWorldDirection, ConeHalfAngle, MinSampleRadius, MinTraceDistance, TraceDistance, StepFactor);
TraceInput.VoxelTraceStartDistance = max(MinTraceDistance, TraceHitDistance - SurfaceBias * 2);
TraceInput.bDitheredTransparency = true;
TraceInput.DitherScreenCoord = ScreenTileCoord * ProbeTracingResolution + TraceTexelCoord;
FConeTraceResult TraceResult = (FConeTraceResult)0;
TraceResult.Lighting = 0;
TraceResult.Transparency = 1;
TraceResult.OpaqueHitDistance = TraceInput.MaxTraceDistance;
ConeTraceLumenSceneVoxels(TraceInput, TraceResult);
float TraceHitDistanceForSkyLeaking = TraceHitDistance;
if (TraceResult.Transparency <= .5f)
{
TraceHitDistance = TraceDistance;
TraceHitDistanceForSkyLeaking = TraceResult.OpaqueHitDistance;
bHit = true;
}
if (Coverage.bValid)
{
if (TraceResult.Transparency > .5f)
{
TraceHitDistance = MaxTraceDistance;
TraceHitDistanceForSkyLeaking = MaxTraceDistance;
}
SampleRadianceCacheAndApply(Coverage, WorldPosition, RayWorldDirection, ConeHalfAngle, TraceResult.Lighting, TraceResult.Transparency);
}
else
{
if (TraceResult.Transparency > .5f)
{
TraceHitDistance = MaxTraceDistance;
TraceHitDistanceForSkyLeaking = MaxTraceDistance;
}
ApplySkylightToTraceResult(RayWorldDirection, TraceResult);
if (TraceHitDistance >= GetProbeMaxHitDistance())
{
TraceHitDistance = MaxTraceDistance;
}
}
TraceResult.Lighting += GetSkylightLeaking(RayWorldDirection, TraceHitDistanceForSkyLeaking);
TraceResult.Lighting *= View_PreExposure;
RWTraceRadiance[TraceBufferCoord] = TraceResult.Lighting;
}
WriteTraceHit(TraceBufferCoord, TraceHitDistance, bHit, false);
}
}
void ConeTraceLumenSceneVoxels(
FConeTraceInput TraceInput,
inout FConeTraceResult OutResult)
{
#if SCENE_TRACE_VOXELS
if (TraceInput.VoxelTraceStartDistance < TraceInput.MaxTraceDistance)
{
FConeTraceInput VoxelTraceInput = TraceInput;
VoxelTraceInput.MinTraceDistance = TraceInput.VoxelTraceStartDistance;
FConeTraceResult VoxelTraceResult;
RayTraceGlobalDistanceField(VoxelTraceInput, VoxelTraceResult);
#if !VISIBILITY_ONLY_TRACE
OutResult.Lighting += VoxelTraceResult.Lighting * OutResult.Transparency;
#endif
OutResult.Transparency *= VoxelTraceResult.Transparency;
OutResult.NumSteps += VoxelTraceResult.NumSteps;
OutResult.OpaqueHitDistance = min(OutResult.OpaqueHitDistance, VoxelTraceResult.OpaqueHitDistance);
}
#endif
}
void RayTraceGlobalDistanceField(
FConeTraceInput TraceInput,
inout FConeTraceResult OutResult)
{
FGlobalSDFTraceResult SDFTraceResult;
{
FGlobalSDFTraceInput SDFTraceInput = SetupGlobalSDFTraceInput(TraceInput.ConeOrigin, TraceInput.ConeDirection, TraceInput.MinTraceDistance, TraceInput.MaxTraceDistance, TraceInput.SDFStepFactor, TraceInput.MinSDFStepFactor);
SDFTraceInput.bDitheredTransparency = TraceInput.bDitheredTransparency;
SDFTraceInput.DitherScreenCoord = TraceInput.DitherScreenCoord;
SDFTraceInput.bExpandSurfaceUsingRayTimeInsteadOfMaxDistance = TraceInput.bExpandSurfaceUsingRayTimeInsteadOfMaxDistance;
SDFTraceInput.InitialMaxDistance = TraceInput.InitialMaxDistance;
SDFTraceResult = RayTraceGlobalDistanceField(SDFTraceInput);
}
float4 LightingAndAlpha = float4(0, 0, 0, 1);
if (GlobalSDFTraceResultIsHit(SDFTraceResult))
{
LightingAndAlpha = EvaluateGlobalDistanceFieldHit(TraceInput, SDFTraceResult);
}
OutResult = (FConeTraceResult)0;
OutResult.Lighting = LightingAndAlpha.rgb;
OutResult.Transparency = LightingAndAlpha.a;
OutResult.NumSteps = SDFTraceResult.TotalStepsTaken;
OutResult.OpaqueHitDistance = GlobalSDFTraceResultIsHit(SDFTraceResult) ? SDFTraceResult.HitTime : TraceInput.MaxTraceDistance;
OutResult.ExpandSurfaceAmount = SDFTraceResult.ExpandSurfaceAmount;
}
FGlobalSDFTraceResult RayTraceGlobalDistanceField(FGlobalSDFTraceInput TraceInput)
{
FGlobalSDFTraceResult TraceResult;
TraceResult.HitTime = -1.0f;
TraceResult.HitClipmapIndex = 0;
TraceResult.TotalStepsTaken = 0;
TraceResult.ExpandSurfaceAmount = 0;
float TraceNoise = InterleavedGradientNoise(TraceInput.DitherScreenCoord.xy, View_StateFrameIndexMod8);
uint MinClipmapIndex = ComputeGlobalDistanceFieldClipmapIndex(TraceInput.WorldRayStart + TraceInput.MinTraceDistance * TraceInput.WorldRayDirection);
float Max