Files
UnrealEngineUWP/Engine/Shaders/Private/LightGridCommon.ush
charles derousiers e13a7edf29 Add cluster shadring permutation for applying hair shadow on top of opaque geometries.
#rb none
#jira none
[FYI] andrew.lauritzen

#ROBOMERGE-SOURCE: CL 15846760 in //UE5/Release-5.0-EarlyAccess/...
#ROBOMERGE-BOT: STARSHIP (Release-5.0-EarlyAccess -> Main) (v786-15839533)

[CL 15846763 by charles derousiers in ue5-main branch]
2021-03-28 14:38:43 -04:00

245 lines
8.2 KiB
Plaintext

// Copyright Epic Games, Inc. All Rights Reserved.
/*=============================================================================
LightGridCommon.ush
=============================================================================*/
// TODO: This is clearly not the right place for these defines! Ideally ought to be exposed from engine somehow...
#define LIGHT_TYPE_DIRECTIONAL 0
#define LIGHT_TYPE_POINT 1
#define LIGHT_TYPE_SPOT 2
#define LIGHT_TYPE_RECT 3
#define LIGHT_TYPE_MAX 4
#if INSTANCED_STEREO
#if MATERIALBLENDING_ANY_TRANSLUCENT
#define ForwardLightDataISR TranslucentBasePass.Shared.ForwardISR
#else
#define ForwardLightDataISR OpaqueBasePass.Shared.ForwardISR
#endif
#endif
struct FLightGridData
{
uint LightGridPixelSizeShift;
float3 LightGridZParams;
int3 CulledGridSize;
};
FLightGridData GetLightGridData(uint EyeIndex)
{
FLightGridData Result;
#if INSTANCED_STEREO
BRANCH
if (EyeIndex == 0)
{
#endif
Result.LightGridPixelSizeShift = ForwardLightData.LightGridPixelSizeShift;
Result.LightGridZParams = ForwardLightData.LightGridZParams;
Result.CulledGridSize = ForwardLightData.CulledGridSize;
#if INSTANCED_STEREO
}
else
{
Result.LightGridPixelSizeShift = ForwardLightDataISR.LightGridPixelSizeShift;
Result.LightGridZParams = ForwardLightDataISR.LightGridZParams;
Result.CulledGridSize = ForwardLightDataISR.CulledGridSize;
}
#endif
return Result;
}
uint3 ComputeLightGridCellCoordinate(uint2 PixelPos, float SceneDepth, uint EyeIndex)
{
const FLightGridData GridData = GetLightGridData(EyeIndex);
uint ZSlice = (uint)(max(0, log2(SceneDepth * GridData.LightGridZParams.x + GridData.LightGridZParams.y) * GridData.LightGridZParams.z));
ZSlice = min(ZSlice, (uint)(GridData.CulledGridSize.z - 1));
return uint3(PixelPos >> GridData.LightGridPixelSizeShift, ZSlice);
}
uint ComputeLightGridCellIndex(uint3 GridCoordinate, uint EyeIndex)
{
const FLightGridData GridData = GetLightGridData(EyeIndex);
return (GridCoordinate.z * GridData.CulledGridSize.y + GridCoordinate.y) * GridData.CulledGridSize.x + GridCoordinate.x;
}
uint ComputeLightGridCellIndex(uint2 PixelPos, float SceneDepth, uint EyeIndex)
{
return ComputeLightGridCellIndex(ComputeLightGridCellCoordinate(PixelPos, SceneDepth, EyeIndex), EyeIndex);
}
uint ComputeLightGridCellIndex(uint2 PixelPos, float SceneDepth)
{
return ComputeLightGridCellIndex(PixelPos, SceneDepth, 0);
}
#ifndef NUM_CULLED_LIGHTS_GRID_STRIDE
#define NUM_CULLED_LIGHTS_GRID_STRIDE 0
#endif
#ifndef LOCAL_LIGHT_DATA_STRIDE
#define LOCAL_LIGHT_DATA_STRIDE 0
#endif
uint GetNumLocalLights(uint EyeIndex)
{
#if INSTANCED_STEREO
return (EyeIndex == 0) ? ForwardLightData.NumLocalLights : ForwardLightDataISR.NumLocalLights;
#else
return ForwardLightData.NumLocalLights;
#endif
}
struct FCulledLightsGridData
{
uint NumLocalLights;
uint DataStartIndex;
};
FCulledLightsGridData GetCulledLightsGrid(uint GridIndex, uint EyeIndex)
{
FCulledLightsGridData Result;
#if INSTANCED_STEREO
BRANCH
if (EyeIndex == 0)
{
#endif
Result.NumLocalLights = min(ForwardLightData.NumCulledLightsGrid[GridIndex * NUM_CULLED_LIGHTS_GRID_STRIDE + 0], ForwardLightData.NumLocalLights);
Result.DataStartIndex = ForwardLightData.NumCulledLightsGrid[GridIndex * NUM_CULLED_LIGHTS_GRID_STRIDE + 1];
#if INSTANCED_STEREO
}
else
{
Result.NumLocalLights = min(ForwardLightDataISR.NumCulledLightsGrid[GridIndex * NUM_CULLED_LIGHTS_GRID_STRIDE + 0], ForwardLightDataISR.NumLocalLights);
Result.DataStartIndex = ForwardLightDataISR.NumCulledLightsGrid[GridIndex * NUM_CULLED_LIGHTS_GRID_STRIDE + 1];
}
#endif
return Result;
}
struct FDirectionalLightData
{
uint HasDirectionalLight;
uint DirectionalLightShadowMapChannelMask;
float2 DirectionalLightDistanceFadeMAD;
float3 DirectionalLightColor;
float3 DirectionalLightDirection;
};
FDirectionalLightData GetDirectionalLightData(uint EyeIndex)
{
FDirectionalLightData Result;
#if INSTANCED_STEREO
BRANCH
if (EyeIndex == 0)
{
#endif
Result.HasDirectionalLight = ForwardLightData.HasDirectionalLight;
Result.DirectionalLightShadowMapChannelMask = ForwardLightData.DirectionalLightShadowMapChannelMask;
Result.DirectionalLightDistanceFadeMAD = ForwardLightData.DirectionalLightDistanceFadeMAD;
Result.DirectionalLightColor = ForwardLightData.DirectionalLightColor;
Result.DirectionalLightDirection = ForwardLightData.DirectionalLightDirection;
#if INSTANCED_STEREO
}
else
{
Result.HasDirectionalLight = ForwardLightDataISR.HasDirectionalLight;
Result.DirectionalLightShadowMapChannelMask = ForwardLightDataISR.DirectionalLightShadowMapChannelMask;
Result.DirectionalLightDistanceFadeMAD = ForwardLightDataISR.DirectionalLightDistanceFadeMAD;
Result.DirectionalLightColor = ForwardLightDataISR.DirectionalLightColor;
Result.DirectionalLightDirection = ForwardLightDataISR.DirectionalLightDirection;
}
#endif
return Result;
}
struct FLocalLightData
{
float4 LightPositionAndInvRadius;
float4 LightColorAndFalloffExponent;
float4 SpotAnglesAndSourceRadiusPacked;
float4 LightDirectionAndShadowMask;
float4 LightTangentAndSoftSourceRadius;
float4 RectBarnDoor;
/** Flag is true if clustered deferred is supported for this light. They are always first / together.*/
bool bClusteredDeferredSupported;
/** Flag is true if it is a simple light. They are always first / together.*/
bool bIsSimpleLight;
};
FLocalLightData GetLocalLightData(uint GridIndex, uint EyeIndex)
{
FLocalLightData Result;
#if INSTANCED_STEREO
BRANCH
if (EyeIndex == 0)
{
#endif
uint LocalLightIndex = ForwardLightData.CulledLightDataGrid[GridIndex];
uint LocalLightBaseIndex = LocalLightIndex * LOCAL_LIGHT_DATA_STRIDE;
Result.bClusteredDeferredSupported = LocalLightIndex < ForwardLightData.ClusteredDeferredSupportedEndIndex;
Result.bIsSimpleLight = LocalLightIndex < ForwardLightData.SimpleLightsEndIndex;
Result.LightPositionAndInvRadius = ForwardLightData.ForwardLocalLightBuffer[LocalLightBaseIndex + 0];
Result.LightColorAndFalloffExponent = ForwardLightData.ForwardLocalLightBuffer[LocalLightBaseIndex + 1];
Result.LightDirectionAndShadowMask = ForwardLightData.ForwardLocalLightBuffer[LocalLightBaseIndex + 2];
Result.SpotAnglesAndSourceRadiusPacked = ForwardLightData.ForwardLocalLightBuffer[LocalLightBaseIndex + 3];
Result.LightTangentAndSoftSourceRadius = ForwardLightData.ForwardLocalLightBuffer[LocalLightBaseIndex + 4];
Result.RectBarnDoor = ForwardLightData.ForwardLocalLightBuffer[LocalLightBaseIndex + 5];
#if INSTANCED_STEREO
}
else
{
uint LocalLightIndex = ForwardLightDataISR.CulledLightDataGrid[GridIndex];
uint LocalLightBaseIndex = LocalLightIndex * LOCAL_LIGHT_DATA_STRIDE;
Result.bClusteredDeferredSupported = LocalLightIndex < ForwardLightDataISR.ClusteredDeferredSupportedEndIndex;
Result.bIsSimpleLight = LocalLightIndex < ForwardLightDataISR.SimpleLightsEndIndex;
Result.LightPositionAndInvRadius = ForwardLightDataISR.ForwardLocalLightBuffer[LocalLightBaseIndex + 0];
Result.LightColorAndFalloffExponent = ForwardLightDataISR.ForwardLocalLightBuffer[LocalLightBaseIndex + 1];
Result.LightDirectionAndShadowMask = ForwardLightDataISR.ForwardLocalLightBuffer[LocalLightBaseIndex + 2];
Result.SpotAnglesAndSourceRadiusPacked = ForwardLightDataISR.ForwardLocalLightBuffer[LocalLightBaseIndex + 3];
Result.LightTangentAndSoftSourceRadius = ForwardLightDataISR.ForwardLocalLightBuffer[LocalLightBaseIndex + 4];
}
#endif
return Result;
}
/**
* Helper to unpack the shadow mask part of the FLocalLightData::LightDirectionAndShadowMask.w
*/
float4 UnpackShadowMapChannelMask(uint ShadowMapChannelMaskPacked)
{
return float4((ShadowMapChannelMaskPacked & 1) ? 1.0f : 0.0f, (ShadowMapChannelMaskPacked & 2) ? 1.0f : 0.0f, (ShadowMapChannelMaskPacked & 4) ? 1.0f : 0.0f, (ShadowMapChannelMaskPacked & 8) ? 1.0f : 0.0f);
}
/**
* Helper to pack/unpack the shadow mask for cluster shading and virtual shadow map
* This packing encode up to 10 lights into a 32bits uint
*/
uint GetShadowMaskMaxLightCount()
{
return 10;
}
void PackShadowMask(inout uint OutShadowMask, float InShadowFactor, uint InLightIndex)
{
OutShadowMask ^= (~uint(round(InShadowFactor * 7.0)) & 7u) << (InLightIndex * 3u);
}
float UnpackShadowMask(uint InShadowMask, uint InLightIndex)
{
return ((InShadowMask >> (InLightIndex * 3u)) & 7u) / 7.0;
}