134 lines
4.8 KiB
HLSL
134 lines
4.8 KiB
HLSL
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "../Common.ush"
|
|
#include "LumenCardCommon.ush"
|
|
#include "LumenCardTile.ush"
|
|
#include "LumenCardTileShadowDownsampleFactor.ush"
|
|
#include "SurfaceCache/LumenSurfaceCache.ush"
|
|
#define SUPPORT_CONTACT_SHADOWS 0
|
|
#define USE_IES_PROFILE 1
|
|
#include "../DeferredLightingCommon.ush"
|
|
#include "../VolumeLightingCommon.ush"
|
|
#define FILTER_DIRECTIONAL_LIGHT_SHADOWING 1
|
|
#include "../ForwardShadowingCommon.ush"
|
|
#include "LumenSceneDirectLighting.ush"
|
|
#include "LumenFloatQuantization.ush"
|
|
|
|
FDeferredLightData GetLumenDirectLightingLightData(uint LightIndex, float3 PreViewTranslation, float Exposure)
|
|
{
|
|
FDeferredLightData Out;
|
|
|
|
#if USE_LIGHT_UNIFORM_BUFFER
|
|
Out = InitDeferredLightFromUniforms(LIGHT_TYPE);
|
|
#else
|
|
FLumenLight LumenLight = LoadLumenLight(LightIndex, PreViewTranslation, Exposure);
|
|
Out = LumenLight.DeferredLightData;
|
|
Out.bRectLight = HAS_RECT_LIGHTS && Out.bRectLight;
|
|
#endif
|
|
return Out;
|
|
}
|
|
|
|
float3 GetIrradianceForLight(
|
|
uint LightIndex,
|
|
FLumenSurfaceCacheData SurfaceCacheData,
|
|
float3 PreViewTranslation, // LUMEN_LWC_TODO
|
|
float Exposure,
|
|
float3 ShadowFactor)
|
|
{
|
|
FDeferredLightData LightData = GetLumenDirectLightingLightData(LightIndex, PreViewTranslation, Exposure);
|
|
float3 TranslatedWorldPosition = SurfaceCacheData.WorldPosition + PreViewTranslation;
|
|
return GetIrradianceForLight(LightData, SurfaceCacheData.WorldNormal, TranslatedWorldPosition, true /*bSupportRectLight*/) * ShadowFactor;
|
|
}
|
|
|
|
#ifndef HAS_MULTIPLE_VIEWS
|
|
#define HAS_MULTIPLE_VIEWS 0
|
|
#endif
|
|
|
|
RWTexture2D<float3> RWDirectLightingAtlas;
|
|
StructuredBuffer<uint> CardTiles;
|
|
StructuredBuffer<uint> LightTileOffsetNumPerCardTile;
|
|
StructuredBuffer<uint2> LightTilesPerCardTile;
|
|
|
|
float CachedLightingPreExposure;
|
|
|
|
#if WAVE_OP_WAVE_SIZE > 0 && COMPILER_SUPPORTS_WAVE_SIZE
|
|
WAVESIZE(WAVE_OP_WAVE_SIZE)
|
|
#endif
|
|
[numthreads(CARD_TILE_SIZE, CARD_TILE_SIZE, 1)]
|
|
void LumenCardBatchDirectLightingCS(
|
|
uint3 GroupId : SV_GroupID,
|
|
uint3 GroupThreadId : SV_GroupThreadID)
|
|
{
|
|
uint CardTileIndex = GroupId.x;
|
|
uint2 TexelCoordInTile = GroupThreadId.xy;
|
|
|
|
uint PackedOffsetNum = LightTileOffsetNumPerCardTile[CardTileIndex];
|
|
uint LightTilesOffset = BitFieldExtractU32(PackedOffsetNum, 24, 0);
|
|
uint NumLightTiles = BitFieldExtractU32(PackedOffsetNum, 8, 24);
|
|
|
|
FCardTileData CardTile = UnpackCardTileData(CardTiles[CardTileIndex]);
|
|
FLumenCardPageData CardPage = GetLumenCardPageData(CardTile.CardPageIndex);
|
|
|
|
uint2 CoordInCardPage = CARD_TILE_SIZE * CardTile.TileCoord + TexelCoordInTile;
|
|
uint2 AtlasCoord = CardPage.PhysicalAtlasCoord + CoordInCardPage;
|
|
|
|
float2 AtlasUV = CardPage.PhysicalAtlasUVRect.xy + CardPage.PhysicalAtlasUVTexelScale * (CoordInCardPage + 0.5);
|
|
float2 CardUV = CardPage.CardUVRect.xy + CardPage.CardUVTexelScale * (CoordInCardPage + 0.5);
|
|
|
|
FLumenCardData Card = GetLumenCardData(CardPage.CardIndex);
|
|
FLumenSurfaceCacheData SurfaceCacheData = GetSurfaceCacheData(Card, CardUV, AtlasUV);
|
|
|
|
if (NumLightTiles == 0 || !SurfaceCacheData.bValid)
|
|
{
|
|
RWDirectLightingAtlas[AtlasCoord] = 0;
|
|
return;
|
|
}
|
|
|
|
float3 Irradiance = 0.0f;
|
|
uint4 TileShadowDownsampleFactorLow = 0;
|
|
uint4 TileShadowDownsampleFactorHigh = 0;
|
|
|
|
for (uint CulledLightIndex = 0; CulledLightIndex < NumLightTiles; ++CulledLightIndex)
|
|
{
|
|
FLightTileForLightPass LightTile = UnpackLightTileForLightPass(LightTilesPerCardTile[LightTilesOffset + CulledLightIndex]);
|
|
|
|
FShadowMaskRay ShadowMaskRay;
|
|
ShadowMaskRay.bShadowFactorComplete = true;
|
|
ShadowMaskRay.ShadowFactor = 1.0f;
|
|
|
|
if (LightTile.ShadowMaskIndex != 0xffffffff)
|
|
{
|
|
ReadShadowMaskRay(LightTile.ShadowMaskIndex, TexelCoordInTile, ShadowMaskRay);
|
|
}
|
|
|
|
if (any(ShadowMaskRay.ShadowFactor > 0.0f))
|
|
{
|
|
uint ViewIndex = HAS_MULTIPLE_VIEWS ? LightTile.ViewIndex : 0;
|
|
const FDFVector3 PreViewTranslation = GetPreViewTranslation(ViewIndex);
|
|
Irradiance += GetIrradianceForLight(LightTile.LightIndex, SurfaceCacheData, DFHackToFloat(PreViewTranslation), ViewExposure[ViewIndex], ShadowMaskRay.ShadowFactor);
|
|
|
|
//Irradiance += bShadowFactorValid ? float3(0, 1, 0) : float3(0.2f, 0.0f, 0.0f);
|
|
}
|
|
|
|
#if WAVE_OP_WAVE_SIZE == 64
|
|
if (WaveActiveAllTrue(!IsVisibleToLight(ShadowMaskRay.ShadowFactor)) || WaveActiveAllTrue(IsVisibleToLight(ShadowMaskRay.ShadowFactor)))
|
|
{
|
|
SetLumenCardTileShadowDownsampleFactorForLight(TileShadowDownsampleFactorLow, TileShadowDownsampleFactorHigh, LightTile.LightIndex);
|
|
}
|
|
#elif WAVE_OP_WAVE_SIZE == 32
|
|
// TODO: add wave32 support
|
|
#endif
|
|
}
|
|
|
|
#if WAVE_OP_WAVE_SIZE == 64
|
|
if (WaveIsFirstLane())
|
|
#elif WAVE_OP_WAVE_SIZE == 32
|
|
// TODO: add wave32 support
|
|
#endif
|
|
{
|
|
WriteLumenCardTileShadowDownsampleFactor(TileShadowDownsampleFactorLow, TileShadowDownsampleFactorHigh, AtlasCoord / CARD_TILE_SIZE, LumenCardScene.PhysicalAtlasSize.x / CARD_TILE_SIZE);
|
|
}
|
|
|
|
RWDirectLightingAtlas[AtlasCoord] = QuantizeForFloatRenderTarget(Irradiance * CachedLightingPreExposure, int3(AtlasCoord, View.StateFrameIndexMod8 + 1));
|
|
}
|