108 lines
3.8 KiB
HLSL
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;
|
|
}
|
|
}
|