Files
UnrealEngine/Engine/Shaders/Private/RayTracing/RayTracingGatherPoints.ush
2025-05-18 13:04:45 +08:00

103 lines
3.0 KiB
HLSL

// Copyright Epic Games, Inc. All Rights Reserved.
#define MAXIMUM_GATHER_POINTS_PER_PIXEL 32
struct FGatherPoints
{
float3 TranslatedCreationPoint;
float3 TranslatedPosition;
uint2 Irradiance;
};
struct FGatherSample
{
float3 TranslatedCreationPoint;
float3 TranslatedPosition;
float3 Irradiance;
float Pdf;
};
struct FRejectionCriteria
{
float3 TranslatedCreationPoint;
float DistanceThreshold2;
};
uint2 PackIrradiance(float3 Irradiance, float Pdf)
{
uint2 Packed = (uint2)0;
Irradiance = ClampToHalfFloatRange(Irradiance);
// Note: Consider keeping Lumiance(Y) in full range
Packed.x = f32tof16(Irradiance.x) | (f32tof16(Irradiance.y) << 16);
Packed.y = f32tof16(Irradiance.z) | (f32tof16(Pdf) << 16);
return Packed;
}
float3 UnpackIrradiance(uint2 Irradiance, inout float Pdf)
{
float3 Unpacked;
Unpacked.x = f16tof32(Irradiance.x & 0xffff);
Unpacked.y = f16tof32(Irradiance.x >> 16);
Unpacked.z = f16tof32(Irradiance.y & 0xffff);
Pdf = f16tof32(Irradiance.y >> 16);
return Unpacked;
}
FGatherSample ReadGatherSample(StructuredBuffer<FGatherPoints> GatherBuffer, uint BaseIndex, uint SampleIndex, uint ElementCount)
{
FGatherSample GatherSample = (FGatherSample) 0.0;
uint Index = BaseIndex + SampleIndex * ElementCount;
GatherSample.TranslatedCreationPoint = GatherBuffer[Index].TranslatedCreationPoint;
GatherSample.TranslatedPosition = GatherBuffer[Index].TranslatedPosition;
GatherSample.Irradiance = UnpackIrradiance(GatherBuffer[Index].Irradiance, GatherSample.Pdf);
return GatherSample;
}
void WriteGatherSample(RWStructuredBuffer<FGatherPoints> GatherBuffer, uint BaseIndex, uint SampleIndex, uint ElementCount, FGatherSample GatherSample)
{
uint Index = BaseIndex + SampleIndex * ElementCount;
GatherBuffer[Index].TranslatedCreationPoint = GatherSample.TranslatedCreationPoint;
GatherBuffer[Index].TranslatedPosition = GatherSample.TranslatedPosition;
GatherBuffer[Index].Irradiance = PackIrradiance(GatherSample.Irradiance, GatherSample.Pdf);
}
FRejectionCriteria CreateRejectionCriteria(float3 TranslatedCreationPoint, float DistanceThreshold)
{
FRejectionCriteria RejectionCriteria;
RejectionCriteria.TranslatedCreationPoint = TranslatedCreationPoint;
RejectionCriteria.DistanceThreshold2 = DistanceThreshold * DistanceThreshold;
return RejectionCriteria;
}
void CreateRejectionMask(
FRejectionCriteria RejectionCriteria,
StructuredBuffer<FGatherPoints> GatherBuffer,
uint BaseIndex,
uint SampleIndex,
uint ElementCount,
int SampleCount,
out bool bShouldReject[MAXIMUM_GATHER_POINTS_PER_PIXEL]
)
{
{
for (int Index = 0; Index < SampleCount; ++Index)
{
FGatherSample GatherSample = ReadGatherSample(GatherBuffer, BaseIndex, SampleIndex + Index, ElementCount);
float3 GPDistance2 = RejectionCriteria.TranslatedCreationPoint - GatherSample.TranslatedCreationPoint;
bShouldReject[Index] = dot(GPDistance2, GPDistance2) > RejectionCriteria.DistanceThreshold2;
}
}
{
for (int Index = SampleCount; Index < MAXIMUM_GATHER_POINTS_PER_PIXEL; ++Index)
{
bShouldReject[Index] = true;
}
}
}