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

118 lines
3.2 KiB
HLSL

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "../Common.ush"
#include "../SHCommon.ush"
/** Compile time settings to encode buffer to the denoiser. */
#define SSD_ENCODE_CLAMP_COLOR 0x1
#define SSD_ENCODE_NORMALIZE_MISS 0x2
#define SSD_ENCODE_NORMALIZE_COLOR 0x4
#define SSD_ENCODE_NORMALIZE (SSD_ENCODE_NORMALIZE_MISS | SSD_ENCODE_NORMALIZE_COLOR)
/** Compile time settings to decode buffer from the denoiser. */
#define SSD_DECODE_NORMALIZE 0x1
uint Compress2Floats(float2 v)
{
// f32tof16() is full rate on GCN.
return f32tof16(v.x) | (f32tof16(v.y) << 16);
}
float2 Uncompress2Floats(uint v)
{
// f16tof32() is full rate on GCN.
return float2(f16tof32(v), f16tof32(v >> 16));
}
uint2 Compress4Floats(float4 v)
{
return uint2(Compress2Floats(v.xy), Compress2Floats(v.zw));
}
float4 Uncompress4Floats(uint2 v)
{
return float4(Uncompress2Floats(v.x), Uncompress2Floats(v.y));
}
float4 f32x4tof16(float4 OutRawSample)
{
return float4(asfloat(Compress2Floats(OutRawSample.xy)), asfloat(Compress2Floats(OutRawSample.zw)), 0, 0);
}
// Encode a SIGNAL_BUFFER_LAYOUT_DIFFUSE_INDIRECT_HARMONIC formated buffer.
void EncodeDiffuseSphericalHarmonicTexel(
float SampleCount,
float MissCount,
FTwoBandSHVectorRGB ColorSH,
const uint Options,
out uint2 OutRawSample[4])
{
float2 UncompressedSample3;
UncompressedSample3.x = SampleCount;
float NormalizationFactor = SampleCount > 0.0 ? rcp(SampleCount) : 0.0;
if (Options & SSD_ENCODE_NORMALIZE_MISS)
{
UncompressedSample3.y = MissCount * NormalizationFactor;
}
else
{
UncompressedSample3.y = MissCount;
}
float ColorNormalizationFactor = 1.0;
if (Options & SSD_ENCODE_NORMALIZE_COLOR)
{
ColorNormalizationFactor = NormalizationFactor;
}
float4 UncompressedSample0 = ColorSH.R.V * ColorNormalizationFactor;
float4 UncompressedSample1 = ColorSH.G.V * ColorNormalizationFactor;
float4 UncompressedSample2 = ColorSH.B.V * ColorNormalizationFactor;
if (Options & SSD_ENCODE_CLAMP_COLOR)
{
UncompressedSample0 = min(UncompressedSample0, MaxHalfFloat);
UncompressedSample1 = min(UncompressedSample1, MaxHalfFloat);
UncompressedSample2 = min(UncompressedSample2, MaxHalfFloat);
}
OutRawSample[0] = Compress4Floats(UncompressedSample0);
OutRawSample[1] = Compress4Floats(UncompressedSample1);
OutRawSample[2] = Compress4Floats(UncompressedSample2);
OutRawSample[3] = uint2(Compress2Floats(UncompressedSample3), 0);
}
// Decodes a SIGNAL_BUFFER_LAYOUT_DIFFUSE_INDIRECT_HARMONIC formated buffer.
void DecodeDiffuseSphericalHarmonicTexel(
uint2 RawSample[4],
const uint Options,
out float OutSampleCount,
out float OutMissCount,
out FTwoBandSHVectorRGB OutColorSH)
{
float2 UncompressedSample3 = Uncompress2Floats(RawSample[3].x);
float Multiplier;
if (Options & SSD_DECODE_NORMALIZE)
{
Multiplier = 1.0;
OutSampleCount = UncompressedSample3.x > 0.0 ? 1.0 : 0.0;
}
else
{
Multiplier = UncompressedSample3.x;
OutSampleCount = Multiplier;
}
OutMissCount = UncompressedSample3.y * Multiplier;
OutColorSH.R.V = Uncompress4Floats(RawSample[0]) * Multiplier;
OutColorSH.G.V = Uncompress4Floats(RawSample[1]) * Multiplier;
OutColorSH.B.V = Uncompress4Floats(RawSample[2]) * Multiplier;
}