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

154 lines
3.9 KiB
HLSL

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#define AVSM_NULL_PTR 0xFF
struct FAVSMSampleData
{
float X;
float Tau;
};
#define AVSM_INVALID_PIXEL_OFFSET 0x3FFFFFF
struct FAVSMIndirectionData
{
uint PixelOffset;
int SampleCount;
float BeginX;
float EndX;
};
/* AVSM Sample Data API */
FAVSMSampleData AVSM_CreateSampleData(float X, float Tau)
{
FAVSMSampleData SampleData;
SampleData.X = X;
SampleData.Tau = Tau;
return SampleData;
}
FAVSMSampleData AVSM_CreateSampleData(float X, float3 Transmittance)
{
return AVSM_CreateSampleData(X, Luminance(Transmittance));
}
uint AVSM_PackSampleDataX(float X, FAVSMIndirectionData IndirectionData)
{
float Extent = IndirectionData.EndX - IndirectionData.BeginX;
float NormalizedX = (X - IndirectionData.BeginX) / Extent;
uint FixedX = saturate(NormalizedX) * MaxHalfFloat;
return FixedX;
}
float AVSM_UnpackSampleDataX(uint FixedX, FAVSMIndirectionData IndirectionData)
{
float Extent = IndirectionData.EndX - IndirectionData.BeginX;
float NormalizedX = FixedX / MaxHalfFloat;
float X = saturate(NormalizedX) * Extent + IndirectionData.BeginX;
return X;
}
int AVSM_PackSampleData(FAVSMSampleData SampleData, FAVSMIndirectionData IndirectionData)
{
int PackedData = 0;
PackedData |= AVSM_PackSampleDataX(SampleData.X, IndirectionData);
PackedData |= f32tof16(SampleData.Tau) << 16;
return PackedData;
}
FAVSMSampleData AVSM_UnpackSampleData(int PackedData, FAVSMIndirectionData IndirectionData)
{
FAVSMSampleData SampleData;
SampleData.X = AVSM_UnpackSampleDataX(PackedData & 0xFFFF, IndirectionData);
SampleData.Tau = f16tof32(PackedData >> 16);
return SampleData;
}
int AVSM_PackSampleData(float X, float Tau, FAVSMIndirectionData IndirectionData)
{
return AVSM_PackSampleData(AVSM_CreateSampleData(X, Tau), IndirectionData);
}
/* AVSM Linked List API */
FAVSMSampleData AVSM_GetLinkedListSampleData(uint2 PackedData)
{
FAVSMSampleData SampleData;
SampleData.X = asfloat(PackedData.x);
SampleData.Tau = f16tof32(PackedData.y >> 16);
return SampleData;
}
void AVSM_SetLinkedListSampleData(inout uint2 PackedData, FAVSMSampleData SampleData)
{
PackedData.x = asuint(SampleData.X);
PackedData.y = (PackedData.y & 0xFFFF) |
(f32tof16(SampleData.Tau) << 16);
}
uint AVSM_GetLinkedListPrevPtr(uint2 PackedData)
{
return (PackedData.y >> 8) & AVSM_NULL_PTR;
}
uint AVSM_GetLinkedListNextPtr(uint2 PackedData)
{
return PackedData.y & AVSM_NULL_PTR;
}
void AVSM_SetLinkedListPrevPtr(inout uint2 PackedData, uint PrevPtr)
{
PackedData.y = (PackedData.y & 0xFFFF00FF) |
((PrevPtr & AVSM_NULL_PTR) << 8);
}
void AVSM_SetLinkedListNextPtr(inout uint2 PackedData, uint NextPtr)
{
PackedData.y = (PackedData.y & 0xFFFFFF00) |
(NextPtr & AVSM_NULL_PTR);
}
/* AVSM Indirection Data API */
FAVSMIndirectionData AVSM_CreateIndirectionData(uint PixelOffset, int SampleCount, float BeginX, float EndX)
{
FAVSMIndirectionData IndirectionData;
IndirectionData.PixelOffset = PixelOffset;
IndirectionData.SampleCount = SampleCount;
IndirectionData.BeginX = BeginX;
IndirectionData.EndX = EndX;
return IndirectionData;
}
uint4 AVSM_PackIndirectionData(FAVSMIndirectionData IndirectionData)
{
uint4 PackedData = 0;
PackedData.x = ((IndirectionData.PixelOffset & AVSM_INVALID_PIXEL_OFFSET) << 6) | (IndirectionData.SampleCount & 0x3f);
PackedData.y = asuint(IndirectionData.BeginX);
PackedData.z = asuint(IndirectionData.EndX);
return PackedData;
}
FAVSMIndirectionData AVSM_UnpackIndirectionData(uint4 PackedData)
{
FAVSMIndirectionData IndirectionData;
IndirectionData.PixelOffset = (PackedData.x >> 6) & AVSM_INVALID_PIXEL_OFFSET;
IndirectionData.SampleCount = PackedData.x & 0x3f;
IndirectionData.BeginX = asfloat(PackedData.y);
IndirectionData.EndX = asfloat(PackedData.z);
return IndirectionData;
}
int Align4(int Value)
{
return (Value + 3) & ~3;
}
int CalcTopLevelSampleCount(int SampleCount)
{
int TopLevelSampleCount = Align4(SampleCount) >> 2;
return TopLevelSampleCount;
}