186 lines
4.0 KiB
HLSL
186 lines
4.0 KiB
HLSL
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "../Common.ush"
|
|
|
|
#define LUMEN_INVALID_PACKED_PIXEL_DATA 0x30
|
|
#define MEGALIGHTS_INVALID_PACKED_PIXEL_DATA 0x30
|
|
|
|
// Used for storing normal and shading info history data and used by:
|
|
// * LumenScreenProbeGather
|
|
// * MegaLightDenoiserTemporal
|
|
struct FNormalAndShadingInfo
|
|
{
|
|
float3 Normal;
|
|
bool bIsHair;
|
|
bool bHasBackfaceDiffuse;
|
|
};
|
|
|
|
float4 PackNormalAndShadingInfo(FNormalAndShadingInfo In)
|
|
{
|
|
// Storage format 10:10:10:2
|
|
const float3 PackedN = In.Normal * 0.5 + 0.5;
|
|
|
|
uint PackedA = In.bIsHair ? 0x1 : 0;
|
|
PackedA |= In.bHasBackfaceDiffuse ? 0x2 : 0;
|
|
|
|
return float4(PackedN, (PackedA + 0.5f) / 4.0f);
|
|
}
|
|
|
|
FNormalAndShadingInfo UnpackNormalAndShadingInfo(float4 In)
|
|
{
|
|
uint PackedA = In.w * 3.0f + 0.5f;
|
|
|
|
// Storage format 10:10:10:2
|
|
FNormalAndShadingInfo Out;
|
|
Out.Normal = In.xyz * 2 - 1;
|
|
Out.bIsHair = PackedA & 0x1 ? true : false;
|
|
Out.bHasBackfaceDiffuse = PackedA & 0x2 ? true : false;
|
|
return Out;
|
|
}
|
|
|
|
uint EncodeHistoryScreenCoord(float2 HistoryScreenCoord, float2 SubPixelGridSize)
|
|
{
|
|
float2 EncodeCoord = clamp(HistoryScreenCoord * SubPixelGridSize + 0.5f, 0.0f, 65535.0f);
|
|
return (uint(EncodeCoord.y) << 16) | uint(EncodeCoord.x);
|
|
}
|
|
|
|
float4 DecodeHistoryScreenCoord(uint Encoded, uint2 HistoryScreenCoordShift, float2 InvSubPixelGridSize)
|
|
{
|
|
uint2 EncodeCoord = uint2(Encoded & 0xFFFF, Encoded >> 16);
|
|
uint2 HistoryScreenCoord = EncodeCoord >> HistoryScreenCoordShift;
|
|
uint2 SubPixelCoord = EncodeCoord - (HistoryScreenCoord << HistoryScreenCoordShift);
|
|
float2 BilinearWeights = float2(SubPixelCoord) * InvSubPixelGridSize;
|
|
return float4(HistoryScreenCoord, BilinearWeights);
|
|
}
|
|
|
|
struct FLumenPackedPixelData
|
|
{
|
|
uint Packed;
|
|
|
|
void SetHistorySampleValidity(bool4 bSampleValid)
|
|
{
|
|
for (uint HistoryIndex = 0; HistoryIndex < 4; ++HistoryIndex)
|
|
{
|
|
Packed |= bSampleValid[HistoryIndex] ? 1u << HistoryIndex : 0;
|
|
}
|
|
}
|
|
|
|
bool4 GetHistorySampleValidity()
|
|
{
|
|
bool4 bHistoryValid;
|
|
for (uint HistoryIndex = 0; HistoryIndex < 4; ++HistoryIndex)
|
|
{
|
|
bHistoryValid[HistoryIndex] = (Packed & (1u << HistoryIndex)) != 0;
|
|
}
|
|
return bHistoryValid;
|
|
}
|
|
|
|
bool AnyHistoryValid()
|
|
{
|
|
return (Packed & 0xF) != 0;
|
|
}
|
|
|
|
void SetStochasticSampleOffset(uint2 Offset, bool bCanReconstruct)
|
|
{
|
|
if (bCanReconstruct)
|
|
{
|
|
Packed |= Offset.x << 4;
|
|
Packed |= Offset.y << 5;
|
|
Packed |= 1u << 6;
|
|
}
|
|
}
|
|
|
|
uint2 GetStochasticSampleOffset()
|
|
{
|
|
return select(bool2(Packed & (1u << 4), Packed & (1u << 5)), 1u, 0u);
|
|
}
|
|
|
|
bool HasValidStochasticSample()
|
|
{
|
|
return (Packed & (1u << 6)) != 0;
|
|
}
|
|
|
|
void SetHasBackfaceDiffuse(bool bBackfaceDiffuse)
|
|
{
|
|
Packed |= bBackfaceDiffuse ? 1u << 7 : 0;
|
|
}
|
|
|
|
bool HasBackfaceDiffuse()
|
|
{
|
|
return (Packed & (1u << 7)) != 0;
|
|
}
|
|
|
|
bool IsValid()
|
|
{
|
|
return Packed != LUMEN_INVALID_PACKED_PIXEL_DATA;
|
|
}
|
|
};
|
|
|
|
struct FMegaLightsPackedPixelData
|
|
{
|
|
uint Packed;
|
|
|
|
void SetHistorySampleValidity(bool4 bSampleValid)
|
|
{
|
|
for (uint HistoryIndex = 0; HistoryIndex < 4; ++HistoryIndex)
|
|
{
|
|
Packed |= bSampleValid[HistoryIndex] ? 1u << HistoryIndex : 0;
|
|
}
|
|
}
|
|
|
|
bool4 GetHistorySampleValidity()
|
|
{
|
|
bool4 bHistoryValid;
|
|
for (uint HistoryIndex = 0; HistoryIndex < 4; ++HistoryIndex)
|
|
{
|
|
bHistoryValid[HistoryIndex] = (Packed & (1u << HistoryIndex)) != 0;
|
|
}
|
|
return bHistoryValid;
|
|
}
|
|
|
|
bool AnyHistoryValid()
|
|
{
|
|
return (Packed & 0xF) != 0;
|
|
}
|
|
|
|
void SetStochasticSampleOffset(uint2 Offset, bool bCanReconstruct)
|
|
{
|
|
if (bCanReconstruct)
|
|
{
|
|
Packed |= Offset.x << 4;
|
|
Packed |= Offset.y << 5;
|
|
Packed |= 1u << 6;
|
|
}
|
|
}
|
|
|
|
uint2 GetStochasticSampleOffset()
|
|
{
|
|
return select(bool2(Packed & (1u << 4), Packed & (1u << 5)), 1u, 0u);
|
|
}
|
|
|
|
int2 GetStochasticSampleOffset(int2 SampleOffsets[4])
|
|
{
|
|
uint SampleOffsetIndex = BitFieldExtractU32(Packed, 2, 4);
|
|
return SampleOffsets[SampleOffsetIndex];
|
|
}
|
|
|
|
bool HasValidStochasticSample()
|
|
{
|
|
return (Packed & (1u << 6)) != 0;
|
|
}
|
|
|
|
void SetAnyHistoryDepthValid(bool bAnyValid)
|
|
{
|
|
Packed |= bAnyValid ? 1u << 7 : 0;
|
|
}
|
|
|
|
bool AnyHistoryDepthValid()
|
|
{
|
|
return (Packed & (1u << 7)) != 0;
|
|
}
|
|
|
|
bool IsValid()
|
|
{
|
|
return Packed != MEGALIGHTS_INVALID_PACKED_PIXEL_DATA;
|
|
}
|
|
}; |