Files
UnrealEngine/Engine/Source/Runtime/Renderer/Private/BasePassRendering.h
2025-05-18 13:04:45 +08:00

1062 lines
45 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
/*=============================================================================
BasePassRendering.h: Base pass rendering definitions.
=============================================================================*/
#pragma once
#include "CoreMinimal.h"
#include "HAL/IConsoleManager.h"
#include "RHI.h"
#include "ShaderParameters.h"
#include "Shader.h"
#include "HitProxies.h"
#include "RHIStaticStates.h"
#include "SceneManagement.h"
#include "Materials/Material.h"
#include "PostProcess/SceneRenderTargets.h"
#include "DBufferTextures.h"
#include "LightMapRendering.h"
#include "VelocityRendering.h"
#include "MeshMaterialShaderType.h"
#include "MeshMaterialShader.h"
#include "ShaderBaseClasses.h"
#include "FogRendering.h"
#include "TranslucentLighting.h"
#include "PlanarReflectionRendering.h"
#include "UnrealEngine.h"
#include "ReflectionEnvironment.h"
#include "Substrate/Substrate.h"
#include "OIT/OITParameters.h"
#include "VirtualShadowMaps/VirtualShadowMapArray.h"
#include "VolumetricCloudRendering.h"
#include "Nanite/NaniteMaterials.h"
#include "BlueNoise.h"
#include "LocalFogVolumeRendering.h"
#include "LightFunctionAtlas.h"
#include "RenderUtils.h"
#include "SceneTexturesConfig.h"
#include "HeterogeneousVolumes/HeterogeneousVolumes.h"
class FScene;
template<typename TBufferStruct> class TUniformBufferRef;
struct FSceneWithoutWaterTextures;
class FViewInfo;
class UMaterialExpressionSingleLayerWaterMaterialOutput;
namespace OIT
{
bool IsSortedPixelsEnabledForProject(EShaderPlatform InPlatform);
}
/** Whether to allow the indirect lighting cache to be applied to dynamic objects. */
extern int32 GIndirectLightingCache;
class FForwardLightData
{
public:
FVector4f LightPositionAndInvRadius;
FVector4f LightColorAndIdAndFalloffExponent;
FVector4f LightDirectionAndSceneInfoExtraDataPacked;
FVector4f SpotAnglesAndSourceRadiusPacked;
FVector4f LightTangentAndIESDataAndSpecularScale;
FVector4f RectDataAndVirtualShadowMapIdOrPrevLocalLightIndex;
};
struct FForwardBasePassTextures
{
FRDGTextureRef ScreenSpaceAO = nullptr;
FRDGTextureRef ScreenSpaceShadowMask = nullptr;
FRDGTextureRef SceneDepthIfResolved = nullptr;
bool bIs24BitUnormDepthStencil = false;
};
BEGIN_GLOBAL_SHADER_PARAMETER_STRUCT(FSharedBasePassUniformParameters,)
SHADER_PARAMETER_STRUCT(FForwardLightUniformParameters, Forward)
SHADER_PARAMETER_STRUCT(FReflectionUniformParameters, Reflection)
SHADER_PARAMETER_STRUCT(FPlanarReflectionUniformParameters, PlanarReflection) // Single global planar reflection for the forward pass.
SHADER_PARAMETER_STRUCT(FFogUniformParameters, Fog)
SHADER_PARAMETER_STRUCT(FFogUniformParameters, FogISR)
SHADER_PARAMETER_STRUCT(FLocalFogVolumeUniformParameters, LFV)
SHADER_PARAMETER_STRUCT(LightFunctionAtlas::FLightFunctionAtlasGlobalParameters, LightFunctionAtlas)
SHADER_PARAMETER(uint32, UseBasePassSkylight)
END_GLOBAL_SHADER_PARAMETER_STRUCT()
BEGIN_GLOBAL_SHADER_PARAMETER_STRUCT(FOpaqueBasePassUniformParameters,)
SHADER_PARAMETER_STRUCT(FSharedBasePassUniformParameters, Shared)
SHADER_PARAMETER_STRUCT(FSubstrateBasePassUniformParameters, Substrate)
// Forward shading
SHADER_PARAMETER(int32, UseForwardScreenSpaceShadowMask)
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, ForwardScreenSpaceShadowMaskTexture)
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, IndirectOcclusionTexture)
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, ResolvedSceneDepthTexture)
// DBuffer decals
SHADER_PARAMETER_STRUCT_INCLUDE(FDBufferParameters, DBuffer)
// Misc
SHADER_PARAMETER_TEXTURE(Texture2D, PreIntegratedGFTexture)
SHADER_PARAMETER_SAMPLER(SamplerState, PreIntegratedGFSampler)
SHADER_PARAMETER(int32, Is24BitUnormDepthStencil)
SHADER_PARAMETER_RDG_BUFFER_SRV(StructuredBuffer<float4>, EyeAdaptationBuffer)
END_GLOBAL_SHADER_PARAMETER_STRUCT()
BEGIN_GLOBAL_SHADER_PARAMETER_STRUCT(FTranslucentBasePassUniformParameters,)
SHADER_PARAMETER_STRUCT(FSharedBasePassUniformParameters, Shared)
SHADER_PARAMETER_STRUCT(FSceneTextureUniformParameters, SceneTextures)
SHADER_PARAMETER_STRUCT(FSubstrateForwardPassUniformParameters, Substrate)
SHADER_PARAMETER_STRUCT(FLightCloudTransmittanceParameters, ForwardDirLightCloudShadow)
SHADER_PARAMETER_STRUCT(FOITBasePassUniformParameters, OIT)
// Material SSR
SHADER_PARAMETER_STRUCT_INCLUDE(FHZBParameters, HZBParameters)
SHADER_PARAMETER(FVector4f, PrevScreenPositionScaleBias)
SHADER_PARAMETER(FVector2f, PrevSceneColorBilinearUVMin)
SHADER_PARAMETER(FVector2f, PrevSceneColorBilinearUVMax)
SHADER_PARAMETER(float, PrevSceneColorPreExposureInv)
SHADER_PARAMETER(int32, SSRQuality)
SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D, PrevSceneColor)
SHADER_PARAMETER_SAMPLER(SamplerState, PrevSceneColorSampler)
// Volumetric cloud
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, VolumetricCloudColor)
SHADER_PARAMETER_SAMPLER(SamplerState, VolumetricCloudColorSampler)
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, VolumetricCloudDepth)
SHADER_PARAMETER_SAMPLER(SamplerState, VolumetricCloudDepthSampler)
SHADER_PARAMETER(float, ApplyVolumetricCloudOnTransparent)
SHADER_PARAMETER(float, SoftBlendingDistanceKm)
SHADER_PARAMETER(FVector2f, VolumetricCloudColorUVScale)
SHADER_PARAMETER(FVector2f, VolumetricCloudColorUVMax)
// Translucency Lighting Volume
SHADER_PARAMETER_STRUCT_INCLUDE(FTranslucencyLightingVolumeParameters, TranslucencyLightingVolume)
SHADER_PARAMETER_STRUCT_INCLUDE(FLumenTranslucencyLightingParameters, LumenParameters)
SHADER_PARAMETER_TEXTURE(Texture2D, PreIntegratedGFTexture)
SHADER_PARAMETER_SAMPLER(SamplerState, PreIntegratedGFSampler)
// Misc
SHADER_PARAMETER_RDG_BUFFER_SRV(StructuredBuffer<float4>, EyeAdaptationBuffer)
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, SceneColorCopyTexture)
SHADER_PARAMETER_SAMPLER(SamplerState, SceneColorCopySampler)
SHADER_PARAMETER_STRUCT(FBlueNoiseParameters, BlueNoise)
SHADER_PARAMETER_STRUCT(FAdaptiveVolumetricShadowMapUniformBufferParameters, AVSM)
SHADER_PARAMETER(int, TranslucencyPass)
END_GLOBAL_SHADER_PARAMETER_STRUCT()
DECLARE_GPU_DRAWCALL_STAT_EXTERN(Basepass);
DECLARE_GPU_STAT_NAMED_EXTERN(NaniteBasePass, TEXT("Nanite BasePass"));
extern void SetupSharedBasePassParameters(
FRDGBuilder& GraphBuilder,
const FViewInfo& View,
const int32 ViewIndex,
bool bLumenGIEnabled,
FSharedBasePassUniformParameters& BasePassParameters,
bool bForRealtimeSkyCapture = false);
extern TRDGUniformBufferRef<FOpaqueBasePassUniformParameters> CreateOpaqueBasePassUniformBuffer(
FRDGBuilder& GraphBuilder,
const FViewInfo& View,
const int32 ViewIndex = 0,
const FForwardBasePassTextures& ForwardBasePassTextures = {},
const FDBufferTextures& DBufferTextures = {},
bool bLumenGIEnabled = false,
bool bForRealtimeSkyCapture = false);
extern TRDGUniformBufferRef<FTranslucentBasePassUniformParameters> CreateTranslucentBasePassUniformBuffer(
FRDGBuilder& GraphBuilder,
const FScene* Scene,
const FViewInfo& View,
const int32 ViewIndex = 0,
const FTranslucencyLightingVolumeTextures& TranslucencyLightingVolumeTextures = {},
FRDGTextureRef SceneColorCopyTexture = nullptr,
const ESceneTextureSetupMode SceneTextureSetupMode = ESceneTextureSetupMode::None,
bool bLumenGIEnabled = false,
ETranslucencyPass::Type TranslucencyPass = ETranslucencyPass::TPT_MAX);
extern bool IsGBufferLayoutSupportedForMaterial(EGBufferLayout Layout, const FMeshMaterialShaderPermutationParameters& Params);
extern void ModifyBasePassCSPSCompilationEnvironment(const FMeshMaterialShaderPermutationParameters& Params, EGBufferLayout GBufferLayout, bool bEnableSkyLight, FShaderCompilerEnvironment& OutEnvironment);
/** Parameters for computing forward lighting. */
class FForwardLightingParameters
{
public:
static void ModifyCompilationEnvironment(EShaderPlatform Platform, FShaderCompilerEnvironment& OutEnvironment)
{
OutEnvironment.SetDefine(TEXT("FORWARD_LIGHT_DATA_STRIDE"), FMath::DivideAndRoundUp<int32>(sizeof(FForwardLightData), sizeof(FVector4f)));
extern int32 NumCulledLightsGridStride;
OutEnvironment.SetDefine(TEXT("NUM_CULLED_LIGHTS_GRID_STRIDE"), NumCulledLightsGridStride);
extern int32 NumCulledGridPrimitiveTypes;
OutEnvironment.SetDefine(TEXT("NUM_CULLED_GRID_PRIMITIVE_TYPES"), NumCulledGridPrimitiveTypes);
}
};
template<typename LightMapPolicyType>
class TBasePassShaderElementData : public FMeshMaterialShaderElementData
{
public:
TBasePassShaderElementData(const typename LightMapPolicyType::ElementDataType& InLightMapPolicyElementData) :
LightMapPolicyElementData(InLightMapPolicyElementData)
{}
typename LightMapPolicyType::ElementDataType LightMapPolicyElementData;
};
/**
* The base shader type for vertex shaders that render the emissive color, and light-mapped/ambient lighting of a mesh.
* The base type is shared between the versions with and without atmospheric fog.
*/
template<typename LightMapPolicyType>
class TBasePassVertexShaderPolicyParamType : public FMeshMaterialShader, public LightMapPolicyType::VertexParametersType
{
DECLARE_INLINE_TYPE_LAYOUT_EXPLICIT_BASES(TBasePassVertexShaderPolicyParamType, NonVirtual, FMeshMaterialShader, typename LightMapPolicyType::VertexParametersType);
protected:
TBasePassVertexShaderPolicyParamType() {}
TBasePassVertexShaderPolicyParamType(const FMeshMaterialShaderType::CompiledShaderInitializerType& Initializer):
FMeshMaterialShader(Initializer)
{
LightMapPolicyType::VertexParametersType::Bind(Initializer.ParameterMap);
ReflectionCaptureBuffer.Bind(Initializer.ParameterMap, TEXT("ReflectionCapture"));
}
public:
static void ModifyCompilationEnvironment(const FMaterialShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment)
{
FMeshMaterialShader::ModifyCompilationEnvironment(Parameters, OutEnvironment);
FForwardLightingParameters::ModifyCompilationEnvironment(Parameters.Platform, OutEnvironment);
}
void GetShaderBindings(
const FScene* Scene,
ERHIFeatureLevel::Type FeatureLevel,
const FPrimitiveSceneProxy* PrimitiveSceneProxy,
const FMaterialRenderProxy& MaterialRenderProxy,
const FMaterial& Material,
const TBasePassShaderElementData<LightMapPolicyType>& ShaderElementData,
FMeshDrawSingleShaderBindings& ShaderBindings) const;
void GetElementShaderBindings(
const FShaderMapPointerTable& PointerTable,
const FScene* Scene,
const FSceneView* ViewIfDynamicMeshCommand,
const FVertexFactory* VertexFactory,
const EVertexInputStreamType InputStreamType,
ERHIFeatureLevel::Type FeatureLevel,
const FPrimitiveSceneProxy* PrimitiveSceneProxy,
const FMeshBatch& MeshBatch,
const FMeshBatchElement& BatchElement,
const TBasePassShaderElementData<LightMapPolicyType>& ShaderElementData,
FMeshDrawSingleShaderBindings& ShaderBindings,
FVertexInputStreamArray& VertexStreams) const;
LAYOUT_FIELD(FShaderUniformBufferParameter, ReflectionCaptureBuffer);
};
/**
* The base shader type for vertex shaders that render the emissive color, and light-mapped/ambient lighting of a mesh.
* The base type is shared between the versions with and without atmospheric fog.
*/
template<typename LightMapPolicyType>
class TBasePassVertexShaderBaseType : public TBasePassVertexShaderPolicyParamType<LightMapPolicyType>
{
typedef TBasePassVertexShaderPolicyParamType<LightMapPolicyType> Super;
DECLARE_INLINE_TYPE_LAYOUT(TBasePassVertexShaderBaseType, NonVirtual);
protected:
TBasePassVertexShaderBaseType(const FMeshMaterialShaderType::CompiledShaderInitializerType& Initializer) : Super(Initializer) {}
TBasePassVertexShaderBaseType() {}
public:
static bool ShouldCompilePermutation(const FMeshMaterialShaderPermutationParameters& Parameters)
{
return LightMapPolicyType::ShouldCompilePermutation(Parameters);
}
static void ModifyCompilationEnvironment(const FMeshMaterialShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment)
{
LightMapPolicyType::ModifyCompilationEnvironment(Parameters, OutEnvironment);
Super::ModifyCompilationEnvironment(Parameters, OutEnvironment);
if (HardwareVariableRateShadingSupportedByPlatform(Parameters.Platform) && Parameters.MaterialParameters.bAllowVariableRateShading)
{
OutEnvironment.SetCompileArgument(TEXT("USING_VARIABLE_RATE_SHADING"), true);
}
}
};
template<typename LightMapPolicyType>
class TBasePassVS : public TBasePassVertexShaderBaseType<LightMapPolicyType>
{
DECLARE_SHADER_TYPE(TBasePassVS,MeshMaterial);
typedef TBasePassVertexShaderBaseType<LightMapPolicyType> Super;
protected:
TBasePassVS() {}
TBasePassVS(const FMeshMaterialShaderType::CompiledShaderInitializerType& Initializer):
Super(Initializer)
{
}
public:
static bool ShouldCompilePermutation(const FMeshMaterialShaderPermutationParameters& Parameters)
{
static const auto SupportAllShaderPermutations = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.SupportAllShaderPermutations"));
const bool bForceAllPermutations = SupportAllShaderPermutations && SupportAllShaderPermutations->GetValueOnAnyThread() != 0;
bool bShouldCache = Super::ShouldCompilePermutation(Parameters) || bForceAllPermutations;
return bShouldCache && (IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5));
}
static void ModifyCompilationEnvironment(const FMeshMaterialShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment)
{
Super::ModifyCompilationEnvironment(Parameters, OutEnvironment);
// @todo MetalMRT: Remove this hack and implement proper atmospheric-fog solution for Metal MRT...
OutEnvironment.SetDefine(TEXT("BASEPASS_SKYATMOSPHERE_AERIALPERSPECTIVE"), !IsMetalMRTPlatform(Parameters.Platform) ? 1 : 0);
// GBUFFER_LAYOUT is used to derive GBUFFER_HAS_VELOCITY, which influences whether VelocityPrevScreenPosition is computed by the vertex shader.
// SLW can force velocity to be drawn in the water base pass even if the rest of the scene outputs in the depth prepass. SLW achieves this override
// by using GBL_ForceVelocity, which requires setting the corresponding define on the vertex shader as well, as the calculation for VelocityPrevScreenPosition will be stripped otherwise.
static const auto SLWForceVelocityCVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.Water.SingleLayer.ForceVelocity"));
const bool bSLWForceVelocity = SLWForceVelocityCVar && SLWForceVelocityCVar->GetValueOnAnyThread() != 0;
if (bSLWForceVelocity && Parameters.MaterialParameters.ShadingModels.HasShadingModel(MSM_SingleLayerWater))
{
OutEnvironment.SetDefine(TEXT("GBUFFER_LAYOUT"), GBL_ForceVelocity);
}
}
};
BEGIN_UNIFORM_BUFFER_STRUCT(FComputeShadingOutputs, )
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float4>, OutTarget0)
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float4>, OutTarget1)
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float4>, OutTarget2)
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float4>, OutTarget3)
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float4>, OutTarget4)
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float4>, OutTarget5)
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float4>, OutTarget6)
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float4>, OutTarget7)
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2DArray<uint>, OutTargets)
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<SUBSTRATE_TOP_LAYER_TYPE>, OutTopLayerTarget)
END_UNIFORM_BUFFER_STRUCT()
/**
* The base type for compute shaders that render the emissive color, and light-mapped/ambient lighting of a mesh.
* The base type is shared between the versions with and without sky light.
*/
template<typename LightMapPolicyType>
class TBasePassComputeShaderPolicyParamType : public FMeshMaterialShader, public LightMapPolicyType::ComputeParametersType
{
DECLARE_INLINE_TYPE_LAYOUT_EXPLICIT_BASES(TBasePassComputeShaderPolicyParamType, NonVirtual, FMeshMaterialShader, typename LightMapPolicyType::ComputeParametersType);
public:
static void ModifyCompilationEnvironment(const FMeshMaterialShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment)
{
FMaterialShader::ModifyCompilationEnvironment(Parameters, OutEnvironment);
FForwardLightingParameters::ModifyCompilationEnvironment(Parameters.Platform, OutEnvironment);
}
static bool ValidateCompiledResult(EShaderPlatform Platform, const FShaderParameterMap& ParameterMap, TArray<FString>& OutError)
{
if (ParameterMap.ContainsParameterAllocation(FSceneTextureUniformParameters::FTypeInfo::GetStructMetadata()->GetShaderVariableName()))
{
OutError.Add(TEXT("Base pass shaders cannot read from the SceneTexturesStruct."));
return false;
}
return true;
}
/** Initialization constructor. */
TBasePassComputeShaderPolicyParamType(const FMeshMaterialShaderType::CompiledShaderInitializerType& Initializer):
FMeshMaterialShader(Initializer)
{
LightMapPolicyType::ComputeParametersType::Bind(Initializer.ParameterMap);
ReflectionCaptureBuffer.Bind(Initializer.ParameterMap, TEXT("ReflectionCapture"));
ShadingOutputsParam.Bind(Initializer.ParameterMap, TEXT("ComputeShadingOutputs"));
ViewRectParam.Bind(Initializer.ParameterMap, TEXT("ViewRect"));
PassDataParam.Bind(Initializer.ParameterMap, TEXT("PassData"));
Target0.Bind(Initializer.ParameterMap, TEXT("ComputeShadingOutputs.OutTarget0"));
Target1.Bind(Initializer.ParameterMap, TEXT("ComputeShadingOutputs.OutTarget1"));
Target2.Bind(Initializer.ParameterMap, TEXT("ComputeShadingOutputs.OutTarget2"));
Target3.Bind(Initializer.ParameterMap, TEXT("ComputeShadingOutputs.OutTarget3"));
Target4.Bind(Initializer.ParameterMap, TEXT("ComputeShadingOutputs.OutTarget4"));
Target5.Bind(Initializer.ParameterMap, TEXT("ComputeShadingOutputs.OutTarget5"));
Target6.Bind(Initializer.ParameterMap, TEXT("ComputeShadingOutputs.OutTarget6"));
Target7.Bind(Initializer.ParameterMap, TEXT("ComputeShadingOutputs.OutTarget7"));
Targets.Bind(Initializer.ParameterMap, TEXT("ComputeShadingOutputs.OutTargets"));
// These parameters should only be used nested in the base pass uniform buffer
check(!Initializer.ParameterMap.ContainsParameterAllocation(FFogUniformParameters::FTypeInfo::GetStructMetadata()->GetShaderVariableName()));
check(!Initializer.ParameterMap.ContainsParameterAllocation(FReflectionUniformParameters::FTypeInfo::GetStructMetadata()->GetShaderVariableName()));
check(!Initializer.ParameterMap.ContainsParameterAllocation(FPlanarReflectionUniformParameters::FTypeInfo::GetStructMetadata()->GetShaderVariableName()));
}
TBasePassComputeShaderPolicyParamType() {}
void GetShaderBindings(
const FScene* Scene,
ERHIFeatureLevel::Type FeatureLevel,
const FPrimitiveSceneProxy* PrimitiveSceneProxy,
const FMaterialRenderProxy& MaterialRenderProxy,
const FMaterial& Material,
const TBasePassShaderElementData<LightMapPolicyType>& ShaderElementData,
FMeshDrawSingleShaderBindings& ShaderBindings) const;
void SetPassParameters(
FRHIBatchedShaderParameters& BatchedParameters,
const FUintVector4& ViewRect,
const FUintVector4& PassData,
FRHIUniformBuffer* ShadingOutputs
);
uint32 GetBoundTargetMask() const;
private:
LAYOUT_FIELD(FShaderUniformBufferParameter, ReflectionCaptureBuffer);
LAYOUT_FIELD(FShaderUniformBufferParameter, ShadingOutputsParam);
LAYOUT_FIELD(FShaderParameter, ViewRectParam);
LAYOUT_FIELD(FShaderParameter, PassDataParam);
LAYOUT_FIELD(FShaderUniformBufferMemberParameter, Target0);
LAYOUT_FIELD(FShaderUniformBufferMemberParameter, Target1);
LAYOUT_FIELD(FShaderUniformBufferMemberParameter, Target2);
LAYOUT_FIELD(FShaderUniformBufferMemberParameter, Target3);
LAYOUT_FIELD(FShaderUniformBufferMemberParameter, Target4);
LAYOUT_FIELD(FShaderUniformBufferMemberParameter, Target5);
LAYOUT_FIELD(FShaderUniformBufferMemberParameter, Target6);
LAYOUT_FIELD(FShaderUniformBufferMemberParameter, Target7);
LAYOUT_FIELD(FShaderUniformBufferMemberParameter, Targets);
};
/**
* The base type for compute shaders that render the emissive color, and light-mapped/ambient lighting of a mesh.
* The base type is shared between the versions with and without sky light.
*/
template<typename LightMapPolicyType>
class TBasePassComputeShaderBaseType : public TBasePassComputeShaderPolicyParamType<LightMapPolicyType>
{
typedef TBasePassComputeShaderPolicyParamType<LightMapPolicyType> Super;
DECLARE_INLINE_TYPE_LAYOUT(TBasePassComputeShaderBaseType, NonVirtual);
public:
static bool ShouldCompilePermutation(const FMeshMaterialShaderPermutationParameters& Parameters)
{
return LightMapPolicyType::ShouldCompilePermutation(Parameters);
}
static void ModifyCompilationEnvironment(const FMeshMaterialShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment)
{
LightMapPolicyType::ModifyCompilationEnvironment(Parameters, OutEnvironment);
Super::ModifyCompilationEnvironment(Parameters, OutEnvironment);
}
/** Initialization constructor. */
TBasePassComputeShaderBaseType(const FMeshMaterialShaderType::CompiledShaderInitializerType& Initializer) : Super(Initializer) {}
TBasePassComputeShaderBaseType() {}
};
/** The concrete base pass compute shader type. */
template<typename LightMapPolicyType, bool bEnableSkyLight, EShaderFrequency ShaderFrequency>
class TBasePassCS : public TBasePassComputeShaderBaseType<LightMapPolicyType>
{
DECLARE_SHADER_TYPE(TBasePassCS,MeshMaterial);
class FVisualizeDim : SHADER_PERMUTATION_BOOL("VISUALIZE");
using FPermutationDomain = TShaderPermutationDomain<FVisualizeDim>;
public:
static bool ShouldCompilePermutation(const FMeshMaterialShaderPermutationParameters& Parameters)
{
// Only compile skylight version for lit materials, and if the project allows them.
static const auto SupportStationarySkylight = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.SupportStationarySkylight"));
static const auto SupportAllShaderPermutations = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.SupportAllShaderPermutations"));
const bool IsSingleLayerWater = Parameters.MaterialParameters.ShadingModels.HasShadingModel(MSM_SingleLayerWater);
const bool bTranslucent = IsTranslucentBlendMode(Parameters.MaterialParameters);
const bool bForceAllPermutations = SupportAllShaderPermutations && SupportAllShaderPermutations->GetValueOnAnyThread() != 0;
const bool bProjectSupportsStationarySkylight = !SupportStationarySkylight || SupportStationarySkylight->GetValueOnAnyThread() != 0 || bForceAllPermutations;
// Debug visualization shaders are ODSC only.
FPermutationDomain PermutationVector{ Parameters.PermutationId };
if (PermutationVector.template Get<FVisualizeDim>() && !EnumHasAllFlags(Parameters.Flags, EShaderPermutationFlags::IsODSCOnly))
{
return false;
}
const bool bCacheShaders = !bEnableSkyLight
//translucent materials need to compile skylight support to support MOVABLE skylights also.
|| bTranslucent
|| IsSingleLayerWater
|| ((bProjectSupportsStationarySkylight || IsForwardShadingEnabled(Parameters.Platform)) && Parameters.MaterialParameters.ShadingModels.IsLit());
return bCacheShaders
&& (IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5))
&& Parameters.VertexFactoryType->SupportsComputeShading()
&& TBasePassComputeShaderBaseType<LightMapPolicyType>::ShouldCompilePermutation(Parameters);
}
static void ModifyCompilationEnvironment(const FMeshMaterialShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment)
{
ModifyBasePassCSPSCompilationEnvironment(Parameters, GBL_ForceVelocity, bEnableSkyLight, OutEnvironment);
OutEnvironment.SetDefine(TEXT("COMPUTE_SHADED"), 1);
if (ShaderFrequency == SF_WorkGraphComputeNode)
{
OutEnvironment.SetDefine(TEXT("WORKGRAPH_NODE"), 1);
}
const bool bTranslucent = IsTranslucentBlendMode(Parameters.MaterialParameters);
const bool bIsSingleLayerWater = Parameters.MaterialParameters.ShadingModels.HasShadingModel(MSM_SingleLayerWater);
const bool bSingleLayerWaterUsesLightFunctionAtlas = bIsSingleLayerWater && GetSingleLayerWaterUsesLightFunctionAtlas();
const bool bTranslucentUsesLightFunctionAtlas = bTranslucent && GetTranslucentUsesLightFunctionAtlas();
OutEnvironment.SetDefine(TEXT("USE_LIGHT_FUNCTION_ATLAS"), (bSingleLayerWaterUsesLightFunctionAtlas || bTranslucentUsesLightFunctionAtlas) ? TEXT("1") : TEXT("0"));
TBasePassComputeShaderBaseType<LightMapPolicyType>::ModifyCompilationEnvironment(Parameters, OutEnvironment);
}
/** Initialization constructor. */
TBasePassCS(const ShaderMetaType::CompiledShaderInitializerType& Initializer):
TBasePassComputeShaderBaseType<LightMapPolicyType>(Initializer)
{}
/** Default constructor. */
TBasePassCS() {}
};
/**
* The base type for pixel shaders that render the emissive color, and light-mapped/ambient lighting of a mesh.
* The base type is shared between the versions with and without sky light.
*/
template<typename LightMapPolicyType>
class TBasePassPixelShaderPolicyParamType : public FMeshMaterialShader, public LightMapPolicyType::PixelParametersType
{
DECLARE_INLINE_TYPE_LAYOUT_EXPLICIT_BASES(TBasePassPixelShaderPolicyParamType, NonVirtual, FMeshMaterialShader, typename LightMapPolicyType::PixelParametersType);
public:
static void ModifyCompilationEnvironment(const FMeshMaterialShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment)
{
FMeshMaterialShader::ModifyCompilationEnvironment(Parameters, OutEnvironment);
FForwardLightingParameters::ModifyCompilationEnvironment(Parameters.Platform, OutEnvironment);
if (HardwareVariableRateShadingSupportedByPlatform(Parameters.Platform) && Parameters.MaterialParameters.bAllowVariableRateShading)
{
OutEnvironment.SetCompileArgument(TEXT("USING_VARIABLE_RATE_SHADING"), true);
}
}
static bool ValidateCompiledResult(EShaderPlatform Platform, const FShaderParameterMap& ParameterMap, TArray<FString>& OutError)
{
if (ParameterMap.ContainsParameterAllocation(FSceneTextureUniformParameters::FTypeInfo::GetStructMetadata()->GetShaderVariableName()))
{
OutError.Add(TEXT("Base pass shaders cannot read from the SceneTexturesStruct."));
return false;
}
return true;
}
/** Initialization constructor. */
TBasePassPixelShaderPolicyParamType(const FMeshMaterialShaderType::CompiledShaderInitializerType& Initializer):
FMeshMaterialShader(Initializer)
{
LightMapPolicyType::PixelParametersType::Bind(Initializer.ParameterMap);
ReflectionCaptureBuffer.Bind(Initializer.ParameterMap, TEXT("ReflectionCapture"));
// These parameters should only be used nested in the base pass uniform buffer
check(!Initializer.ParameterMap.ContainsParameterAllocation(FFogUniformParameters::FTypeInfo::GetStructMetadata()->GetShaderVariableName()));
check(!Initializer.ParameterMap.ContainsParameterAllocation(FReflectionUniformParameters::FTypeInfo::GetStructMetadata()->GetShaderVariableName()));
check(!Initializer.ParameterMap.ContainsParameterAllocation(FPlanarReflectionUniformParameters::FTypeInfo::GetStructMetadata()->GetShaderVariableName()));
}
TBasePassPixelShaderPolicyParamType() {}
void GetShaderBindings(
const FScene* Scene,
ERHIFeatureLevel::Type FeatureLevel,
const FPrimitiveSceneProxy* PrimitiveSceneProxy,
const FMaterialRenderProxy& MaterialRenderProxy,
const FMaterial& Material,
const TBasePassShaderElementData<LightMapPolicyType>& ShaderElementData,
FMeshDrawSingleShaderBindings& ShaderBindings) const;
private:
LAYOUT_FIELD(FShaderUniformBufferParameter, ReflectionCaptureBuffer);
};
/**
* The base type for pixel shaders that render the emissive color, and light-mapped/ambient lighting of a mesh.
* The base type is shared between the versions with and without sky light.
*/
template<typename LightMapPolicyType>
class TBasePassPixelShaderBaseType : public TBasePassPixelShaderPolicyParamType<LightMapPolicyType>
{
typedef TBasePassPixelShaderPolicyParamType<LightMapPolicyType> Super;
DECLARE_INLINE_TYPE_LAYOUT(TBasePassPixelShaderBaseType, NonVirtual);
public:
static bool ShouldCompilePermutation(const FMeshMaterialShaderPermutationParameters& Parameters)
{
return LightMapPolicyType::ShouldCompilePermutation(Parameters);
}
static void ModifyCompilationEnvironment(const FMeshMaterialShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment)
{
LightMapPolicyType::ModifyCompilationEnvironment(Parameters, OutEnvironment);
Super::ModifyCompilationEnvironment(Parameters, OutEnvironment);
}
/** Initialization constructor. */
TBasePassPixelShaderBaseType(const FMeshMaterialShaderType::CompiledShaderInitializerType& Initializer) : Super(Initializer) {}
TBasePassPixelShaderBaseType() {}
};
/** The concrete base pass pixel shader type. */
template<typename LightMapPolicyType, bool bEnableSkyLight, EGBufferLayout GBufferLayout>
class TBasePassPS : public TBasePassPixelShaderBaseType<LightMapPolicyType>
{
DECLARE_SHADER_TYPE(TBasePassPS,MeshMaterial);
class FVisualizeDim : SHADER_PERMUTATION_BOOL("VISUALIZE");
class FSupportOITDim : SHADER_PERMUTATION_BOOL("PERMUTATION_SUPPORTS_OIT");
using FPermutationDomain = TShaderPermutationDomain<FVisualizeDim, FSupportOITDim>;
public:
static bool ShouldCompilePermutation(const FMeshMaterialShaderPermutationParameters& Parameters)
{
// Only compile skylight version for lit materials, and if the project allows them.
static const auto SupportStationarySkylight = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.SupportStationarySkylight"));
static const auto SupportAllShaderPermutations = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.SupportAllShaderPermutations"));
const bool IsSingleLayerWater = Parameters.MaterialParameters.ShadingModels.HasShadingModel(MSM_SingleLayerWater);
const bool bTranslucent = IsTranslucentBlendMode(Parameters.MaterialParameters);
const bool bForceAllPermutations = SupportAllShaderPermutations && SupportAllShaderPermutations->GetValueOnAnyThread() != 0;
const bool bProjectSupportsStationarySkylight = !SupportStationarySkylight || SupportStationarySkylight->GetValueOnAnyThread() != 0 || bForceAllPermutations;
FPermutationDomain PermutationVector{ Parameters.PermutationId };
// Debug visualization shaders are ODSC only.
if (PermutationVector.template Get<FVisualizeDim>() && !EnumHasAllFlags(Parameters.Flags, EShaderPermutationFlags::IsODSCOnly))
{
return false;
}
// Only compiled OIT permutation for translucent surface, and if OIT sorted pixel is enabled for the current project
if (PermutationVector.template Get<FSupportOITDim>())
{
if (!bTranslucent || !OIT::IsSortedPixelsEnabledForProject(Parameters.Platform))
{
return false;
}
}
const bool bCacheShaders = !bEnableSkyLight
//translucent materials need to compile skylight support to support MOVABLE skylights also.
|| bTranslucent
|| IsSingleLayerWater
|| ((bProjectSupportsStationarySkylight || IsForwardShadingEnabled(Parameters.Platform)) && Parameters.MaterialParameters.ShadingModels.IsLit());
return bCacheShaders
&& (IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5))
&& TBasePassPixelShaderBaseType<LightMapPolicyType>::ShouldCompilePermutation(Parameters)
&& IsGBufferLayoutSupportedForMaterial(GBufferLayout, Parameters);
}
static void ModifyCompilationEnvironment(const FMeshMaterialShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment)
{
ModifyBasePassCSPSCompilationEnvironment(Parameters, GBufferLayout, bEnableSkyLight, OutEnvironment);
const bool bIsSingleLayerWater = Parameters.MaterialParameters.ShadingModels.HasShadingModel(MSM_SingleLayerWater);
if (bIsSingleLayerWater)
{
const bool bHasDepthPrepass = IsSingleLayerWaterDepthPrepassEnabled(Parameters.Platform, GetMaxSupportedFeatureLevel(Parameters.Platform));
if (bHasDepthPrepass)
{
OutEnvironment.SetDefine(TEXT("SINGLE_LAYER_WATER_NO_DISCARD"), TEXT("1"));
}
}
const bool bTranslucent = IsTranslucentBlendMode(Parameters.MaterialParameters);
const bool bSingleLayerWaterUsesLightFunctionAtlas = bIsSingleLayerWater && GetSingleLayerWaterUsesLightFunctionAtlas();
const bool bTranslucentUsesLightFunctionAtlas = bTranslucent && GetTranslucentUsesLightFunctionAtlas();
OutEnvironment.SetDefine(TEXT("USE_LIGHT_FUNCTION_ATLAS"), (bSingleLayerWaterUsesLightFunctionAtlas || bTranslucentUsesLightFunctionAtlas) ? TEXT("1") : TEXT("0"));
const bool bIsTranslucent = IsTranslucentBlendMode(Parameters.MaterialParameters);
if (bIsTranslucent && DoesPlatformSupportHeterogeneousVolumes(Parameters.Platform) && ShouldCompositeHeterogeneousVolumesWithTranslucency())
{
OutEnvironment.SetDefine(TEXT("ADAPTIVE_VOLUMETRIC_SHADOW_MAP"), TEXT("1"));
}
TBasePassPixelShaderBaseType<LightMapPolicyType>::ModifyCompilationEnvironment(Parameters, OutEnvironment);
}
/** Initialization constructor. */
TBasePassPS(const ShaderMetaType::CompiledShaderInitializerType& Initializer):
TBasePassPixelShaderBaseType<LightMapPolicyType>(Initializer)
{}
/** Default constructor. */
TBasePassPS() {}
};
//Alternative base pass PS for 128 bit canvas render targets that need to be set at shader compilation time.
class F128BitRTBasePassPS : public TBasePassPS<TUniformLightMapPolicy<LMP_NO_LIGHTMAP>, false, GBL_Default>
{
DECLARE_SHADER_TYPE(F128BitRTBasePassPS, MeshMaterial);
public:
F128BitRTBasePassPS();
F128BitRTBasePassPS(const ShaderMetaType::CompiledShaderInitializerType& Initializer);
static bool ShouldCompilePermutation(const FMeshMaterialShaderPermutationParameters& Parameters);
static void ModifyCompilationEnvironment(const FMeshMaterialShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment);
};
/**
* Get shader templates allowing to redirect between compatible shaders.
*/
template <typename LightMapPolicyType>
void AddBasePassComputeShader(bool bEnableSkyLight, bool bIsDebug, EShaderFrequency ShaderFrequency, FMaterialShaderTypes& OutShaderTypes)
{
int32 PermutationId = 0;
if (bIsDebug)
{
using FMyShader = TBasePassCS<LightMapPolicyType, true, SF_Compute>;
typename FMyShader::FPermutationDomain PermutationVector;
PermutationVector.template Set<typename FMyShader::FVisualizeDim>(bIsDebug);
PermutationId = PermutationVector.ToDimensionValueId();
}
if (ShaderFrequency == SF_Compute)
{
if (bEnableSkyLight)
{
OutShaderTypes.AddShaderType<TBasePassCS<LightMapPolicyType, true, SF_Compute>>(PermutationId);
}
else
{
OutShaderTypes.AddShaderType<TBasePassCS<LightMapPolicyType, false, SF_Compute>>(PermutationId);
}
}
else if (ShaderFrequency == SF_WorkGraphComputeNode)
{
if (bEnableSkyLight)
{
OutShaderTypes.AddShaderType<TBasePassCS<LightMapPolicyType, true, SF_WorkGraphComputeNode>>(PermutationId);
}
else
{
OutShaderTypes.AddShaderType<TBasePassCS<LightMapPolicyType, false, SF_WorkGraphComputeNode>>(PermutationId);
}
}
}
template <typename LightMapPolicyType>
bool GetBasePassShader(
const FMaterial& Material,
const FVertexFactoryType* VertexFactoryType,
LightMapPolicyType LightMapPolicy,
ERHIFeatureLevel::Type FeatureLevel,
bool bEnableSkyLight,
bool bIsDebug,
EShaderFrequency ShaderFrequency,
TShaderRef<TBasePassComputeShaderPolicyParamType<LightMapPolicyType>>* ComputeShader
)
{
FMaterialShaderTypes ShaderTypes;
if (ComputeShader)
{
AddBasePassComputeShader<LightMapPolicyType>(bEnableSkyLight, bIsDebug, ShaderFrequency, ShaderTypes);
}
FMaterialShaders Shaders;
if (!Material.TryGetShaders(ShaderTypes, VertexFactoryType, Shaders))
{
return false;
}
Shaders.TryGetShader(ShaderFrequency, ComputeShader);
return true;
}
template <>
bool GetBasePassShader<FUniformLightMapPolicy>(
const FMaterial& Material,
const FVertexFactoryType* VertexFactoryType,
FUniformLightMapPolicy LightMapPolicy,
ERHIFeatureLevel::Type FeatureLevel,
bool bEnableSkyLight,
bool bIsDebug,
EShaderFrequency ShaderFrequency,
TShaderRef<TBasePassComputeShaderPolicyParamType<FUniformLightMapPolicy>>* ComputeShader
);
/**
* Get shader templates allowing to redirect between compatible shaders.
*/
template <typename LightMapPolicyType, EGBufferLayout GBufferLayout>
void AddBasePassPixelShader(bool bEnableSkyLight, bool bIsDebug, FMaterialShaderTypes& OutShaderTypes, bool bIsForOITPass = false)
{
int32 PermutationId = 0;
if (bIsDebug || bIsForOITPass)
{
using FMyShader = TBasePassPS<LightMapPolicyType, true, GBufferLayout>;
typename FMyShader::FPermutationDomain PermutationVector;
PermutationVector.template Set<typename FMyShader::FVisualizeDim>(bIsDebug);
PermutationVector.template Set<typename FMyShader::FSupportOITDim>(bIsForOITPass);
PermutationId = PermutationVector.ToDimensionValueId();
}
if (bEnableSkyLight)
{
OutShaderTypes.AddShaderType<TBasePassPS<LightMapPolicyType, true, GBufferLayout>>(PermutationId);
}
else
{
OutShaderTypes.AddShaderType<TBasePassPS<LightMapPolicyType, false, GBufferLayout>>(PermutationId);
}
}
template <typename LightMapPolicyType>
bool GetBasePassShaders(
const FMaterial& Material,
const FVertexFactoryType* VertexFactoryType,
LightMapPolicyType LightMapPolicy,
ERHIFeatureLevel::Type FeatureLevel,
bool bEnableSkyLight,
bool bIsDebug,
bool bUse128bitRT,
EGBufferLayout GBufferLayout,
TShaderRef<TBasePassVertexShaderPolicyParamType<LightMapPolicyType>>* VertexShader,
TShaderRef<TBasePassPixelShaderPolicyParamType<LightMapPolicyType>>* PixelShader,
bool bIsForOITPass = false
)
{
FMaterialShaderTypes ShaderTypes;
if (VertexShader)
{
ShaderTypes.AddShaderType<TBasePassVS<LightMapPolicyType>>();
}
if (PixelShader)
{
switch (GBufferLayout)
{
case GBL_Default:
AddBasePassPixelShader<LightMapPolicyType, GBL_Default>(bEnableSkyLight, bIsDebug, ShaderTypes, bIsForOITPass);
break;
case GBL_ForceVelocity:
AddBasePassPixelShader<LightMapPolicyType, GBL_ForceVelocity>(bEnableSkyLight, bIsDebug, ShaderTypes, bIsForOITPass);
break;
default:
check(false);
break;
}
}
FMaterialShaders Shaders;
if (!Material.TryGetShaders(ShaderTypes, VertexFactoryType, Shaders))
{
return false;
}
Shaders.TryGetVertexShader(VertexShader);
Shaders.TryGetPixelShader(PixelShader);
return true;
}
template <>
bool GetBasePassShaders<FUniformLightMapPolicy>(
const FMaterial& Material,
const FVertexFactoryType* VertexFactoryType,
FUniformLightMapPolicy LightMapPolicy,
ERHIFeatureLevel::Type FeatureLevel,
bool bEnableSkyLight,
bool bIsDebug,
bool bUse128bitRT,
EGBufferLayout GBufferLayout,
TShaderRef<TBasePassVertexShaderPolicyParamType<FUniformLightMapPolicy>>* VertexShader,
TShaderRef<TBasePassPixelShaderPolicyParamType<FUniformLightMapPolicy>>* PixelShader,
bool bIsForOITPass
);
class FBasePassMeshProcessor : public FSceneRenderingAllocatorObject<FBasePassMeshProcessor>, public FMeshPassProcessor
{
public:
enum class EFlags
{
None = 0,
// Informs the processor whether a depth-stencil target is bound when processed draw commands are issued.
CanUseDepthStencil = (1 << 0),
bRequires128bitRT = (1 << 1)
};
FBasePassMeshProcessor(
EMeshPass::Type InMeshPassType,
const FScene* InScene,
ERHIFeatureLevel::Type InFeatureLevel,
const FSceneView* InViewIfDynamicMeshCommand,
const FMeshPassProcessorRenderState& InDrawRenderState,
FMeshPassDrawListContext* InDrawListContext,
EFlags Flags,
ETranslucencyPass::Type InTranslucencyPassType = ETranslucencyPass::TPT_MAX);
virtual void AddMeshBatch(const FMeshBatch& RESTRICT MeshBatch, uint64 BatchElementMask, const FPrimitiveSceneProxy* RESTRICT PrimitiveSceneProxy, int32 StaticMeshId = -1) override final;
virtual void CollectPSOInitializers(const FSceneTexturesConfig& SceneTexturesConfig, const FMaterial& Material, const FPSOPrecacheVertexFactoryData& VertexFactoryData, const FPSOPrecacheParams& PreCacheParams, TArray<FPSOPrecacheData>& PSOInitializers) override final;
FMeshPassProcessorRenderState PassDrawRenderState;
FORCEINLINE_DEBUGGABLE void Set128BitRequirement(const bool Required)
{
bRequiresExplicit128bitRT = Required;
}
FORCEINLINE_DEBUGGABLE bool Get128BitRequirement() const
{
return bRequiresExplicit128bitRT;
}
static ELightMapPolicyType GetUniformLightMapPolicyType(ERHIFeatureLevel::Type FeatureLevelconst, const FScene* Scene, const FLightCacheInterface* LCI, const FPrimitiveSceneProxy* RESTRICT PrimitiveSceneProxy, const FMaterial& Material);
static TArray<ELightMapPolicyType, TInlineAllocator<2>> GetUniformLightMapPolicyTypeForPSOCollection(ERHIFeatureLevel::Type FeatureLevel, const FMaterial& Material);
template<typename PassShadersType>
static void AddBasePassGraphicsPipelineStateInitializer(
ERHIFeatureLevel::Type InFeatureLevel,
const FPSOPrecacheVertexFactoryData& VertexFactoryData,
const FMaterial& RESTRICT MaterialResource,
const FMeshPassProcessorRenderState& RESTRICT DrawRenderState,
const FGraphicsPipelineRenderTargetsInfo& RESTRICT RenderTargetsInfo,
const PassShadersType& PassShaders,
ERasterizerFillMode MeshFillMode,
ERasterizerCullMode MeshCullMode,
EPrimitiveType PrimitiveType,
bool bPrecacheAlphaColorChannel,
int InPSOCollectorIndex,
TArray<FPSOPrecacheData>& PSOInitializers)
{
AddGraphicsPipelineStateInitializer(
VertexFactoryData,
MaterialResource,
DrawRenderState,
RenderTargetsInfo,
PassShaders,
MeshFillMode,
MeshCullMode,
PrimitiveType,
EMeshPassFeatures::Default,
ESubpassHint::None,
0,
true /*bRequired*/,
InPSOCollectorIndex,
PSOInitializers);
// Planar reflections and scene captures use scene color alpha to keep track of where content has been rendered, for compositing into a different scene later
static TConsoleVariableData<int32>* CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.PSOPrecache.PrecacheAlphaColorChannel"));
if (bPrecacheAlphaColorChannel && CVar && CVar->GetValueOnAnyThread() > 0)
{
FGraphicsPipelineRenderTargetsInfo AlphaColorRenderTargetsInfo = RenderTargetsInfo;
bool bRequiresAlphaChannel = true;
ETextureCreateFlags ExtraSceneColorCreateFlags = ETextureCreateFlags::None;
EPixelFormat SceneColorFormatWithAlpha;
ETextureCreateFlags SceneColorCreateFlagsWithAlpha;
GetSceneColorFormatAndCreateFlags(InFeatureLevel, bRequiresAlphaChannel, ExtraSceneColorCreateFlags, RenderTargetsInfo.NumSamples, false, SceneColorFormatWithAlpha, SceneColorCreateFlagsWithAlpha);
AlphaColorRenderTargetsInfo.RenderTargetFormats[0] = SceneColorFormatWithAlpha;
AlphaColorRenderTargetsInfo.RenderTargetFlags[0] = SceneColorCreateFlagsWithAlpha;
AddGraphicsPipelineStateInitializer(
VertexFactoryData,
MaterialResource,
DrawRenderState,
AlphaColorRenderTargetsInfo,
PassShaders,
MeshFillMode,
MeshCullMode,
PrimitiveType,
EMeshPassFeatures::Default,
ESubpassHint::None,
0,
true,
InPSOCollectorIndex,
PSOInitializers);
}
}
private:
bool TryAddMeshBatch(const FMeshBatch& RESTRICT MeshBatch, uint64 BatchElementMask, const FPrimitiveSceneProxy* RESTRICT PrimitiveSceneProxy, int32 StaticMeshId, const FMaterialRenderProxy& MaterialRenderProxy, const FMaterial& Material);
bool ShouldDraw(const FMaterial& Material);
template<typename LightMapPolicyType>
bool Process(
const FMeshBatch& RESTRICT MeshBatch,
uint64 BatchElementMask,
int32 StaticMeshId,
const FPrimitiveSceneProxy* RESTRICT PrimitiveSceneProxy,
const FMaterialRenderProxy& RESTRICT MaterialRenderProxy,
const FMaterial& RESTRICT MaterialResource,
const bool bIsMasked,
const bool bIsTranslucent,
FMaterialShadingModelField ShadingModels,
const LightMapPolicyType& RESTRICT LightMapPolicy,
const typename LightMapPolicyType::ElementDataType& RESTRICT LightMapElementData,
ERasterizerFillMode MeshFillMode,
ERasterizerCullMode MeshCullMode);
void CollectPSOInitializersForSkyLight(
const FSceneTexturesConfig& SceneTexturesConfig,
const FPSOPrecacheVertexFactoryData& VertexFactoryData,
const FPSOPrecacheParams& PreCacheParams,
const FMaterial& RESTRICT MaterialResource,
const bool bRenderSkylight,
const bool bDitheredLODTransition,
ERasterizerFillMode MeshFillMode,
ERasterizerCullMode MeshCullMode,
EPrimitiveType PrimitiveType,
TArray<FPSOPrecacheData>& PSOInitializers);
template<typename LightMapPolicyType>
void CollectPSOInitializersForLMPolicy(
const FSceneTexturesConfig& SceneTexturesConfig,
const FPSOPrecacheVertexFactoryData& VertexFactoryData,
const FPSOPrecacheParams& PreCacheParams,
const FMaterial& RESTRICT MaterialResource,
FMaterialShadingModelField ShadingModels,
const bool bRenderSkylight,
const bool bDitheredLODTransition,
const LightMapPolicyType& RESTRICT LightMapPolicy,
ERasterizerFillMode MeshFillMode,
ERasterizerCullMode MeshCullMode,
EPrimitiveType PrimitiveType,
TArray<FPSOPrecacheData>& PSOInitializers);
const bool bIsDebug;
const ETranslucencyPass::Type TranslucencyPassType;
const bool bTranslucentBasePass;
const bool bOITBasePass;
const bool bEnableReceiveDecalOutput;
EDepthDrawingMode EarlyZPassMode;
bool bRequiresExplicit128bitRT;
float AutoBeforeDOFTranslucencyBoundary = 0.0f;
};
ENUM_CLASS_FLAGS(FBasePassMeshProcessor::EFlags);
extern void SetupBasePassState(FExclusiveDepthStencil::Type BasePassDepthStencilAccess, const bool bShaderComplexity, FMeshPassProcessorRenderState& DrawRenderState);
extern FMeshDrawCommandSortKey CalculateTranslucentMeshStaticSortKey(const FPrimitiveSceneProxy* RESTRICT PrimitiveSceneProxy, uint16 MeshIdInPrimitive);
struct FNaniteBasePassData
{
TShaderRef<TBasePassComputeShaderPolicyParamType<FUniformLightMapPolicy>> TypedShader;
};