810 lines
27 KiB
HLSL
810 lines
27 KiB
HLSL
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "Common.ush"
|
|
#include "HairShadingCommon.ush" // Used for FHairTransmittanceData
|
|
#include "/Engine/Shared/LightViewData.h"
|
|
#include "/Engine/Shared/LightDefinitions.h"
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Defines
|
|
|
|
#define LIGHTING_CHANNEL_MASK 0x7
|
|
|
|
#define MAX_RECT_ATLAS_MIP 32
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Rect light texture data
|
|
struct FRectTexture
|
|
{
|
|
half2 AtlasUVOffset;
|
|
half2 AtlasUVScale;
|
|
half AtlasMaxLevel;
|
|
};
|
|
|
|
FRectTexture InitRectTexture()
|
|
{
|
|
FRectTexture Out;
|
|
Out.AtlasUVOffset = 0;
|
|
Out.AtlasUVScale = 0;
|
|
Out.AtlasMaxLevel = MAX_RECT_ATLAS_MIP;
|
|
return Out;
|
|
}
|
|
|
|
struct FRectLightData
|
|
{
|
|
float BarnCosAngle;
|
|
float BarnLength;
|
|
FRectTexture AtlasData;
|
|
};
|
|
|
|
FRectLightData UnpackRectLightData(uint In0, uint In1, uint In2)
|
|
{
|
|
FRectLightData Out;
|
|
Out.AtlasData.AtlasUVOffset = half2(f16tof32(In0 & 0xFFFF), f16tof32(In0 >> 16));
|
|
Out.AtlasData.AtlasUVScale = half2(f16tof32(In1 & 0xFFFF), f16tof32(In1 >> 16));
|
|
Out.BarnLength = f16tof32(In2 & 0xFFFF); // 16 bits
|
|
Out.BarnCosAngle = UnpackUnorm10(In2 >> 16); // 10 bits
|
|
Out.AtlasData.AtlasMaxLevel = half(In2 >> 26); // 6 bits
|
|
return Out;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Directional light data
|
|
|
|
struct FDirectionalLightData
|
|
{
|
|
uint HasDirectionalLight;
|
|
uint DirectionalLightSceneInfoExtraDataPacked;
|
|
float2 DirectionalLightDistanceFadeMAD;
|
|
float3 DirectionalLightColor;
|
|
float3 DirectionalLightDirection;
|
|
float DirectionalLightSourceRadius;
|
|
float DirectionalLightSoftSourceRadius;
|
|
float DirectionalLightSpecularScale;
|
|
float DirectionalLightDiffuseScale;
|
|
uint LightFunctionAtlasLightIndex;
|
|
uint bAffectsTranslucentLighting;
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Forward light data
|
|
struct FForwardLightData
|
|
{
|
|
// Raw value form light buffers
|
|
float4 LightPositionAndInvRadius;
|
|
float4 LightColorAndIdAndFalloffExponent;
|
|
float4 SpotAnglesAndSourceRadiusPacked;
|
|
float4 LightDirectionAndSceneInfoExtraDataPacked;
|
|
float4 LightTangentAndIESDataAndSpecularScale;
|
|
float3 RectData;
|
|
|
|
// Derived terms after unpacking
|
|
/** Virtual shadow map ID or INDEX_NONE if not present.*/
|
|
int VirtualShadowMapId;
|
|
/** Previous frame LocalLightIndex or INDEX_NONE if not present.*/
|
|
int PrevLocalLightIndex;
|
|
/** Index into GPUScene lights */
|
|
int LightSceneId;
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Helper struct to provide type safety when loading lights from the Light Grid
|
|
// Local lights can optimize bRadialLight=true
|
|
struct FLocalLightData
|
|
{
|
|
FForwardLightData Internal;
|
|
#if !COMPILER_SUPPORTS_HLSL2021
|
|
uint Unused; // necessary to avoid ambiguity with struct FForwardLightData
|
|
#endif
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Simple light data
|
|
|
|
/** Data about a single light to be shaded with the simple shading model, designed for speed and limited feature set. */
|
|
struct FSimpleDeferredLightData
|
|
{
|
|
float3 TranslatedWorldPosition;
|
|
float InvRadius;
|
|
float3 Color;
|
|
float FalloffExponent;
|
|
/** Whether to use inverse squared falloff. */
|
|
bool bInverseSquared;
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Light-weight light data - Used for raytracing/VSM/Lumen/...
|
|
|
|
// Mirrors FLightShaderParameters on C++ side.
|
|
struct FLightShaderParameters
|
|
{
|
|
float3 TranslatedWorldPosition;
|
|
float InvRadius;
|
|
float3 Color;
|
|
float FalloffExponent;
|
|
float3 Direction;
|
|
float3 Tangent;
|
|
float2 SpotAngles;
|
|
float SpecularScale;
|
|
float DiffuseScale;
|
|
float SourceRadius;
|
|
float SoftSourceRadius;
|
|
float SourceLength;
|
|
float RectLightBarnCosAngle;
|
|
float RectLightBarnLength;
|
|
float2 RectLightAtlasUVOffset;
|
|
float2 RectLightAtlasUVScale;
|
|
float RectLightAtlasMaxLevel;
|
|
float IESAtlasIndex;
|
|
uint LightFunctionAtlasLightIndex;
|
|
uint bAffectsTranslucentLighting;
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Heavy light data - used for deferred lighting functions
|
|
|
|
/**
|
|
* Data about a single light.
|
|
* Putting the light data in this struct allows the same lighting code to be used between standard deferred,
|
|
* Where many light properties are known at compile time, and tiled deferred, where all light properties have to be fetched from a buffer.
|
|
*/
|
|
// TODO: inherit or compose FLightShaderParameters
|
|
struct FDeferredLightData
|
|
{
|
|
float3 TranslatedWorldPosition;
|
|
half InvRadius;
|
|
/** Premultiplied with light brightness, can be huge. Do not use half precision here */
|
|
float3 Color;
|
|
half FalloffExponent;
|
|
float3 Direction;
|
|
float3 Tangent;
|
|
float SoftSourceRadius;
|
|
half2 SpotAngles;
|
|
float SourceRadius;
|
|
float SourceLength;
|
|
half SpecularScale;
|
|
half DiffuseScale;
|
|
float ContactShadowLength;
|
|
/** Intensity of shadow-casting contact shadows */
|
|
float ContactShadowCastingIntensity;
|
|
/** Intensity of non-shadow-casting contact shadows */
|
|
float ContactShadowNonCastingIntensity;
|
|
float2 DistanceFadeMAD;
|
|
half4 ShadowMapChannelMask;
|
|
/** Whether ContactShadowLength is in World Space or in Screen Space. */
|
|
bool ContactShadowLengthInWS;
|
|
/** Whether to use inverse squared falloff. */
|
|
bool bInverseSquared;
|
|
/** Whether this is a light with radial attenuation, aka point or spot light. */
|
|
bool bRadialLight;
|
|
/** Whether this light needs spotlight attenuation. */
|
|
bool bSpotLight;
|
|
bool bRectLight;
|
|
/** Whether the light should apply shadowing. */
|
|
uint ShadowedBits;
|
|
/** Rect light data. */
|
|
FRectLightData RectLightData;
|
|
/** IES data. */
|
|
float IESAtlasIndex;
|
|
// Light function atlas index
|
|
uint LightFunctionAtlasLightIndex;
|
|
/** Hair transmittance data. */
|
|
FHairTransmittanceData HairTransmittance;
|
|
// Wether the light affect translucent materials or not
|
|
uint bAffectsTranslucentLighting;
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Pack/unpack function related to light structures
|
|
|
|
float3 UnpackLightTranslatedWorldPosition(FForwardLightData In)
|
|
{
|
|
return In.LightPositionAndInvRadius.xyz;
|
|
}
|
|
|
|
float3 UnpackLightTranslatedWorldPosition(FLocalLightData In)
|
|
{
|
|
return UnpackLightTranslatedWorldPosition(In.Internal);
|
|
}
|
|
|
|
float UnpackLightInvRadius(FForwardLightData In)
|
|
{
|
|
return In.LightPositionAndInvRadius.w;
|
|
}
|
|
|
|
float UnpackLightInvRadius(FLocalLightData In)
|
|
{
|
|
return UnpackLightInvRadius(In.Internal);
|
|
}
|
|
|
|
float3 UnpackLightDirection(FForwardLightData In)
|
|
{
|
|
return In.LightDirectionAndSceneInfoExtraDataPacked.xyz;
|
|
}
|
|
|
|
float3 UnpackLightDirection(FLocalLightData In)
|
|
{
|
|
return UnpackLightDirection(In.Internal);
|
|
}
|
|
|
|
uint UnpackLightSceneInfoExtraDataPacked(FForwardLightData In)
|
|
{
|
|
return asuint(In.LightDirectionAndSceneInfoExtraDataPacked.w);
|
|
}
|
|
|
|
uint UnpackLightSceneInfoExtraDataPacked(FLocalLightData In)
|
|
{
|
|
return UnpackLightSceneInfoExtraDataPacked(In.Internal);
|
|
}
|
|
|
|
float3 UnpackLightColor(float2 In)
|
|
{
|
|
float3 Dir = float3(
|
|
((asuint(In.y) >> 0) & 0x3FF),
|
|
((asuint(In.y) >> 10) & 0x3FF),
|
|
((asuint(In.y) >> 20) & 0x3FF));
|
|
return In.x * Dir;
|
|
}
|
|
|
|
float3 UnpackLightColor(FForwardLightData In)
|
|
{
|
|
return UnpackLightColor(In.LightColorAndIdAndFalloffExponent.xy);
|
|
}
|
|
|
|
float3 UnpackLightColor(FLocalLightData In)
|
|
{
|
|
return UnpackLightColor(In.Internal);
|
|
}
|
|
|
|
float UnpackLightFalloffExponent(FForwardLightData In)
|
|
{
|
|
return In.LightColorAndIdAndFalloffExponent.w;
|
|
}
|
|
|
|
float UnpackLightFalloffExponent(FLocalLightData In)
|
|
{
|
|
return UnpackLightFalloffExponent(In.Internal);
|
|
}
|
|
|
|
float4 UnpackShadowMapChannelMask(uint In)
|
|
{
|
|
// 8 ALU
|
|
return float4((In & 0x1), (In & 0x2) >> 1, (In & 0x4) >> 2, (In & 0x8) >> 3);
|
|
}
|
|
|
|
uint UnpackLightingChannelMask(uint In)
|
|
{
|
|
return (In >> 8) & LIGHTING_CHANNEL_MASK;
|
|
}
|
|
|
|
uint UnpackLightingChannelMask(FForwardLightData In)
|
|
{
|
|
const uint LightSceneInfoExtraDataPacked = asuint(In.LightDirectionAndSceneInfoExtraDataPacked.w);
|
|
return UnpackLightingChannelMask(LightSceneInfoExtraDataPacked);
|
|
}
|
|
|
|
uint UnpackLightingChannelMask(FLocalLightData In)
|
|
{
|
|
return UnpackLightingChannelMask(In.Internal);
|
|
}
|
|
|
|
uint UnpackLightType(uint InLightSceneInfoExtraDataPacked)
|
|
{
|
|
return (InLightSceneInfoExtraDataPacked >> 16) & 0x3;
|
|
}
|
|
|
|
bool UnpackCastShadow(uint InLightSceneInfoExtraDataPacked)
|
|
{
|
|
return ((InLightSceneInfoExtraDataPacked >> 18) & 0x1) != 0;
|
|
}
|
|
|
|
bool UnpackCastVolumetricShadow(uint InLightSceneInfoExtraDataPacked)
|
|
{
|
|
return ((InLightSceneInfoExtraDataPacked >> 31) & 0x1) != 0;
|
|
}
|
|
|
|
bool UnpackCastShadow(FForwardLightData In)
|
|
{
|
|
const uint LightSceneInfoExtraDataPacked = asuint(In.LightDirectionAndSceneInfoExtraDataPacked.w);
|
|
return UnpackCastShadow(LightSceneInfoExtraDataPacked);
|
|
}
|
|
|
|
bool UnpackCastVolumetricShadow(FForwardLightData In)
|
|
{
|
|
const uint LightSceneInfoExtraDataPacked = asuint(In.LightDirectionAndSceneInfoExtraDataPacked.w);
|
|
return UnpackCastVolumetricShadow(LightSceneInfoExtraDataPacked);
|
|
}
|
|
|
|
bool UnpackCastShadow(FLocalLightData In)
|
|
{
|
|
return UnpackCastShadow(In.Internal);
|
|
}
|
|
|
|
bool UnpackHasLightFunction(uint InLightSceneInfoExtraDataPacked)
|
|
{
|
|
return ((InLightSceneInfoExtraDataPacked >> 19) & 0x1) != 0;
|
|
}
|
|
|
|
bool UnpackHasLightFunction(FForwardLightData In)
|
|
{
|
|
const uint LightSceneInfoExtraDataPacked = asuint(In.LightDirectionAndSceneInfoExtraDataPacked.w);
|
|
return UnpackHasLightFunction(LightSceneInfoExtraDataPacked);
|
|
}
|
|
|
|
bool UnpackHasLightFunction(FLocalLightData In)
|
|
{
|
|
return UnpackHasLightFunction(In.Internal);
|
|
}
|
|
|
|
uint UnpackLightFunctionAtlasIndex(uint InLightSceneInfoExtraDataPacked)
|
|
{
|
|
return ((InLightSceneInfoExtraDataPacked >> 20) & 0xFF);
|
|
}
|
|
|
|
uint UnpackLightFunctionAtlasIndex(FForwardLightData In)
|
|
{
|
|
const uint LightSceneInfoExtraDataPacked = asuint(In.LightDirectionAndSceneInfoExtraDataPacked.w);
|
|
return UnpackLightFunctionAtlasIndex(LightSceneInfoExtraDataPacked);
|
|
}
|
|
|
|
uint UnpackLightFunctionAtlasIndex(FLocalLightData In)
|
|
{
|
|
return UnpackLightFunctionAtlasIndex(In.Internal);
|
|
}
|
|
|
|
uint UnpackAffectsTranslucentLighting(uint InLightSceneInfoExtraDataPacked)
|
|
{
|
|
return ((InLightSceneInfoExtraDataPacked >> 28) & 0x1);
|
|
}
|
|
|
|
uint UnpackAffectsTranslucentLighting(FForwardLightData In)
|
|
{
|
|
const uint LightSceneInfoExtraDataPacked = asuint(In.LightDirectionAndSceneInfoExtraDataPacked.w);
|
|
return UnpackAffectsTranslucentLighting(LightSceneInfoExtraDataPacked);
|
|
}
|
|
|
|
uint UnpackAffectsTranslucentLighting(FLocalLightData In)
|
|
{
|
|
return UnpackAffectsTranslucentLighting(In.Internal);
|
|
}
|
|
|
|
uint UnpackIsHandledByMegaLights(uint InLightSceneInfoExtraDataPacked)
|
|
{
|
|
return ((InLightSceneInfoExtraDataPacked >> 29) & 0x1);
|
|
}
|
|
|
|
uint UnpackIsHandledByMegaLights(FForwardLightData In)
|
|
{
|
|
const uint LightSceneInfoExtraDataPacked = asuint(In.LightDirectionAndSceneInfoExtraDataPacked.w);
|
|
return UnpackIsHandledByMegaLights(LightSceneInfoExtraDataPacked);
|
|
}
|
|
|
|
uint UnpackIsHandledByMegaLights(FLocalLightData In)
|
|
{
|
|
return UnpackIsHandledByMegaLights(In.Internal);
|
|
}
|
|
|
|
uint UnpackIsClusteredDeferredSupported(uint InLightSceneInfoExtraDataPacked)
|
|
{
|
|
return ((InLightSceneInfoExtraDataPacked >> 30) & 0x1);
|
|
}
|
|
|
|
uint UnpackIsClusteredDeferredSupported(FForwardLightData In)
|
|
{
|
|
const uint LightSceneInfoExtraDataPacked = asuint(In.LightDirectionAndSceneInfoExtraDataPacked.w);
|
|
return UnpackIsClusteredDeferredSupported(LightSceneInfoExtraDataPacked);
|
|
}
|
|
|
|
uint UnpackIsClusteredDeferredSupported(FLocalLightData In)
|
|
{
|
|
return UnpackIsClusteredDeferredSupported(In.Internal);
|
|
}
|
|
|
|
float UnpackVolumetricScatteringIntensity(FForwardLightData In)
|
|
{
|
|
return f16tof32(asuint(In.SpotAnglesAndSourceRadiusPacked.w) >> 16);
|
|
}
|
|
|
|
float UnpackVolumetricScatteringIntensity(FLocalLightData In)
|
|
{
|
|
return UnpackVolumetricScatteringIntensity(In.Internal);
|
|
}
|
|
|
|
float UnpackLightSourceRadius(FForwardLightData In)
|
|
{
|
|
return f16tof32(asuint(In.SpotAnglesAndSourceRadiusPacked.z) & 0xFFFF);
|
|
}
|
|
|
|
float UnpackLightSourceRadius(FLocalLightData In)
|
|
{
|
|
return UnpackLightSourceRadius(In.Internal);
|
|
}
|
|
|
|
float UnpackLightSoftSourceRadius(FForwardLightData In)
|
|
{
|
|
return f16tof32(asuint(In.SpotAnglesAndSourceRadiusPacked.z) >> 16);
|
|
}
|
|
|
|
float UnpackLightSoftSourceRadius(FLocalLightData In)
|
|
{
|
|
return UnpackLightSoftSourceRadius(In.Internal);
|
|
}
|
|
|
|
float UnpackLightSourceLength(FForwardLightData In)
|
|
{
|
|
return f16tof32(asuint(In.SpotAnglesAndSourceRadiusPacked.w));
|
|
}
|
|
|
|
float UnpackLightSourceLength(FLocalLightData In)
|
|
{
|
|
return UnpackLightSourceLength(In.Internal);
|
|
}
|
|
|
|
float GetLightSourceRadius(FForwardLightData In)
|
|
{
|
|
return UnpackLightSourceRadius(In);
|
|
}
|
|
|
|
float GetLightSourceRadius(FLocalLightData In)
|
|
{
|
|
return GetLightSourceRadius(In.Internal);
|
|
}
|
|
|
|
float2 GetLightSpotAngles(FForwardLightData In)
|
|
{
|
|
return In.SpotAnglesAndSourceRadiusPacked.xy;
|
|
}
|
|
|
|
float2 GetLightSpotAngles(FLocalLightData In)
|
|
{
|
|
return GetLightSpotAngles(In.Internal);
|
|
}
|
|
|
|
float UnpackLightSpecularScale(FForwardLightData In)
|
|
{
|
|
return UnpackUnorm10(asuint(In.LightTangentAndIESDataAndSpecularScale.w));
|
|
}
|
|
|
|
float UnpackLightSpecularScale(FLocalLightData In)
|
|
{
|
|
return UnpackLightSpecularScale(In.Internal);
|
|
}
|
|
|
|
float UnpackLightDiffuseScale(FForwardLightData In)
|
|
{
|
|
return UnpackUnorm10(asuint(In.LightTangentAndIESDataAndSpecularScale.w)>>10);
|
|
}
|
|
|
|
float UnpackLightDiffuseScale(FLocalLightData In)
|
|
{
|
|
return UnpackLightDiffuseScale(In.Internal);
|
|
}
|
|
|
|
float UnpackLigthIESAtlasIndex(FForwardLightData In)
|
|
{
|
|
// Offset IESAtlasIndex here in order to preserve INDEX_NONE = -1 after encoding
|
|
return int(asuint(In.LightTangentAndIESDataAndSpecularScale.w) >> 20) - 1;
|
|
}
|
|
|
|
float UnpackLigthIESAtlasIndex(FLocalLightData In)
|
|
{
|
|
return UnpackLigthIESAtlasIndex(In.Internal);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Conversion functions
|
|
|
|
FRectTexture ConvertToRectTexture(FDeferredLightData In)
|
|
{
|
|
FRectTexture Output;
|
|
Output.AtlasUVOffset = In.RectLightData.AtlasData.AtlasUVOffset;
|
|
Output.AtlasUVScale = In.RectLightData.AtlasData.AtlasUVScale;
|
|
Output.AtlasMaxLevel = In.RectLightData.AtlasData.AtlasMaxLevel;
|
|
return Output;
|
|
}
|
|
|
|
// Helper function for converting FForwardLightData into FDeferredLightData
|
|
FDeferredLightData ConvertToDeferredLight(
|
|
const FForwardLightData In,
|
|
float InSpecularScale,
|
|
inout half4 OutPreviewShadowMapChannelMask,
|
|
inout uint OutLightingChannelMask)
|
|
{
|
|
FDeferredLightData Out = (FDeferredLightData)0;
|
|
|
|
const uint LightSceneInfoExtraDataPacked = asuint(In.LightDirectionAndSceneInfoExtraDataPacked.w);
|
|
const uint LightType = UnpackLightType(LightSceneInfoExtraDataPacked);
|
|
|
|
Out.TranslatedWorldPosition = In.LightPositionAndInvRadius.xyz;
|
|
Out.InvRadius = In.LightPositionAndInvRadius.w;
|
|
Out.Color = UnpackLightColor(In.LightColorAndIdAndFalloffExponent.xy);
|
|
Out.FalloffExponent = In.LightColorAndIdAndFalloffExponent.w;
|
|
Out.Direction = In.LightDirectionAndSceneInfoExtraDataPacked.xyz;
|
|
Out.SpotAngles = GetLightSpotAngles(In);
|
|
Out.SourceRadius = UnpackLightSourceRadius(In);
|
|
Out.SourceLength = UnpackLightSourceLength(In);
|
|
Out.Tangent = In.LightTangentAndIESDataAndSpecularScale.xyz;
|
|
Out.SoftSourceRadius = UnpackLightSoftSourceRadius(In);
|
|
Out.bInverseSquared = Out.FalloffExponent == 0 && (LightType != LIGHT_TYPE_DIRECTIONAL); // Directional lights don't use 'inverse squared attenuation'
|
|
Out.SpecularScale = UnpackLightSpecularScale(In) * InSpecularScale;
|
|
Out.DiffuseScale = UnpackLightDiffuseScale(In);
|
|
Out.bRadialLight = LightType != LIGHT_TYPE_DIRECTIONAL;
|
|
Out.bSpotLight = LightType == LIGHT_TYPE_SPOT;
|
|
Out.bRectLight = LightType == LIGHT_TYPE_RECT;
|
|
Out.HairTransmittance = InitHairTransmittanceData();
|
|
Out.RectLightData = UnpackRectLightData(
|
|
asuint(In.RectData.x),
|
|
asuint(In.RectData.y),
|
|
asuint(In.RectData.z));
|
|
Out.IESAtlasIndex = UnpackLigthIESAtlasIndex(In);
|
|
Out.LightFunctionAtlasLightIndex = UnpackLightFunctionAtlasIndex(In);
|
|
|
|
Out.bAffectsTranslucentLighting = UnpackAffectsTranslucentLighting(In);
|
|
|
|
// Shadow
|
|
// * Static shadowing uses ShadowMapChannel,
|
|
// * Dynamic shadows are packed into light attenuation using PreviewShadowMapChannel
|
|
// Data Layout on [10:0] with:
|
|
// * ShadowMapChannelMask = [3:0]
|
|
// * PreviewShadowMapChannel= [7:4]
|
|
// * LightincChannelMask = [8:10]
|
|
Out.ShadowedBits = (LightSceneInfoExtraDataPacked & 0xFF) != 0 ? 1 : 0;
|
|
Out.ShadowMapChannelMask = UnpackShadowMapChannelMask(LightSceneInfoExtraDataPacked);
|
|
OutPreviewShadowMapChannelMask = UnpackShadowMapChannelMask(LightSceneInfoExtraDataPacked >> 4);
|
|
OutLightingChannelMask = UnpackLightingChannelMask(LightSceneInfoExtraDataPacked);
|
|
return Out;
|
|
}
|
|
|
|
FDeferredLightData ConvertToDeferredLight(
|
|
const FLocalLightData In,
|
|
float InSpecularScale,
|
|
inout half4 OutPreviewShadowMapChannelMask,
|
|
inout uint OutLightingChannelMask)
|
|
{
|
|
FDeferredLightData DeferredLightData = ConvertToDeferredLight(In.Internal, InSpecularScale, OutPreviewShadowMapChannelMask, OutLightingChannelMask);
|
|
DeferredLightData.bRadialLight = true;
|
|
DeferredLightData.bInverseSquared = DeferredLightData.FalloffExponent == 0;
|
|
|
|
return DeferredLightData;
|
|
}
|
|
|
|
FDeferredLightData ConvertToDeferredLight(const FForwardLightData In)
|
|
{
|
|
half4 OutPreviewShadowMapChannelMask = 0;
|
|
uint OutLightingChannelMask = LIGHTING_CHANNEL_MASK;
|
|
return ConvertToDeferredLight(In, 1.0f, OutPreviewShadowMapChannelMask, OutLightingChannelMask);
|
|
}
|
|
|
|
FDeferredLightData ConvertToDeferredLight(const FLocalLightData In)
|
|
{
|
|
half4 OutPreviewShadowMapChannelMask = 0;
|
|
uint OutLightingChannelMask = LIGHTING_CHANNEL_MASK;
|
|
return ConvertToDeferredLight(In, 1.0f, OutPreviewShadowMapChannelMask, OutLightingChannelMask);
|
|
}
|
|
|
|
FDeferredLightData ConvertToDeferredLight_Mobile(const FLocalLightData In)
|
|
{
|
|
half4 OutPreviewShadowMapChannelMask = 0;
|
|
uint OutLightingChannelMask = LIGHTING_CHANNEL_MASK;
|
|
FDeferredLightData Out = ConvertToDeferredLight(In, 1.0f, OutPreviewShadowMapChannelMask, OutLightingChannelMask);
|
|
|
|
// Override value for performance on mobile
|
|
Out.SoftSourceRadius= 0;
|
|
Out.SpecularScale = 1.0f; // If enabled -> UnpackLightSpecularScale(In);
|
|
Out.DiffuseScale = 1.0f; // If enabled -> UnpackLightDiffuseScale(In);
|
|
#if RECT_LIGHT_AS_SPOTLIGHT
|
|
// Render RectLight approximately as SpotLight
|
|
Out.bSpotLight = Out.bSpotLight || Out.bRectLight;
|
|
Out.bRectLight = false;
|
|
#endif
|
|
|
|
BRANCH
|
|
if (!Out.bRectLight)
|
|
{
|
|
Out.SourceRadius = 0;
|
|
Out.SourceLength = 0;
|
|
Out.Tangent = 0;
|
|
}
|
|
|
|
return Out;
|
|
}
|
|
|
|
FLightShaderParameters ConvertToLightShaderParameters(FDeferredLightData In)
|
|
{
|
|
FLightShaderParameters Out;
|
|
Out.TranslatedWorldPosition = In.TranslatedWorldPosition;
|
|
Out.InvRadius = In.InvRadius;
|
|
Out.Color = In.Color;
|
|
Out.FalloffExponent = In.FalloffExponent;
|
|
Out.Direction = In.Direction;
|
|
Out.Tangent = In.Tangent;
|
|
Out.SpotAngles = In.SpotAngles;
|
|
Out.SpecularScale = 1;
|
|
Out.DiffuseScale = 1;
|
|
Out.SourceRadius = In.SourceRadius;
|
|
Out.SoftSourceRadius = In.SoftSourceRadius;
|
|
Out.SourceLength = In.SourceLength;
|
|
Out.RectLightBarnCosAngle = In.RectLightData.BarnCosAngle;
|
|
Out.RectLightBarnLength = In.RectLightData.BarnLength;
|
|
Out.RectLightAtlasUVOffset = In.RectLightData.AtlasData.AtlasUVOffset;
|
|
Out.RectLightAtlasUVScale = In.RectLightData.AtlasData.AtlasUVScale;
|
|
Out.RectLightAtlasMaxLevel = In.RectLightData.AtlasData.AtlasMaxLevel;
|
|
return Out;
|
|
}
|
|
|
|
FLightShaderParameters ConvertFromForward(const FForwardLightData In)
|
|
{
|
|
FLightShaderParameters Out = (FLightShaderParameters)0;
|
|
Out.TranslatedWorldPosition = In.LightPositionAndInvRadius.xyz;
|
|
Out.InvRadius = In.LightPositionAndInvRadius.w;
|
|
Out.Color = UnpackLightColor(In.LightColorAndIdAndFalloffExponent.xy);
|
|
Out.FalloffExponent = In.LightColorAndIdAndFalloffExponent.w;
|
|
Out.Direction = In.LightDirectionAndSceneInfoExtraDataPacked.xyz;
|
|
Out.Tangent = In.LightTangentAndIESDataAndSpecularScale.xyz;
|
|
Out.SpotAngles = GetLightSpotAngles(In);
|
|
Out.SpecularScale = UnpackLightSpecularScale(In);
|
|
Out.DiffuseScale = UnpackLightDiffuseScale(In);
|
|
Out.IESAtlasIndex = UnpackLigthIESAtlasIndex(In);
|
|
Out.SourceRadius = UnpackLightSourceRadius(In);
|
|
Out.SoftSourceRadius = UnpackLightSoftSourceRadius(In);
|
|
Out.SourceLength = UnpackLightSourceLength(In);
|
|
|
|
Out.LightFunctionAtlasLightIndex = UnpackLightFunctionAtlasIndex(In);
|
|
|
|
Out.bAffectsTranslucentLighting = UnpackAffectsTranslucentLighting(In);
|
|
|
|
const FRectLightData RectLightData = UnpackRectLightData(
|
|
asuint(In.RectData.x),
|
|
asuint(In.RectData.y),
|
|
asuint(In.RectData.z));
|
|
Out.RectLightBarnCosAngle = RectLightData.BarnCosAngle;
|
|
Out.RectLightBarnLength = RectLightData.BarnLength;
|
|
Out.RectLightAtlasUVOffset = RectLightData.AtlasData.AtlasUVOffset;
|
|
Out.RectLightAtlasUVScale = RectLightData.AtlasData.AtlasUVScale;
|
|
Out.RectLightAtlasMaxLevel = RectLightData.AtlasData.AtlasMaxLevel;
|
|
|
|
return Out;
|
|
}
|
|
|
|
FLightShaderParameters ConvertFromLocal(const FLocalLightData In)
|
|
{
|
|
return ConvertFromForward(In.Internal);
|
|
}
|
|
|
|
// Helper function for converting FDirectionalLightData into FDeferredLightData
|
|
FDeferredLightData ConvertToDeferredLight(
|
|
FDirectionalLightData In,
|
|
float InSpecularScale,
|
|
inout half4 OutPreviewShadowMapChannelMask,
|
|
inout uint OutLightingChannelMask)
|
|
{
|
|
FDeferredLightData Out = (FDeferredLightData)0;
|
|
Out.Color = In.DirectionalLightColor;
|
|
Out.FalloffExponent = 0;
|
|
Out.Direction = In.DirectionalLightDirection;
|
|
Out.DistanceFadeMAD = In.DirectionalLightDistanceFadeMAD;
|
|
Out.bRadialLight = false;
|
|
Out.SpecularScale = In.DirectionalLightSpecularScale * InSpecularScale;
|
|
Out.DiffuseScale = In.DirectionalLightDiffuseScale;
|
|
Out.ShadowedBits = (In.DirectionalLightSceneInfoExtraDataPacked & 0xFF) != 0 ? 1 : 0;
|
|
Out.HairTransmittance = InitHairTransmittanceData();
|
|
Out.SourceRadius = In.DirectionalLightSourceRadius;
|
|
Out.SoftSourceRadius = In.DirectionalLightSoftSourceRadius;
|
|
Out.IESAtlasIndex = -1;
|
|
Out.LightFunctionAtlasLightIndex = In.LightFunctionAtlasLightIndex;
|
|
Out.bAffectsTranslucentLighting = In.bAffectsTranslucentLighting;
|
|
|
|
// Shadow
|
|
// * Static shadowing uses ShadowMapChannel,
|
|
// * Dynamic shadows are packed into light attenuation using PreviewShadowMapChannel
|
|
// Data Layout on [10:0] with:
|
|
// * ShadowMapChannelMask = [3:0]
|
|
// * PreviewShadowMapChannel= [7:4]
|
|
// * LightincChannelMask = [8:10]
|
|
Out.ShadowMapChannelMask = UnpackShadowMapChannelMask(In.DirectionalLightSceneInfoExtraDataPacked);
|
|
OutPreviewShadowMapChannelMask = UnpackShadowMapChannelMask(In.DirectionalLightSceneInfoExtraDataPacked >> 4);
|
|
OutLightingChannelMask = UnpackLightingChannelMask(In.DirectionalLightSceneInfoExtraDataPacked);
|
|
|
|
return Out;
|
|
}
|
|
|
|
// Helper function for converting FLightSceneData into FDeferredLightData
|
|
FDeferredLightData ConvertToDeferredLight(FLightSceneData In, FLightViewData InViewData)
|
|
{
|
|
FDeferredLightData Out = (FDeferredLightData)0;
|
|
|
|
const uint LightType = UnpackLightType(InViewData.LightSceneInfoExtraDataPacked);
|
|
|
|
Out.TranslatedWorldPosition = InViewData.TranslatedWorldPosition;
|
|
Out.InvRadius = In.InvRadius;
|
|
Out.Color = InViewData.Color;
|
|
Out.FalloffExponent = In.FalloffExponent;
|
|
Out.Direction = In.Direction;
|
|
Out.SpotAngles = In.SpotAngles;
|
|
Out.SourceRadius = In.SourceRadius;
|
|
Out.SourceLength = In.SourceLength;
|
|
Out.Tangent = In.Tangent;
|
|
Out.SoftSourceRadius = In.SoftSourceRadius;
|
|
Out.bInverseSquared = In.FalloffExponent == 0 && (LightType != LIGHT_TYPE_DIRECTIONAL); // Directional lights don't use 'inverse squared attenuation'
|
|
Out.SpecularScale = In.SpecularScale;
|
|
Out.DiffuseScale = In.DiffuseScale;
|
|
Out.bRadialLight = LightType != LIGHT_TYPE_DIRECTIONAL;
|
|
Out.bSpotLight = LightType == LIGHT_TYPE_SPOT;
|
|
Out.bRectLight = LightType == LIGHT_TYPE_RECT;
|
|
Out.HairTransmittance = InitHairTransmittanceData();
|
|
|
|
Out.RectLightData.BarnCosAngle = In.RectLightBarnCosAngle;
|
|
Out.RectLightData.BarnLength = In.RectLightBarnLength;
|
|
Out.RectLightData.AtlasData.AtlasMaxLevel = InViewData.RectLightAtlasMaxLevel;
|
|
Out.RectLightData.AtlasData.AtlasUVOffset = InViewData.RectLightAtlasUVOffset;
|
|
Out.RectLightData.AtlasData.AtlasUVScale = InViewData.RectLightAtlasUVScale;
|
|
|
|
Out.IESAtlasIndex = InViewData.IESAtlasIndex;
|
|
Out.LightFunctionAtlasLightIndex = UnpackLightFunctionAtlasIndex(InViewData.LightSceneInfoExtraDataPacked);
|
|
|
|
Out.bAffectsTranslucentLighting = UnpackAffectsTranslucentLighting(InViewData.LightSceneInfoExtraDataPacked);
|
|
|
|
// Shadow
|
|
// * Static shadowing uses ShadowMapChannel,
|
|
// * Dynamic shadows are packed into light attenuation using PreviewShadowMapChannel
|
|
// Data Layout on [10:0] with:
|
|
// * ShadowMapChannelMask = [3:0]
|
|
// * PreviewShadowMapChannel= [7:4]
|
|
// * LightingChannelMask = [8:10]
|
|
Out.ShadowedBits = (InViewData.LightSceneInfoExtraDataPacked & 0xFF) != 0 ? 1 : 0;
|
|
Out.ShadowMapChannelMask = UnpackShadowMapChannelMask(InViewData.LightSceneInfoExtraDataPacked);
|
|
return Out;
|
|
}
|
|
|
|
// Helper function for converting FLightSceneData into FLightShaderParameters
|
|
FLightShaderParameters ConvertToLightShaderParameters(FLightSceneData In, FLightViewData InViewData)
|
|
{
|
|
FLightShaderParameters Out;
|
|
Out.TranslatedWorldPosition = DFFastAddDemote(In.WorldPosition, PrimaryView.PreViewTranslation);
|
|
Out.InvRadius = In.InvRadius;
|
|
Out.Color = InViewData.Color;
|
|
Out.FalloffExponent = In.FalloffExponent;
|
|
Out.Direction = In.Direction;
|
|
Out.Tangent = In.Tangent;
|
|
Out.SpotAngles = In.SpotAngles;
|
|
Out.SpecularScale = 1.0f; // In.SpecularScale;
|
|
Out.DiffuseScale = In.DiffuseScale;
|
|
Out.SourceRadius = In.SourceRadius;
|
|
Out.SoftSourceRadius = In.SoftSourceRadius;
|
|
Out.SourceLength = In.SourceLength;
|
|
Out.RectLightBarnCosAngle = In.RectLightBarnCosAngle;
|
|
Out.RectLightBarnLength = In.RectLightBarnLength;
|
|
Out.RectLightAtlasUVOffset = InViewData.RectLightAtlasUVOffset;
|
|
Out.RectLightAtlasUVScale = InViewData.RectLightAtlasUVScale;
|
|
Out.RectLightAtlasMaxLevel = InViewData.RectLightAtlasMaxLevel;
|
|
return Out;
|
|
}
|
|
|
|
// Helper function for converting FLocalLightData into FSimpleDeferredLightData
|
|
FSimpleDeferredLightData ConvertToSimpleLight(FLocalLightData In)
|
|
{
|
|
FSimpleDeferredLightData Out = (FSimpleDeferredLightData)0;
|
|
Out.TranslatedWorldPosition = In.Internal.LightPositionAndInvRadius.xyz;
|
|
Out.InvRadius = In.Internal.LightPositionAndInvRadius.w;
|
|
Out.Color = UnpackLightColor(In.Internal.LightColorAndIdAndFalloffExponent.xy);
|
|
Out.FalloffExponent = In.Internal.LightColorAndIdAndFalloffExponent.w;
|
|
Out.bInverseSquared = Out.FalloffExponent == 0;
|
|
return Out;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Helper functions
|
|
|
|
// Return true if the point is influenced by the light
|
|
bool IsLightVisible(FForwardLightData InLight, float3 TranslatedWorldPosition)
|
|
{
|
|
float InvLightRadiusSq = InLight.LightPositionAndInvRadius.w * InLight.LightPositionAndInvRadius.w;
|
|
return length2(TranslatedWorldPosition - InLight.LightPositionAndInvRadius.xyz) * InvLightRadiusSq <= 1.0f;
|
|
}
|
|
|
|
bool IsLightVisible(FLocalLightData InLight, float3 TranslatedWorldPosition)
|
|
{
|
|
return IsLightVisible(InLight.Internal, TranslatedWorldPosition);
|
|
} |