Files
UnrealEngineUWP/Engine/Source/Runtime/RenderCore/Private/GBufferInfo.cpp
Sebastien Hillaire 4e91e8da1d Strata - fixed SLW to not cause issue on when shader specifies output format wiht Strata.
The separated main dir light buffer is no longer bound as render target during the base pass. It is used for the DFShadow only.
The main dir light contribution flow thgouth the Strata mateiral buffer.

#rb charles.derousiers
#preflight https://horde.devtools.epicgames.com/job/6273d021b86624d2e8cab0f0

[CL 20056963 by Sebastien Hillaire in ue5-main branch]
2022-05-05 09:38:59 -04:00

532 lines
20 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
/*=============================================================================
GBufferInfo.cpp: Dynamic GBuffer implementation.
=============================================================================*/
#include "GBufferInfo.h"
// This is very ugly, but temporary. We can't include EngineTypes.h because this file is ShaderCore and that
// file is Engine. But since we will remove this flag anyways, we will copy/paste the enums for now, but remove
// them as soon as flexible GBuffer is in.
static const int32 EGBufferFormat_Force8BitsPerChannel = 0;
static const int32 EGBufferFormat_Default = 1;
/** Same as Default except normals are encoded at 16 bits per channel. */
static const int32 EGBufferFormat_HighPrecisionNormals = 3;
/** Forces all GBuffers to 16 bits per channel. Intended as profiling for best quality. */
static const int32 EGBufferFormat_Force16BitsPerChannel = 5;
// Strata::IsEnabled is only accessible in the Renderer module
bool RenderCore_IsStrataEnabled()
{
static IConsoleVariable* CVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.Strata"));
return CVar->GetInt() > 0;
}
static bool IsGBufferPackingEqual(const FGBufferPacking& Lhs, const FGBufferPacking& Rhs)
{
return
Lhs.bFull == Rhs.bFull &&
Lhs.bIsValid == Rhs.bIsValid &&
Lhs.TargetIndex == Rhs.TargetIndex &&
Lhs.DstBitStart == Rhs.DstBitStart &&
Lhs.DstChannelIndex == Rhs.DstChannelIndex &&
Lhs.SrcBitStart == Rhs.SrcBitStart &&
Lhs.SrcChannelIndex == Rhs.SrcChannelIndex &&
Lhs.BitNum == Rhs.BitNum;
}
static bool IsGBufferItemEqual(const FGBufferItem& Lhs, const FGBufferItem& Rhs)
{
for (int32 I = 0; I < FGBufferItem::MaxPacking; I++)
{
const bool bSame = IsGBufferPackingEqual(Lhs.Packing[I], Rhs.Packing[I]);
if (!bSame)
{
return false;
}
}
return Lhs.bIsValid == Rhs.bIsValid &&
Lhs.bQuantizationBias == Rhs.bQuantizationBias &&
Lhs.BufferSlot == Rhs.BufferSlot &&
Lhs.Compression == Rhs.Compression &&
Lhs.Checker == Rhs.Checker;
}
bool RENDERCORE_API IsGBufferInfoEqual(const FGBufferInfo& Lhs, const FGBufferInfo& Rhs)
{
if (Lhs.NumTargets != Rhs.NumTargets)
{
return false;
}
for (int32 I = 0; I < Lhs.NumTargets; I++)
{
if (!(Lhs.Targets[I] == Rhs.Targets[I]))
{
return false;
}
}
for (int32 I = 0; I < GBS_Num; I++)
{
if (!IsGBufferItemEqual(Lhs.Slots[I], Rhs.Slots[I]))
{
return false;
}
}
return true;
}
TArray < EGBufferSlot > FetchGBufferSlots(bool bHasVelocity, bool bHasTangent, bool bHasPrecShadowFactor)
{
TArray < EGBufferSlot > NeededSlots;
NeededSlots.Push(GBS_SceneColor);
NeededSlots.Push(GBS_WorldNormal);
NeededSlots.Push(GBS_PerObjectGBufferData);
NeededSlots.Push(GBS_Metallic);
NeededSlots.Push(GBS_Specular);
NeededSlots.Push(GBS_Roughness);
NeededSlots.Push(GBS_ShadingModelId);
NeededSlots.Push(GBS_SelectiveOutputMask);
NeededSlots.Push(GBS_BaseColor);
// this is needed for all combinations, will have to split it later
NeededSlots.Push(GBS_GenericAO);
if (bHasVelocity)
{
NeededSlots.Push(GBS_Velocity);
}
if (bHasPrecShadowFactor)
{
NeededSlots.Push(GBS_PrecomputedShadowFactor);
}
if (bHasTangent)
{
NeededSlots.Push(GBS_WorldTangent);
NeededSlots.Push(GBS_Anisotropy);
}
NeededSlots.Push(GBS_CustomData);
return NeededSlots;
}
// finds the target by searching for the name. returns -1 if not found.
int32 FindGBufferTargetByName(const FGBufferInfo& GBufferInfo, const FString& Name)
{
for (int32 I = 0; I < GBufferInfo.NumTargets; I++)
{
if (GBufferInfo.Targets[I].TargetName.Compare(Name) == 0)
{
return I;
}
}
return -1;
}
FGBufferBinding FindGBufferBindingByName(const FGBufferInfo& GBufferInfo, const FString& Name)
{
const int32 Index = FindGBufferTargetByName(GBufferInfo, Name);
FGBufferBinding Binding;
if (Index >= 0)
{
const FGBufferTarget& Target = GBufferInfo.Targets[Index];
EPixelFormat PixelFormat = PF_Unknown;
switch (Target.TargetType)
{
case GBT_Unorm_8_8_8_8:
PixelFormat = PF_B8G8R8A8;
break;
case GBT_Unorm_11_11_10:
PixelFormat = PF_FloatR11G11B10;
break;
case GBT_Unorm_10_10_10_2:
PixelFormat = PF_A2B10G10R10;
break;
case GBT_Float_16_16:
PixelFormat = PF_G16R16;
break;
case GBT_Float_16_16_16_16:
PixelFormat = PF_A16B16G16R16;
break;
case GBT_Invalid:
default:
check(0);
break;
}
Binding.Index = Index;
Binding.Format = PixelFormat;
Binding.Flags = TexCreate_ShaderResource | TexCreate_RenderTargetable | (Target.bIsSrgb ? TexCreate_SRGB : TexCreate_None);
}
return Binding;
}
/*
* 4.25 Logic:
*
* if (SrcGlobal.GBUFFER_HAS_VELOCITY == 0 && SrcGlobal.GBUFFER_HAS_TANGENT == 0)
* 0: Lighting
* 1: GBufferA
* 2: GBufferB
* 3: GBufferC
* 4: GBufferD
* if (GBUFFER_HAS_PRECSHADOWFACTOR)
* 5: GBufferE
* else if (SrcGlobal.GBUFFER_HAS_VELOCITY == 1 && SrcGlobal.GBUFFER_HAS_TANGENT == 0)
* 0: Lighting
* 1: GBufferA
* 2: GBufferB
* 3: GBufferC
* 4: Velocity (NOTE!)
* 5: GBufferD
* if (GBUFFER_HAS_PRECSHADOWFACTOR)
* 6: GBufferE
* else if (SrcGlobal.GBUFFER_HAS_VELOCITY == 0 && SrcGlobal.GBUFFER_HAS_TANGENT == 1)
* 0: Lighting
* 1: GBufferA
* 2: GBufferB
* 3: GBufferC
* 4: GBufferF (NOTE!)
* 5: GBufferD
* if (GBUFFER_HAS_PRECSHADOWFACTOR)
* 6: GBufferE
* else if (SrcGlobal.GBUFFER_HAS_VELOCITY == 1 && SrcGlobal.GBUFFER_HAS_TANGENT == 1)
* assert(0)
*
*/
/*
* LegacyFormatIndex: EGBufferFormat enum. Going forward, we will have better granularity on choosing precision, so thes
* are just being maintained for the transition.
*
* bUsesVelocityDepth: Normal velocity format is half16 for RG. But when enabled, it changes to half16 RGBA with
* alpha storing depth and blue unused.
*
*/
FGBufferInfo RENDERCORE_API FetchLegacyGBufferInfo(const FGBufferParams& Params)
{
FGBufferInfo Info = {};
check(!Params.bHasVelocity || !Params.bHasTangent);
bool bStaticLighting = Params.bHasPrecShadowFactor;
int32 TargetLighting = 0;
int32 TargetGBufferA = 1;
int32 TargetGBufferB = 2;
int32 TargetGBufferC = 3;
int32 TargetGBufferD = -1;
int32 TargetGBufferE = -1;
int32 TargetGBufferF = -1;
int32 TargetVelocity = -1;
int32 TargetSeparatedMainDirLight = -1;
// Strata ouputs material data through UAV. Only SceneColor, PrecalcShadow & Velocity data are still emitted through RenderTargets
const bool bStrata = RenderCore_IsStrataEnabled();
if (bStrata)
{
TargetGBufferA = -1;
TargetGBufferB = -1;
TargetGBufferC = -1;
Info.NumTargets = 1;
if (Params.bHasVelocity)
{
TargetVelocity = Info.NumTargets++;
}
if (Params.bHasPrecShadowFactor)
{
TargetGBufferE = Info.NumTargets++;
}
// this value isn't correct, becuase it doesn't resepect the scene color format cvar, but it's ignored anyways
// so it's ok for now
Info.Targets[TargetLighting].Init(GBT_Unorm_11_11_10, TEXT("Lighting"), false, true, true, true);
Info.Slots[GBS_SceneColor] = FGBufferItem(GBS_SceneColor, GBC_Raw_Float_11_11_10, GBCH_Both);
Info.Slots[GBS_SceneColor].Packing[0] = FGBufferPacking(TargetLighting, 0, 0);
Info.Slots[GBS_SceneColor].Packing[1] = FGBufferPacking(TargetLighting, 1, 1);
Info.Slots[GBS_SceneColor].Packing[2] = FGBufferPacking(TargetLighting, 2, 2);
if (Params.bHasVelocity)
{
Info.Targets[TargetVelocity].Init(Params.bUsesVelocityDepth ? GBT_Float_16_16_16_16 : GBT_Float_16_16, TEXT("Velocity"), false, true, true, false); // Velocity
Info.Slots[GBS_Velocity] = FGBufferItem(GBS_Velocity, Params.bUsesVelocityDepth ? GBC_Raw_Float_16_16_16_16 : GBC_Raw_Float_16_16, GBCH_Both);
Info.Slots[GBS_Velocity].Packing[0] = FGBufferPacking(TargetVelocity, 0, 0);
Info.Slots[GBS_Velocity].Packing[1] = FGBufferPacking(TargetVelocity, 1, 1);
if (Params.bUsesVelocityDepth)
{
Info.Slots[GBS_Velocity].Packing[2] = FGBufferPacking(TargetVelocity, 2, 2);
Info.Slots[GBS_Velocity].Packing[3] = FGBufferPacking(TargetVelocity, 3, 3);
}
}
if (Params.bHasPrecShadowFactor)
{
Info.Targets[TargetGBufferE].Init(GBT_Unorm_8_8_8_8, TEXT("GBufferE"), false, true, true, false); // Precalc
Info.Slots[GBS_PrecomputedShadowFactor] = FGBufferItem(GBS_PrecomputedShadowFactor, GBC_Raw_Unorm_8_8_8_8, GBCH_Both);
Info.Slots[GBS_PrecomputedShadowFactor].Packing[0] = FGBufferPacking(TargetGBufferE, 0, 0);
Info.Slots[GBS_PrecomputedShadowFactor].Packing[1] = FGBufferPacking(TargetGBufferE, 1, 1);
Info.Slots[GBS_PrecomputedShadowFactor].Packing[2] = FGBufferPacking(TargetGBufferE, 2, 2);
Info.Slots[GBS_PrecomputedShadowFactor].Packing[3] = FGBufferPacking(TargetGBufferE, 3, 3);
}
// We do not setup GBS_SeparatedMainDirLight as the data will flow through the Strata material buffer.
return Info;
}
if (Params.bHasVelocity == 0 && Params.bHasTangent == 0)
{
Info.NumTargets = Params.bHasPrecShadowFactor ? 6 : 5;
}
else
{
Info.NumTargets = Params.bHasPrecShadowFactor ? 7 : 6;
}
// good to see the quality loss due to precision in the gbuffer
const bool bHighPrecisionGBuffers = (Params.LegacyFormatIndex >= EGBufferFormat_Force16BitsPerChannel);
// good to profile the impact of non 8 bit formats
const bool bEnforce8BitPerChannel = (Params.LegacyFormatIndex == EGBufferFormat_Force8BitsPerChannel);
EGBufferType NormalGBufferFormatTarget = bHighPrecisionGBuffers ? GBT_Float_16_16_16_16 : GBT_Unorm_10_10_10_2;
EGBufferCompression NormalGBufferFormatChannel = bHighPrecisionGBuffers ? GBC_EncodeNormal_Normal_16_16_16 : GBC_EncodeNormal_Normal_10_10_10;
if (bEnforce8BitPerChannel)
{
NormalGBufferFormatTarget = GBT_Unorm_8_8_8_8;
NormalGBufferFormatChannel = GBC_EncodeNormal_Normal_8_8_8;
}
else if (Params.LegacyFormatIndex == EGBufferFormat_HighPrecisionNormals)
{
NormalGBufferFormatTarget = GBT_Float_16_16_16_16;
NormalGBufferFormatChannel = GBC_EncodeNormal_Normal_16_16_16;
}
const EGBufferType DiffuseAndSpecularGBufferFormat = bHighPrecisionGBuffers ? GBT_Float_16_16_16_16 : GBT_Unorm_8_8_8_8;
const EGBufferCompression DiffuseGBufferChannel = bHighPrecisionGBuffers ? GBC_Raw_Float_16_16_16 : GBC_Raw_Unorm_8_8_8;
const EGBufferCompression SpecularGBufferChannel = bHighPrecisionGBuffers ? GBC_Raw_Float_16 : GBC_Raw_Unorm_8;
Info.Targets[0].Init(GBT_Unorm_11_11_10, TEXT("Lighting"), false, true, true, true);
Info.Targets[1].Init(NormalGBufferFormatTarget,TEXT("GBufferA"), false, true, true, true);
Info.Targets[2].Init(DiffuseAndSpecularGBufferFormat, TEXT("GBufferB"), false, true, true, true);
const bool bLegacyAlbedoSrgb = true;
Info.Targets[3].Init(DiffuseAndSpecularGBufferFormat, TEXT("GBufferC"), bLegacyAlbedoSrgb && !bHighPrecisionGBuffers, true, true, true);
// This code should match TBasePassPS
if (Params.bHasVelocity == 0 && Params.bHasTangent == 0)
{
TargetGBufferD = 4;
Info.Targets[4].Init(GBT_Unorm_8_8_8_8, TEXT("GBufferD"), false, true, true, true);
TargetSeparatedMainDirLight = 5;
if (Params.bHasPrecShadowFactor)
{
TargetGBufferE = 5;
Info.Targets[5].Init(GBT_Unorm_8_8_8_8, TEXT("GBufferE"), false, true, true, true);
TargetSeparatedMainDirLight = 6;
}
}
else if (Params.bHasVelocity)
{
TargetVelocity = 4;
TargetGBufferD = 5;
// note the false for use extra flags for velocity, not quite sure of all the ramifications, but this keeps it consistent with previous usage
Info.Targets[4].Init(Params.bUsesVelocityDepth ? GBT_Float_16_16_16_16 : GBT_Float_16_16, TEXT("Velocity"), false, true, true, false);
Info.Targets[5].Init(GBT_Unorm_8_8_8_8, TEXT("GBufferD"), false, true, true, true);
TargetSeparatedMainDirLight = 6;
if (Params.bHasPrecShadowFactor)
{
TargetGBufferE = 6;
Info.Targets[6].Init(GBT_Unorm_8_8_8_8, TEXT("GBufferE"), false, true, true, false);
TargetSeparatedMainDirLight = 7;
}
}
else if (Params.bHasTangent)
{
TargetGBufferF = 4;
TargetGBufferD = 5;
Info.Targets[4].Init(GBT_Unorm_8_8_8_8, TEXT("GBufferF"), false, true, true, true);
Info.Targets[5].Init(GBT_Unorm_8_8_8_8, TEXT("GBufferD"), false, true, true, true);
TargetSeparatedMainDirLight = 6;
if (Params.bHasPrecShadowFactor)
{
TargetGBufferE = 6;
Info.Targets[6].Init(GBT_Unorm_8_8_8_8, TEXT("GBufferE"), false, true, true, true);
TargetSeparatedMainDirLight = 7;
}
}
else
{
// should never hit this path
check(0);
}
// this value isn't correct, becuase it doesn't resepect the scene color format cvar, but it's ignored anyways
// so it's ok for now
Info.Slots[GBS_SceneColor] = FGBufferItem(GBS_SceneColor, GBC_Raw_Float_11_11_10, GBCH_Both);
Info.Slots[GBS_SceneColor].Packing[0] = FGBufferPacking(TargetLighting, 0, 0);
Info.Slots[GBS_SceneColor].Packing[1] = FGBufferPacking(TargetLighting, 1, 1);
Info.Slots[GBS_SceneColor].Packing[2] = FGBufferPacking(TargetLighting, 2, 2);
Info.Slots[GBS_WorldNormal] = FGBufferItem(GBS_WorldNormal, NormalGBufferFormatChannel, GBCH_Both);
Info.Slots[GBS_WorldNormal].Packing[0] = FGBufferPacking(TargetGBufferA, 0, 0);
Info.Slots[GBS_WorldNormal].Packing[1] = FGBufferPacking(TargetGBufferA, 1, 1);
Info.Slots[GBS_WorldNormal].Packing[2] = FGBufferPacking(TargetGBufferA, 2, 2);
Info.Slots[GBS_PerObjectGBufferData] = FGBufferItem(GBS_PerObjectGBufferData, GBC_Raw_Unorm_2, GBCH_Both);
Info.Slots[GBS_PerObjectGBufferData].Packing[0] = FGBufferPacking(TargetGBufferA, 0, 3);
#if 1
Info.Slots[GBS_Metallic] = FGBufferItem(GBS_Metallic, SpecularGBufferChannel, GBCH_Both);
Info.Slots[GBS_Metallic].Packing[0] = FGBufferPacking(TargetGBufferB, 0, 0);
Info.Slots[GBS_Specular] = FGBufferItem(GBS_Specular, SpecularGBufferChannel, GBCH_Both);
Info.Slots[GBS_Specular].Packing[0] = FGBufferPacking(TargetGBufferB, 0, 1);
Info.Slots[GBS_Roughness] = FGBufferItem(GBS_Roughness, SpecularGBufferChannel, GBCH_Both);
Info.Slots[GBS_Roughness].Packing[0] = FGBufferPacking(TargetGBufferB, 0, 2);
#else
Info.Slots[GBS_Metallic] = FGBufferItem(GBS_Metallic, GBC_Packed_Quantized_4, GBCH_Both);
Info.Slots[GBS_Metallic].Packing[0] = FGBufferPacking(TargetGBufferB, 0, 0, 0, 0, 4);
Info.Slots[GBS_Specular] = FGBufferItem(GBS_Specular, GBC_Packed_Quantized_4, GBCH_Both);
Info.Slots[GBS_Specular].Packing[0] = FGBufferPacking(TargetGBufferB, 0, 0, 0, 4, 4);
Info.Slots[GBS_Roughness] = FGBufferItem(GBS_Roughness, GBC_Packed_Quantized_4, GBCH_Both);
Info.Slots[GBS_Roughness].Packing[0] = FGBufferPacking(TargetGBufferB, 0, 1, 0, 0, 4);
#endif
// pack it into bits [0:3] of alpha
Info.Slots[GBS_ShadingModelId] = FGBufferItem(GBS_ShadingModelId, GBC_Bits_4, GBCH_Both);
Info.Slots[GBS_ShadingModelId].Packing[0] = FGBufferPacking(TargetGBufferB, 0, 3, 0, 0, 4);
// pack it into bits [4:7] of alpha
Info.Slots[GBS_SelectiveOutputMask] = FGBufferItem(GBS_SelectiveOutputMask, GBC_Bits_4, GBCH_Both);
Info.Slots[GBS_SelectiveOutputMask].Packing[0] = FGBufferPacking(TargetGBufferB, 0, 3, 0, 4, 4);
{
#if 1
EGBufferCompression BaseColorCompression = GBC_Invalid;
Info.Slots[GBS_BaseColor] = FGBufferItem(GBS_BaseColor, DiffuseGBufferChannel, GBCH_Both);
Info.Slots[GBS_BaseColor].Packing[0] = FGBufferPacking(TargetGBufferC, 0, 0);
Info.Slots[GBS_BaseColor].Packing[1] = FGBufferPacking(TargetGBufferC, 1, 1);
Info.Slots[GBS_BaseColor].Packing[2] = FGBufferPacking(TargetGBufferC, 2, 2);
#elif 0
// pack it for funzies
Info.Slots[GBS_BaseColor] = FGBufferItem(GBS_BaseColor, GBC_Packed_Color_5_6_5, GBCH_Both);
Info.Slots[GBS_BaseColor].bQuantizationBias = true;
Info.Slots[GBS_BaseColor].Packing[0] = FGBufferPacking(TargetGBufferB, 0, 0, 0, 0, 5);
Info.Slots[GBS_BaseColor].Packing[1] = FGBufferPacking(TargetGBufferB, 1, 1, 0, 0, 6);
Info.Slots[GBS_BaseColor].Packing[2] = FGBufferPacking(TargetGBufferB, 2, 2, 0, 0, 5);
#elif 0
// pack it for funzies
Info.Slots[GBS_BaseColor] = FGBufferItem(GBS_BaseColor, GBC_Packed_Color_5_6_5, GBCH_Both);
Info.Slots[GBS_BaseColor].bQuantizationBias = true;
Info.Slots[GBS_BaseColor].Packing[0] = FGBufferPacking(TargetGBufferC, 0, 0, 0, 0, 5);
Info.Slots[GBS_BaseColor].Packing[1] = FGBufferPacking(TargetGBufferC, 1, 0, 0, 5, 3);
Info.Slots[GBS_BaseColor].Packing[2] = FGBufferPacking(TargetGBufferC, 1, 1, 3, 5, 3);
Info.Slots[GBS_BaseColor].Packing[3] = FGBufferPacking(TargetGBufferC, 2, 1, 0, 0, 5);
#elif 1
// pack it for funzies
Info.Slots[GBS_BaseColor] = FGBufferItem(GBS_BaseColor, GBC_Packed_Color_4_4_4_Sqrt, GBCH_Both);
Info.Slots[GBS_BaseColor].bQuantizationBias = true;
Info.Slots[GBS_BaseColor].Packing[0] = FGBufferPacking(TargetGBufferB, 0, 1, 0, 4, 4);
Info.Slots[GBS_BaseColor].Packing[1] = FGBufferPacking(TargetGBufferB, 1, 2, 0, 0, 4);
Info.Slots[GBS_BaseColor].Packing[2] = FGBufferPacking(TargetGBufferB, 2, 2, 0, 4, 4);
#else
// pack it for funzies
Info.Slots[GBS_BaseColor] = FGBufferItem(GBS_BaseColor, GBC_Packed_Color_3_3_2_Sqrt, GBCH_Both);
Info.Slots[GBS_BaseColor].bQuantizationBias = true;
Info.Slots[GBS_BaseColor].Packing[0] = FGBufferPacking(TargetGBufferC, 0, 0, 0, 0, 3);
Info.Slots[GBS_BaseColor].Packing[1] = FGBufferPacking(TargetGBufferC, 1, 0, 0, 3, 3);
Info.Slots[GBS_BaseColor].Packing[2] = FGBufferPacking(TargetGBufferC, 2, 0, 0, 6, 2);
#endif
{
Info.Slots[GBS_GenericAO] = FGBufferItem(GBS_GenericAO, GBC_Raw_Unorm_8, GBCH_Both);
Info.Slots[GBS_GenericAO].Packing[0] = FGBufferPacking(TargetGBufferC, 0, 3);
}
}
if (Params.bHasVelocity)
{
Info.Slots[GBS_Velocity] = FGBufferItem(GBS_Velocity, Params.bUsesVelocityDepth ? GBC_Raw_Float_16_16_16_16 : GBC_Raw_Float_16_16, GBCH_Both);
Info.Slots[GBS_Velocity].Packing[0] = FGBufferPacking(TargetVelocity, 0, 0);
Info.Slots[GBS_Velocity].Packing[1] = FGBufferPacking(TargetVelocity, 1, 1);
if (Params.bUsesVelocityDepth)
{
Info.Slots[GBS_Velocity].Packing[2] = FGBufferPacking(TargetVelocity, 2, 2);
Info.Slots[GBS_Velocity].Packing[3] = FGBufferPacking(TargetVelocity, 3, 3);
}
}
if (Params.bHasPrecShadowFactor)
{
Info.Slots[GBS_PrecomputedShadowFactor] = FGBufferItem(GBS_PrecomputedShadowFactor, GBC_Raw_Unorm_8_8_8_8, GBCH_Both);
Info.Slots[GBS_PrecomputedShadowFactor].Packing[0] = FGBufferPacking(TargetGBufferE, 0, 0);
Info.Slots[GBS_PrecomputedShadowFactor].Packing[1] = FGBufferPacking(TargetGBufferE, 1, 1);
Info.Slots[GBS_PrecomputedShadowFactor].Packing[2] = FGBufferPacking(TargetGBufferE, 2, 2);
Info.Slots[GBS_PrecomputedShadowFactor].Packing[3] = FGBufferPacking(TargetGBufferE, 3, 3);
}
if (Params.bHasTangent)
{
Info.Slots[GBS_WorldTangent] = FGBufferItem(GBS_WorldTangent, GBC_Raw_Unorm_8_8_8, GBCH_Both);
Info.Slots[GBS_WorldTangent].Packing[0] = FGBufferPacking(TargetGBufferF, 0, 0);
Info.Slots[GBS_WorldTangent].Packing[1] = FGBufferPacking(TargetGBufferF, 1, 1);
Info.Slots[GBS_WorldTangent].Packing[2] = FGBufferPacking(TargetGBufferF, 2, 2);
Info.Slots[GBS_Anisotropy] = FGBufferItem(GBS_Anisotropy, GBC_Raw_Unorm_8, GBCH_Both);
Info.Slots[GBS_Anisotropy].Packing[0] = FGBufferPacking(TargetGBufferF, 0, 3);
}
// GBufferD
Info.Slots[GBS_CustomData] = FGBufferItem(GBS_CustomData, GBC_Raw_Unorm_8_8_8_8, GBCH_Both);
Info.Slots[GBS_CustomData].Packing[0] = FGBufferPacking(TargetGBufferD, 0, 0);
Info.Slots[GBS_CustomData].Packing[1] = FGBufferPacking(TargetGBufferD, 1, 1);
Info.Slots[GBS_CustomData].Packing[2] = FGBufferPacking(TargetGBufferD, 2, 2);
Info.Slots[GBS_CustomData].Packing[3] = FGBufferPacking(TargetGBufferD, 3, 3);
// Special water output
if (Params.bHasSingleLayerWaterSeparatedMainLight)
{
Info.Slots[GBS_SeparatedMainDirLight] = FGBufferItem(GBS_SeparatedMainDirLight, GBC_Raw_Float_11_11_10, GBCH_Both);
Info.Slots[GBS_SeparatedMainDirLight].Packing[0] = FGBufferPacking(TargetSeparatedMainDirLight, 0, 0);
Info.Slots[GBS_SeparatedMainDirLight].Packing[1] = FGBufferPacking(TargetSeparatedMainDirLight, 1, 1);
Info.Slots[GBS_SeparatedMainDirLight].Packing[2] = FGBufferPacking(TargetSeparatedMainDirLight, 2, 2);
}
return Info;
}
FGBufferInfo RENDERCORE_API FetchFullGBufferInfo(const FGBufferParams& Params)
{
// For now, we are only doing legacy. But next, we will have a switch between the old and new formats.
FGBufferInfo Ret = FetchLegacyGBufferInfo(Params);
return Ret;
}