174 lines
5.4 KiB
HLSL
174 lines
5.4 KiB
HLSL
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*=============================================================================
|
|
LumenCardTiles.ush
|
|
=============================================================================*/
|
|
|
|
#pragma once
|
|
|
|
#include "/Engine/Shared/LumenDefinitions.h"
|
|
|
|
#define CARD_TILE_SIZE 8
|
|
#define NULL_PACKED_CARD_TILE 0xFFFFFFFF
|
|
|
|
struct FCardTileData
|
|
{
|
|
uint CardPageIndex;
|
|
uint2 TileCoord;
|
|
};
|
|
|
|
FCardTileData UnpackCardTileData(uint PackedTile)
|
|
{
|
|
FCardTileData TileData;
|
|
TileData.CardPageIndex = PackedTile & 0xFFFFFF;
|
|
TileData.TileCoord.x = (PackedTile >> 24) & 0xF;
|
|
TileData.TileCoord.y = (PackedTile >> 28) & 0xF;
|
|
return TileData;
|
|
}
|
|
|
|
uint PackCardTileData(FCardTileData CardTile)
|
|
{
|
|
uint PackedTile = CardTile.CardPageIndex;
|
|
PackedTile |= (CardTile.TileCoord.x << 24);
|
|
PackedTile |= (CardTile.TileCoord.y << 28);
|
|
return PackedTile;
|
|
}
|
|
|
|
struct FLightTileForCompactionPass
|
|
{
|
|
uint LightIndex;
|
|
uint ViewIndex;
|
|
uint bHasShadowMask;
|
|
uint CardTileIndex;
|
|
uint CulledLightIndex;
|
|
uint LightType;
|
|
};
|
|
|
|
struct FLightTileForShadowMaskPass
|
|
{
|
|
uint LightIndex;
|
|
uint ViewIndex;
|
|
uint CardPageIndex;
|
|
uint2 TileCoord;
|
|
};
|
|
|
|
struct FLightTileForLightPass
|
|
{
|
|
uint LightIndex;
|
|
uint ViewIndex;
|
|
uint ShadowMaskIndex;
|
|
};
|
|
|
|
FLightTileForCompactionPass UnpackLightTileForCompactionPass(uint2 PackedTile)
|
|
{
|
|
FLightTileForCompactionPass Tile;
|
|
Tile.LightIndex = BitFieldExtractU32(PackedTile.x, 28, 0);
|
|
Tile.ViewIndex = BitFieldExtractU32(PackedTile.x, 3, 28);
|
|
Tile.bHasShadowMask = BitFieldExtractU32(PackedTile.x, 1, 31);
|
|
Tile.CardTileIndex = BitFieldExtractU32(PackedTile.y, 24, 0);
|
|
Tile.CulledLightIndex = BitFieldExtractU32(PackedTile.y, 6, 24);
|
|
Tile.LightType = BitFieldExtractU32(PackedTile.y, 2, 30);
|
|
return Tile;
|
|
}
|
|
|
|
FLightTileForShadowMaskPass UnpackLightTileForShadowMaskPass(uint2 PackedTile)
|
|
{
|
|
FLightTileForShadowMaskPass Tile;
|
|
Tile.LightIndex = BitFieldExtractU32(PackedTile.x, 28, 0);
|
|
Tile.ViewIndex = BitFieldExtractU32(PackedTile.x, 4, 28);
|
|
Tile.CardPageIndex = BitFieldExtractU32(PackedTile.y, 24, 0);
|
|
Tile.TileCoord.x = BitFieldExtractU32(PackedTile.y, 4, 24);
|
|
Tile.TileCoord.y = BitFieldExtractU32(PackedTile.y, 4, 28);
|
|
return Tile;
|
|
}
|
|
|
|
FLightTileForLightPass UnpackLightTileForLightPass(uint2 PackedTile)
|
|
{
|
|
FLightTileForLightPass Tile;
|
|
Tile.LightIndex = BitFieldExtractU32(PackedTile.x, 28, 0);
|
|
Tile.ViewIndex = BitFieldExtractU32(PackedTile.x, 4, 28);
|
|
Tile.ShadowMaskIndex = PackedTile.y;
|
|
return Tile;
|
|
}
|
|
|
|
uint2 PackLightTileForCompactionPass(FLightTileForCompactionPass Tile)
|
|
{
|
|
uint2 PackedTile;
|
|
PackedTile.x = Tile.LightIndex | (Tile.ViewIndex << 28) | (Tile.bHasShadowMask << 31);
|
|
PackedTile.y = Tile.CardTileIndex | (Tile.CulledLightIndex << 24) | (Tile.LightType << 30);
|
|
return PackedTile;
|
|
}
|
|
|
|
uint2 PackLightTileForShadowMaskPass(FLightTileForShadowMaskPass Tile)
|
|
{
|
|
uint2 PackedTile;
|
|
PackedTile.x = Tile.LightIndex | (Tile.ViewIndex << 28);
|
|
PackedTile.y = Tile.CardPageIndex;
|
|
PackedTile.y |= (Tile.TileCoord.x << 24);
|
|
PackedTile.y |= (Tile.TileCoord.y << 28);
|
|
return PackedTile;
|
|
}
|
|
|
|
uint2 PackLightTileForLightPass(FLightTileForLightPass Tile)
|
|
{
|
|
uint2 PackedTile;
|
|
PackedTile.x = Tile.LightIndex | (Tile.ViewIndex << 28);
|
|
PackedTile.y = Tile.ShadowMaskIndex;
|
|
return PackedTile;
|
|
}
|
|
|
|
float4x4 FrustumTranslatedWorldToClip[LUMEN_MAX_VIEWS];
|
|
float4 PreViewTranslationHigh[LUMEN_MAX_VIEWS];
|
|
float4 PreViewTranslationLow[LUMEN_MAX_VIEWS];
|
|
float2 ViewExposure;
|
|
|
|
FDFVector3 GetPreViewTranslation(uint ViewIndex)
|
|
{
|
|
return MakeDFVector3(PreViewTranslationHigh[ViewIndex].xyz, PreViewTranslationLow[ViewIndex].xyz);
|
|
}
|
|
|
|
uint GetCardViewIndex(FLumenCardPageData CardPage, FLumenCardData Card, float2 UVMin, float2 UVMax, float2 CardTileDepthRange, uint NumViews, bool bPrioritizeWhenInFrustum)
|
|
{
|
|
float3 CardPageLocalCenter;
|
|
float3 CardPageLocalExtent;
|
|
GetCardLocalBBox(CardPage, Card, UVMin, UVMax, CardTileDepthRange, CardPageLocalCenter, CardPageLocalExtent);
|
|
|
|
uint ViewIndex = 0;
|
|
|
|
if (NumViews > 1)
|
|
{
|
|
FDFVector3 PreViewTranslation0 = GetPreViewTranslation(0);
|
|
FDFVector3 PreViewTranslation1 = GetPreViewTranslation(1);
|
|
float3 CardTranslatedWorldOrigin0 = DFFastToTranslatedWorld(Card.Origin, PreViewTranslation0);
|
|
float3 CardTranslatedWorldOrigin1 = DFFastToTranslatedWorld(Card.Origin, PreViewTranslation1);
|
|
float View0Distance = length(CardTranslatedWorldOrigin0);
|
|
float View1Distance = length(CardTranslatedWorldOrigin1);
|
|
|
|
#define IN_FRUSTUM_DISTANCE 1
|
|
#if IN_FRUSTUM_DISTANCE
|
|
float3 CardPageRotated = mul(Card.WorldToLocalRotation, CardPageLocalCenter);
|
|
float3 CardPageTranslatedWorldCenter0 = CardPageRotated + CardTranslatedWorldOrigin0;
|
|
float3 CardPageTranslatedWorldCenter1 = CardPageRotated + CardTranslatedWorldOrigin1;
|
|
|
|
if (bPrioritizeWhenInFrustum)
|
|
{
|
|
float4 CardOriginClipSpace0 = mul(float4(CardPageTranslatedWorldCenter0, 1.0f), FrustumTranslatedWorldToClip[0]);
|
|
|
|
if (all(CardOriginClipSpace0.xy >= CardOriginClipSpace0.w) && all(CardOriginClipSpace0.xy <= CardOriginClipSpace0.w) && CardOriginClipSpace0.z < 1.0f)
|
|
{
|
|
View0Distance = .5f * CardOriginClipSpace0.w;
|
|
}
|
|
|
|
float4 CardOriginClipSpace1 = mul(float4(CardPageTranslatedWorldCenter1, 1.0f), FrustumTranslatedWorldToClip[1]);
|
|
|
|
if (all(CardOriginClipSpace1.xy >= CardOriginClipSpace1.w) && all(CardOriginClipSpace1.xy <= CardOriginClipSpace1.w) && CardOriginClipSpace1.z < 1.0f)
|
|
{
|
|
View1Distance = .5f * CardOriginClipSpace1.w;
|
|
}
|
|
}
|
|
#endif
|
|
ViewIndex = View0Distance < View1Distance ? 0 : 1;
|
|
}
|
|
|
|
return ViewIndex;
|
|
} |