127 lines
4.8 KiB
HLSL
127 lines
4.8 KiB
HLSL
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*=============================================================================
|
|
LumenRadianceCacheCommon.ush
|
|
=============================================================================*/
|
|
|
|
#pragma once
|
|
|
|
#define USED_PROBE_INDEX 0xFFFFFFFE
|
|
|
|
#if !IS_MATERIAL_SHADER
|
|
RWTexture3D<uint> RWRadianceProbeIndirectionTexture;
|
|
#endif
|
|
|
|
|
|
#define RADIANCE_PROBE_MAX_CLIPMAPS 6
|
|
#define INVALID_PROBE_INDEX 0xFFFFFFFF
|
|
|
|
#if IS_MATERIAL_SHADER
|
|
#define GetRadianceProbeClipmapCornerTWSForMark(index) RadianceCacheMark.ClipmapCornerTWSAndCellSizeForMark[index].xyz
|
|
#define GetRadianceProbeClipmapCellSizeForMark(index) RadianceCacheMark.ClipmapCornerTWSAndCellSizeForMark[index].w
|
|
|
|
#define NumRadianceProbeClipmapsForMark RadianceCacheMark.NumRadianceProbeClipmapsForMark
|
|
#define RadianceProbeClipmapResolutionForMark RadianceCacheMark.RadianceProbeClipmapResolutionForMark
|
|
#define InvClipmapFadeSizeForMark RadianceCacheMark.InvClipmapFadeSizeForMark
|
|
|
|
#else
|
|
float4 ClipmapCornerTWSAndCellSizeForMark[RADIANCE_PROBE_MAX_CLIPMAPS];
|
|
|
|
#define GetRadianceProbeClipmapCornerTWSForMark(index) ClipmapCornerTWSAndCellSizeForMark[index].xyz
|
|
#define GetRadianceProbeClipmapCellSizeForMark(index) ClipmapCornerTWSAndCellSizeForMark[index].w
|
|
|
|
|
|
uint NumRadianceProbeClipmapsForMark;
|
|
uint RadianceProbeClipmapResolutionForMark;
|
|
float InvClipmapFadeSizeForMark;
|
|
#endif
|
|
|
|
|
|
struct FRadianceProbeCoord
|
|
{
|
|
uint3 ProbeMinCoord;
|
|
uint3 ProbeMaxCoord;
|
|
uint ClipmapIndex;
|
|
};
|
|
|
|
bool IsValidRadianceCacheClipmapForMark(uint InClipmapIndex)
|
|
{
|
|
return InClipmapIndex < NumRadianceProbeClipmapsForMark;
|
|
}
|
|
|
|
float3 GetRadianceProbeCoordFloatForMark(float3 ProbeWorldPosition, uint ClipmapIndex)
|
|
{
|
|
const float3 ProbeTranslatedWorldPosition = ProbeWorldPosition + DFHackToFloat(PrimaryView.PreViewTranslation); // LUMEN_LWC_TODO
|
|
|
|
const float3 CornerTranslatedWorldPosition = GetRadianceProbeClipmapCornerTWSForMark(ClipmapIndex);
|
|
const float3 CornerToProbe = ProbeTranslatedWorldPosition - CornerTranslatedWorldPosition;
|
|
const float CellSize = GetRadianceProbeClipmapCellSizeForMark(ClipmapIndex);
|
|
return CornerToProbe / CellSize;
|
|
}
|
|
|
|
FRadianceProbeCoord GetRadianceProbeCoord(float3 WorldPosition, float ClipmapDitherRandom)
|
|
{
|
|
FRadianceProbeCoord Out = (FRadianceProbeCoord)0;
|
|
Out.ClipmapIndex = NumRadianceProbeClipmapsForMark;
|
|
|
|
uint ClipmapIndex = 0;
|
|
for (; ClipmapIndex < NumRadianceProbeClipmapsForMark; ++ClipmapIndex)
|
|
{
|
|
float3 ProbeCoordFloat = GetRadianceProbeCoordFloatForMark(WorldPosition, ClipmapIndex);
|
|
float3 BottomEdgeFades = saturate((ProbeCoordFloat - .5f) * InvClipmapFadeSizeForMark);
|
|
float3 TopEdgeFades = saturate(((float3)RadianceProbeClipmapResolutionForMark - .5f - ProbeCoordFloat) * InvClipmapFadeSizeForMark);
|
|
float EdgeFade = min(min3(BottomEdgeFades.x, BottomEdgeFades.y, BottomEdgeFades.z), min3(TopEdgeFades.x, TopEdgeFades.y, TopEdgeFades.z));
|
|
|
|
int3 ProbeMinCoord;
|
|
int3 ProbeMaxCoord;
|
|
|
|
ProbeMinCoord = floor(ProbeCoordFloat - 0.5f);
|
|
ProbeMaxCoord = ProbeMinCoord + 1;
|
|
|
|
if (EdgeFade > ClipmapDitherRandom)
|
|
{
|
|
Out.ProbeMinCoord = ProbeMinCoord;
|
|
Out.ProbeMaxCoord = ProbeMaxCoord;
|
|
Out.ClipmapIndex = ClipmapIndex;
|
|
return Out;
|
|
}
|
|
}
|
|
|
|
return Out;
|
|
}
|
|
|
|
uint GetRadianceProbeClipmapForMark(float3 WorldPosition, float ClipmapDitherRandom)
|
|
{
|
|
FRadianceProbeCoord Cell = GetRadianceProbeCoord(WorldPosition, ClipmapDitherRandom);
|
|
return Cell.ClipmapIndex;
|
|
}
|
|
|
|
uint GetRadianceProbeClipmapForMark(float3 WorldPosition)
|
|
{
|
|
return GetRadianceProbeClipmapForMark(WorldPosition, .01f);
|
|
}
|
|
|
|
void MarkProbeIndirectionTextureCoord(int3 ProbeCoord, uint ClipmapIndex)
|
|
{
|
|
if (all(ProbeCoord >= 0) && all(ProbeCoord < (int3)RadianceProbeClipmapResolutionForMark) && ClipmapIndex < NumRadianceProbeClipmapsForMark)
|
|
{
|
|
int3 IndirectionTextureCoord = ProbeCoord + int3(ClipmapIndex * RadianceProbeClipmapResolutionForMark, 0, 0);
|
|
RWRadianceProbeIndirectionTexture[IndirectionTextureCoord] = USED_PROBE_INDEX;
|
|
}
|
|
}
|
|
|
|
void MarkPositionUsedInIndirectionTexture(float3 WorldPosition, uint ClipmapIndex)
|
|
{
|
|
float3 ProbeCoordFloat = GetRadianceProbeCoordFloatForMark(WorldPosition, ClipmapIndex);
|
|
int3 BottomCornerProbeCoord = floor(ProbeCoordFloat - 0.5f);
|
|
|
|
MarkProbeIndirectionTextureCoord(BottomCornerProbeCoord + int3(0, 0, 0), ClipmapIndex);
|
|
MarkProbeIndirectionTextureCoord(BottomCornerProbeCoord + int3(0, 0, 1), ClipmapIndex);
|
|
MarkProbeIndirectionTextureCoord(BottomCornerProbeCoord + int3(0, 1, 0), ClipmapIndex);
|
|
MarkProbeIndirectionTextureCoord(BottomCornerProbeCoord + int3(0, 1, 1), ClipmapIndex);
|
|
MarkProbeIndirectionTextureCoord(BottomCornerProbeCoord + int3(1, 0, 0), ClipmapIndex);
|
|
MarkProbeIndirectionTextureCoord(BottomCornerProbeCoord + int3(1, 0, 1), ClipmapIndex);
|
|
MarkProbeIndirectionTextureCoord(BottomCornerProbeCoord + int3(1, 1, 0), ClipmapIndex);
|
|
MarkProbeIndirectionTextureCoord(BottomCornerProbeCoord + int3(1, 1, 1), ClipmapIndex);
|
|
}
|