Files
UnrealEngine/Engine/Shaders/Private/Lumen/LumenCardTileShadowDownsampleFactor.ush
Brandyn / Techy fcc1b09210 init
2026-04-04 15:40:51 -05:00

108 lines
3.8 KiB
HLSL

// Copyright Epic Games, Inc. All Rights Reserved.
/*=============================================================================
LumenCardTileShadowDownsampleFactor.ush: Tracks whether surface tiles were uniformly shadowed in the last lighitng update
=============================================================================*/
#pragma once
#include "../Visualization.ush"
#define LUMEN_CARD_TILE_SHADOW_DOWNSAMPLE_FACTOR_DWORDS 8
#define LUMEN_CARD_TILE_SHADOW_DOWNSAMPLE_FACTOR_DWORDS_MASK (LUMEN_CARD_TILE_SHADOW_DOWNSAMPLE_FACTOR_DWORDS * 32 - 1u)
Buffer<uint> TileShadowDownsampleFactorAtlas;
bool LumenCardTileHasUniformVisibilityToLight(uint TileIndexInPhysicalAtlas, uint LightIndex)
{
uint BitIndex = LightIndex & LUMEN_CARD_TILE_SHADOW_DOWNSAMPLE_FACTOR_DWORDS_MASK;
uint DwordIndex = LUMEN_CARD_TILE_SHADOW_DOWNSAMPLE_FACTOR_DWORDS * TileIndexInPhysicalAtlas + BitIndex / 32;
uint MaskPart = TileShadowDownsampleFactorAtlas[DwordIndex];
return BitFieldExtractU32(MaskPart, 1, BitIndex % 32) != 0;
}
bool LumenCardTileHasUniformVisibilityToLight(uint2 TilePhysicalAtlasCoord, uint PhysicalAtlasWidthInTiles, uint LightIndex)
{
uint TileIndex = TilePhysicalAtlasCoord.y * PhysicalAtlasWidthInTiles + TilePhysicalAtlasCoord.x;
return LumenCardTileHasUniformVisibilityToLight(TileIndex, LightIndex);
}
struct FTileShadowDownsampleFactor
{
uint4 Data[2];
};
Buffer<uint4> TileShadowDownsampleFactorAtlasForResampling;
FTileShadowDownsampleFactor LoadLumenCardTileShadowDownsampleFactor(uint TileIndexInPhysicalAtlas)
{
uint ReadOffset = LUMEN_CARD_TILE_SHADOW_DOWNSAMPLE_FACTOR_DWORDS / 4 * TileIndexInPhysicalAtlas;
FTileShadowDownsampleFactor Factor;
Factor.Data[0] = TileShadowDownsampleFactorAtlasForResampling[ReadOffset];
Factor.Data[1] = TileShadowDownsampleFactorAtlasForResampling[ReadOffset + 1];
return Factor;
}
FTileShadowDownsampleFactor LoadLumenCardTileShadowDownsampleFactor(uint2 TilePhysicalAtlasCoord, uint PhysicalAtlasWidthInTiles)
{
uint TileIndex = TilePhysicalAtlasCoord.y * PhysicalAtlasWidthInTiles + TilePhysicalAtlasCoord.x;
return LoadLumenCardTileShadowDownsampleFactor(TileIndex);
}
float3 GetLumenCardTileShadowDownsampleFactorVisualizationColor(uint2 TilePhysicalAtlasCoord, uint PhysicalAtlasWidthInTiles)
{
FTileShadowDownsampleFactor Factor = LoadLumenCardTileShadowDownsampleFactor(TilePhysicalAtlasCoord, PhysicalAtlasWidthInTiles);
uint NumTrackedLights = 0;
for (uint Index = 0; Index < 4; ++Index)
{
NumTrackedLights += countbits(Factor.Data[0][Index]);
NumTrackedLights += countbits(Factor.Data[1][Index]);
}
float3 Color;
switch (NumTrackedLights)
{
case 0:
Color = float3(0.5, 0.5, 0.5);
break;
default:
Color = IntToColor(NumTrackedLights);
break;
}
return Color;
}
RWBuffer<uint4> RWTileShadowDownsampleFactorAtlas;
void WriteLumenCardTileShadowDownsampleFactor(FTileShadowDownsampleFactor Factor, uint TileIndexInPhysicalAtlas)
{
uint WriteOffset = LUMEN_CARD_TILE_SHADOW_DOWNSAMPLE_FACTOR_DWORDS / 4 * TileIndexInPhysicalAtlas;
RWTileShadowDownsampleFactorAtlas[WriteOffset] = Factor.Data[0];
RWTileShadowDownsampleFactorAtlas[WriteOffset + 1] = Factor.Data[1];
}
void WriteLumenCardTileShadowDownsampleFactor(FTileShadowDownsampleFactor Factor, uint2 TilePhysicalAtlasCoord, uint PhysicalAtlasWidthInTiles)
{
uint TileIndex = TilePhysicalAtlasCoord.y * PhysicalAtlasWidthInTiles + TilePhysicalAtlasCoord.x;
WriteLumenCardTileShadowDownsampleFactor(Factor, TileIndex);
}
void SetLumenCardTileShadowDownsampleFactorForLight(inout FTileShadowDownsampleFactor Factor, uint LightIndex)
{
uint BitIndex = LightIndex & LUMEN_CARD_TILE_SHADOW_DOWNSAMPLE_FACTOR_DWORDS_MASK;
uint DwordIndex = BitIndex / 32;
uint Mask = 1u << BitIndex % 32;
if (DwordIndex < 4)
{
Factor.Data[0][DwordIndex] |= Mask;
}
else
{
Factor.Data[1][DwordIndex - 4] |= Mask;
}
}