// Copyright Epic Games, Inc. All Rights Reserved. /*============================================================================= LumenRadianceCacheCommon.ush =============================================================================*/ #pragma once #define USED_PROBE_INDEX 0xFFFFFFFE #if !IS_MATERIAL_SHADER RWTexture3D 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); }