2020-09-24 00:43:27 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "MobileDeferredShadingPass.h"
# include "SceneView.h"
# include "ScenePrivate.h"
# include "PostProcess/PostProcessing.h"
# include "PostProcess/SceneFilterRendering.h"
# include "PipelineStateCache.h"
2021-03-09 00:23:43 -04:00
# include "PlanarReflectionRendering.h"
2022-04-18 09:09:40 -04:00
# include "LocalLightSceneProxy.h"
2020-09-24 00:43:27 -04:00
int32 GMobileUseClusteredDeferredShading = 0 ;
static FAutoConsoleVariableRef CVarMobileUseClusteredDeferredShading (
TEXT ( " r.Mobile.UseClusteredDeferredShading " ) ,
GMobileUseClusteredDeferredShading ,
TEXT ( " Toggle use of clustered deferred shading for lights that support it. 0 is off (default), 1 is on " ) ,
ECVF_RenderThreadSafe
) ;
int32 GMobileUseLightStencilCulling = 1 ;
static FAutoConsoleVariableRef CVarMobileUseLightStencilCulling (
TEXT ( " r.Mobile.UseLightStencilCulling " ) ,
GMobileUseLightStencilCulling ,
TEXT ( " Whether to use stencil to cull local lights. 0 is off, 1 is on (default) " ) ,
ECVF_RenderThreadSafe
) ;
2020-12-04 12:07:09 -04:00
BEGIN_SHADER_PARAMETER_STRUCT ( FMobileDeferredPassParameters , )
SHADER_PARAMETER_RDG_UNIFORM_BUFFER ( FMobileSceneTextureUniformParameters , MobileSceneTextures )
RENDER_TARGET_BINDING_SLOTS ( )
END_SHADER_PARAMETER_STRUCT ( )
2022-04-13 01:56:42 -04:00
class FMobileDirectionalLightFunctionPS : public FMaterialShader
2020-09-24 00:43:27 -04:00
{
2022-04-13 01:56:42 -04:00
DECLARE_SHADER_TYPE ( FMobileDirectionalLightFunctionPS , Material ) ;
SHADER_USE_PARAMETER_STRUCT_WITH_LEGACY_BASE ( FMobileDirectionalLightFunctionPS , FMaterialShader )
2020-09-24 00:43:27 -04:00
2022-04-22 01:15:27 -04:00
class FEnableShadingModelSupport : SHADER_PERMUTATION_BOOL ( " ENABLE_SHADINGMODEL_SUPPORT_MOBILE_DEFERRED " ) ;
class FEnableClustredLights : SHADER_PERMUTATION_BOOL ( " ENABLE_CLUSTERED_LIGHTS " ) ;
class FEnableClustredReflection : SHADER_PERMUTATION_BOOL ( " ENABLE_CLUSTERED_REFLECTION " ) ;
2022-05-12 00:00:22 -04:00
class FEnablePlanarReflection : SHADER_PERMUTATION_BOOL ( " ENABLE_PLANAR_REFLECTION " ) ;
2022-04-22 01:15:27 -04:00
class FEnableSkyLight : SHADER_PERMUTATION_BOOL ( " ENABLE_SKY_LIGHT " ) ;
2022-05-12 00:00:22 -04:00
class FEnableCSM : SHADER_PERMUTATION_BOOL ( " ENABLE_MOBILE_CSM " ) ;
class FShadowQuality : SHADER_PERMUTATION_RANGE_INT ( " MOBILE_SHADOW_QUALITY " , 1 , 3 ) ; // not using Quality=0
2022-04-13 01:56:42 -04:00
2022-04-22 01:15:27 -04:00
using FPermutationDomain = TShaderPermutationDomain <
FEnableShadingModelSupport ,
2022-04-13 01:56:42 -04:00
FEnableClustredLights ,
FEnableClustredReflection ,
2022-05-12 00:00:22 -04:00
FEnablePlanarReflection ,
2022-04-13 01:56:42 -04:00
FEnableSkyLight ,
2022-05-12 00:00:22 -04:00
FEnableCSM ,
2022-04-13 01:56:42 -04:00
FShadowQuality > ;
2020-09-24 00:43:27 -04:00
BEGIN_SHADER_PARAMETER_STRUCT ( FParameters , )
SHADER_PARAMETER_STRUCT_REF ( FMobileDirectionalLightShaderParameters , MobileDirectionalLight )
2022-04-28 06:34:43 -04:00
SHADER_PARAMETER_STRUCT_REF ( FMobileReflectionCaptureShaderData , MobileReflectionCaptureData )
2022-01-26 13:56:31 -05:00
SHADER_PARAMETER ( FMatrix44f , TranslatedWorldToLight )
2021-09-22 10:01:48 -04:00
SHADER_PARAMETER ( FVector4f , LightFunctionParameters )
2021-05-05 15:07:25 -04:00
SHADER_PARAMETER ( FVector3f , LightFunctionParameters2 )
2021-08-09 06:21:58 -04:00
SHADER_PARAMETER_TEXTURE ( Texture2D , ScreenSpaceShadowMaskTexture )
SHADER_PARAMETER_SAMPLER ( SamplerState , ScreenSpaceShadowMaskSampler )
2020-09-24 00:43:27 -04:00
END_SHADER_PARAMETER_STRUCT ( )
2020-12-11 14:21:20 -04:00
static void ModifyCompilationEnvironment ( const FMaterialShaderPermutationParameters & Parameters , FShaderCompilerEnvironment & OutEnvironment )
2020-09-24 00:43:27 -04:00
{
2020-12-11 14:21:20 -04:00
FMaterialShader : : ModifyCompilationEnvironment ( Parameters , OutEnvironment ) ;
2020-09-24 00:43:27 -04:00
FForwardLightingParameters : : ModifyCompilationEnvironment ( Parameters . Platform , OutEnvironment ) ;
OutEnvironment . SetDefine ( TEXT ( PREPROCESSOR_TO_STRING ( MAX_MOBILE_SHADOWCASCADES ) ) , GetMobileMaxShadowCascades ( ) ) ;
2020-12-11 14:21:20 -04:00
OutEnvironment . SetDefine ( TEXT ( " USE_LIGHT_FUNCTION " ) , Parameters . MaterialParameters . bIsDefaultMaterial ? 0 : 1 ) ;
2022-04-18 09:09:40 -04:00
OutEnvironment . SetDefine ( TEXT ( " USE_SHADOWMASKTEXTURE " ) , MobileUsesShadowMaskTexture ( Parameters . Platform ) ? 1u : 0u ) ;
2022-04-13 01:56:42 -04:00
OutEnvironment . SetDefine ( TEXT ( " MATERIAL_SHADER " ) , 1 ) ;
2020-09-24 00:43:27 -04:00
}
2022-04-18 09:09:40 -04:00
static FPermutationDomain RemapPermutationVector ( FPermutationDomain PermutationVector , EShaderPlatform Platform )
2020-09-24 00:43:27 -04:00
{
2022-04-18 09:09:40 -04:00
if ( MobileUsesShadowMaskTexture ( Platform ) )
{
2022-05-12 00:00:22 -04:00
PermutationVector . Set < FEnableCSM > ( false ) ;
2022-04-18 09:09:40 -04:00
}
2022-05-12 00:00:22 -04:00
if ( PermutationVector . Get < FEnableCSM > ( ) = = false )
2020-09-24 00:43:27 -04:00
{
2022-05-12 00:00:22 -04:00
PermutationVector . Set < FShadowQuality > ( 1 ) ;
2020-09-24 00:43:27 -04:00
}
2022-04-22 01:15:27 -04:00
2022-05-11 03:17:42 -04:00
if ( ! MobileUsesGBufferCustomData ( Platform ) )
2022-04-22 01:15:27 -04:00
{
PermutationVector . Set < FEnableShadingModelSupport > ( false ) ;
}
2020-09-24 00:43:27 -04:00
return PermutationVector ;
}
2020-12-11 14:21:20 -04:00
static bool ShouldCompilePermutation ( const FMaterialShaderPermutationParameters & Parameters )
2020-09-24 00:43:27 -04:00
{
2020-12-11 14:21:20 -04:00
if ( Parameters . MaterialParameters . MaterialDomain ! = MD_LightFunction | |
! IsMobilePlatform ( Parameters . Platform ) | |
! IsMobileDeferredShadingEnabled ( Parameters . Platform ) )
2020-09-24 00:43:27 -04:00
{
return false ;
}
FPermutationDomain PermutationVector ( Parameters . PermutationId ) ;
// Compile out the shader if this permutation gets remapped.
2022-04-18 09:09:40 -04:00
if ( RemapPermutationVector ( PermutationVector , Parameters . Platform ) ! = PermutationVector )
2020-09-24 00:43:27 -04:00
{
return false ;
}
return true ;
}
2022-05-12 00:00:22 -04:00
static FPermutationDomain BuildPermutationVector ( const FViewInfo & View , bool bInlineReflectionAndSky , bool bShadingModelSupport , bool bDynamicShadows , bool bSkyLight , bool bPlanarReflection )
2020-09-24 00:43:27 -04:00
{
2022-04-13 01:56:42 -04:00
bool bUseClusteredLights = GMobileUseClusteredDeferredShading ! = 0 ;
bool bClustredReflection = bInlineReflectionAndSky & & ( View . NumBoxReflectionCaptures + View . NumSphereReflectionCaptures ) > 0 ;
bool bEnableSkyLight = bInlineReflectionAndSky & & bSkyLight ;
2022-04-18 09:09:40 -04:00
const bool bMobileUsesShadowMaskTexture = MobileUsesShadowMaskTexture ( View . GetShaderPlatform ( ) ) ;
int32 ShadowQuality = bDynamicShadows & & ! bMobileUsesShadowMaskTexture ? ( int32 ) GetShadowQuality ( ) : 0 ;
2022-04-13 01:56:42 -04:00
2020-09-24 00:43:27 -04:00
FPermutationDomain PermutationVector ;
2022-04-22 01:15:27 -04:00
PermutationVector . Set < FMobileDirectionalLightFunctionPS : : FEnableShadingModelSupport > ( bShadingModelSupport ) ;
2022-04-13 01:56:42 -04:00
PermutationVector . Set < FMobileDirectionalLightFunctionPS : : FEnableClustredLights > ( bUseClusteredLights ) ;
PermutationVector . Set < FMobileDirectionalLightFunctionPS : : FEnableClustredReflection > ( bClustredReflection ) ;
2022-05-12 00:00:22 -04:00
PermutationVector . Set < FMobileDirectionalLightFunctionPS : : FEnablePlanarReflection > ( bPlanarReflection ) ;
2022-04-13 01:56:42 -04:00
PermutationVector . Set < FMobileDirectionalLightFunctionPS : : FEnableSkyLight > ( bEnableSkyLight ) ;
2022-05-12 00:00:22 -04:00
PermutationVector . Set < FMobileDirectionalLightFunctionPS : : FEnableCSM > ( ShadowQuality > 0 ) ;
PermutationVector . Set < FMobileDirectionalLightFunctionPS : : FShadowQuality > ( FMath : : Clamp ( ShadowQuality , 1 , 3 ) ) ;
2020-09-24 00:43:27 -04:00
return PermutationVector ;
}
2020-12-11 14:21:20 -04:00
2022-04-13 01:56:42 -04:00
static void SetParameters ( FRHICommandList & RHICmdList , const TShaderRef < FMobileDirectionalLightFunctionPS > & Shader , const FViewInfo & View , const FMaterialRenderProxy * Proxy , const FMaterial & Material , const FParameters & Parameters )
2020-12-11 14:21:20 -04:00
{
FMaterialShader * MaterialShader = Shader . GetShader ( ) ;
FRHIPixelShader * ShaderRHI = Shader . GetPixelShader ( ) ;
MaterialShader - > SetParameters ( RHICmdList , ShaderRHI , Proxy , Material , View ) ;
SetShaderParameters ( RHICmdList , Shader , ShaderRHI , Parameters ) ;
}
2020-09-24 00:43:27 -04:00
} ;
2022-04-13 01:56:42 -04:00
IMPLEMENT_MATERIAL_SHADER_TYPE ( , FMobileDirectionalLightFunctionPS , TEXT ( " /Engine/Private/MobileDeferredShading.usf " ) , TEXT ( " MobileDirectionalLightPS " ) , SF_Pixel ) ;
2020-09-24 00:43:27 -04:00
2020-12-11 14:21:20 -04:00
/**
* A pixel shader for projecting a light function onto the scene .
*/
class FMobileRadialLightFunctionPS : public FMaterialShader
2020-09-24 00:43:27 -04:00
{
2020-12-11 14:21:20 -04:00
public :
DECLARE_SHADER_TYPE ( FMobileRadialLightFunctionPS , Material ) ;
SHADER_USE_PARAMETER_STRUCT_WITH_LEGACY_BASE ( FMobileRadialLightFunctionPS , FMaterialShader )
2020-09-24 00:43:27 -04:00
2022-04-22 01:15:27 -04:00
class FEnableShadingModelSupport : SHADER_PERMUTATION_BOOL ( " ENABLE_SHADINGMODEL_SUPPORT_MOBILE_DEFERRED " ) ;
class FSpotLightDim : SHADER_PERMUTATION_BOOL ( " IS_SPOT_LIGHT " ) ;
class FIESProfileDim : SHADER_PERMUTATION_BOOL ( " USE_IES_PROFILE " ) ;
class FSpotLightShadowDim : SHADER_PERMUTATION_BOOL ( " SUPPORT_SPOTLIGHTS_SHADOW " ) ;
using FPermutationDomain = TShaderPermutationDomain < FEnableShadingModelSupport , FSpotLightDim , FIESProfileDim , FSpotLightShadowDim > ;
2020-09-24 00:43:27 -04:00
BEGIN_SHADER_PARAMETER_STRUCT ( FParameters , )
2022-01-26 13:56:31 -05:00
SHADER_PARAMETER ( FMatrix44f , TranslatedWorldToLight )
2021-09-22 10:01:48 -04:00
SHADER_PARAMETER ( FVector4f , LightFunctionParameters )
2021-05-05 15:07:25 -04:00
SHADER_PARAMETER ( FVector3f , LightFunctionParameters2 )
2020-09-24 00:43:27 -04:00
SHADER_PARAMETER_STRUCT_REF ( FDeferredLightUniformStruct , DeferredLightUniforms )
2022-04-18 09:09:40 -04:00
SHADER_PARAMETER_STRUCT_INCLUDE ( FMobileMovableLocalLightShadowParameters , MobileMovableLocalLightShadow )
2020-11-24 18:42:39 -04:00
SHADER_PARAMETER_TEXTURE ( Texture2D , IESTexture )
SHADER_PARAMETER_SAMPLER ( SamplerState , IESTextureSampler )
2020-09-24 00:43:27 -04:00
END_SHADER_PARAMETER_STRUCT ( )
2020-12-11 14:21:20 -04:00
static bool ShouldCompilePermutation ( const FMaterialShaderPermutationParameters & Parameters )
2020-09-24 00:43:27 -04:00
{
2020-12-11 14:21:20 -04:00
if ( Parameters . MaterialParameters . MaterialDomain ! = MD_LightFunction | |
! IsMobilePlatform ( Parameters . Platform ) | |
! IsMobileDeferredShadingEnabled ( Parameters . Platform ) )
{
return false ;
}
2022-04-18 09:09:40 -04:00
FPermutationDomain PermutationVector ( Parameters . PermutationId ) ;
// Compile out the shader if this permutation gets remapped.
if ( RemapPermutationVector ( PermutationVector , Parameters . Platform ) ! = PermutationVector )
{
return false ;
}
2020-12-11 14:21:20 -04:00
return true ;
2020-09-24 00:43:27 -04:00
}
2022-04-18 09:09:40 -04:00
static FPermutationDomain RemapPermutationVector ( FPermutationDomain PermutationVector , EShaderPlatform Platform )
{
if ( ! IsMobileMovableSpotlightShadowsEnabled ( Platform ) )
{
PermutationVector . Set < FSpotLightShadowDim > ( false ) ;
}
2022-05-11 03:17:42 -04:00
if ( ! MobileUsesGBufferCustomData ( Platform ) )
2022-04-22 01:15:27 -04:00
{
PermutationVector . Set < FEnableShadingModelSupport > ( false ) ;
}
2022-04-18 09:09:40 -04:00
return PermutationVector ;
}
2020-12-11 14:21:20 -04:00
static void ModifyCompilationEnvironment ( const FMaterialShaderPermutationParameters & Parameters , FShaderCompilerEnvironment & OutEnvironment )
2020-09-24 00:43:27 -04:00
{
2020-12-11 14:21:20 -04:00
FMaterialShader : : ModifyCompilationEnvironment ( Parameters , OutEnvironment ) ;
OutEnvironment . SetDefine ( TEXT ( " USE_LIGHT_FUNCTION " ) , Parameters . MaterialParameters . bIsDefaultMaterial ? 0 : 1 ) ;
2022-04-13 01:56:42 -04:00
OutEnvironment . SetDefine ( TEXT ( " MATERIAL_SHADER " ) , 1 ) ;
2022-04-18 09:09:40 -04:00
OutEnvironment . SetDefine ( TEXT ( " USE_SHADOWMASKTEXTURE " ) , 0 ) ;
OutEnvironment . SetDefine ( TEXT ( " ENABLE_CLUSTERED_LIGHTS " ) , 0 ) ;
2020-12-11 14:21:20 -04:00
}
static void SetParameters ( FRHICommandList & RHICmdList , const TShaderRef < FMobileRadialLightFunctionPS > & Shader , const FViewInfo & View , const FMaterialRenderProxy * Proxy , const FMaterial & Material , const FParameters & Parameters )
{
FMaterialShader * MaterialShader = Shader . GetShader ( ) ;
FRHIPixelShader * ShaderRHI = Shader . GetPixelShader ( ) ;
MaterialShader - > SetViewParameters ( RHICmdList , ShaderRHI , View , View . ViewUniformBuffer ) ;
MaterialShader - > SetParameters ( RHICmdList , ShaderRHI , Proxy , Material , View ) ;
SetShaderParameters ( RHICmdList , Shader , ShaderRHI , Parameters ) ;
2020-09-24 00:43:27 -04:00
}
} ;
2020-12-11 14:21:20 -04:00
IMPLEMENT_MATERIAL_SHADER_TYPE ( , FMobileRadialLightFunctionPS , TEXT ( " /Engine/Private/MobileDeferredShading.usf " ) , TEXT ( " MobileRadialLightPS " ) , SF_Pixel ) ;
2020-09-24 00:43:27 -04:00
2022-04-13 01:56:42 -04:00
/**
* A pixel shader for reflection env and sky lighting .
*/
class FMobileReflectionEnvironmentSkyLightingPS : public FGlobalShader
{
public :
DECLARE_GLOBAL_SHADER ( FMobileReflectionEnvironmentSkyLightingPS ) ;
SHADER_USE_PARAMETER_STRUCT ( FMobileReflectionEnvironmentSkyLightingPS , FGlobalShader ) ;
2022-04-22 01:15:27 -04:00
class FEnableShadingModelSupport : SHADER_PERMUTATION_BOOL ( " ENABLE_SHADINGMODEL_SUPPORT_MOBILE_DEFERRED " ) ;
class FEnableClustredReflection : SHADER_PERMUTATION_BOOL ( " ENABLE_CLUSTERED_REFLECTION " ) ;
2022-05-12 00:00:22 -04:00
class FEnablePlanarReflection : SHADER_PERMUTATION_BOOL ( " ENABLE_PLANAR_REFLECTION " ) ;
2022-04-22 01:15:27 -04:00
class FEnableSkyLight : SHADER_PERMUTATION_BOOL ( " ENABLE_SKY_LIGHT " ) ;
2022-05-12 00:00:22 -04:00
using FPermutationDomain = TShaderPermutationDomain <
FEnableShadingModelSupport ,
FEnableClustredReflection ,
FEnablePlanarReflection ,
FEnableSkyLight
> ;
2022-04-13 01:56:42 -04:00
BEGIN_SHADER_PARAMETER_STRUCT ( FParameters , )
SHADER_PARAMETER_STRUCT_REF ( FViewUniformShaderParameters , View )
2022-04-28 06:34:43 -04:00
SHADER_PARAMETER_STRUCT_REF ( FMobileReflectionCaptureShaderData , MobileReflectionCaptureData )
2022-04-13 01:56:42 -04:00
END_SHADER_PARAMETER_STRUCT ( )
static bool ShouldCompilePermutation ( const FGlobalShaderPermutationParameters & Parameters )
{
if ( ! IsMobilePlatform ( Parameters . Platform ) | |
! IsMobileDeferredShadingEnabled ( Parameters . Platform ) )
{
return false ;
}
2022-04-22 01:15:27 -04:00
FPermutationDomain PermutationVector ( Parameters . PermutationId ) ;
2022-05-11 03:17:42 -04:00
if ( ! MobileUsesGBufferCustomData ( Parameters . Platform ) & & PermutationVector . Get < FEnableShadingModelSupport > ( ) )
2022-04-22 01:15:27 -04:00
{
return false ;
}
2022-04-13 01:56:42 -04:00
return true ;
}
2022-04-22 01:15:27 -04:00
static void ModifyCompilationEnvironment ( const FGlobalShaderPermutationParameters & Parameters , FShaderCompilerEnvironment & OutEnvironment )
{
FGlobalShader : : ModifyCompilationEnvironment ( Parameters , OutEnvironment ) ;
}
2022-04-13 01:56:42 -04:00
} ;
IMPLEMENT_GLOBAL_SHADER ( FMobileReflectionEnvironmentSkyLightingPS , " /Engine/Private/MobileDeferredShading.usf " , " MobileReflectionEnvironmentSkyLightingPS " , SF_Pixel ) ;
2022-04-22 01:15:27 -04:00
extern uint8 GetMobileShadingModelStencilValue ( FMaterialShadingModelField ShadingModel ) ;
2022-04-13 01:56:42 -04:00
constexpr uint32 GetLightingChannel ( uint32 LightingChannelMask )
{
return ( LightingChannelMask & 0x1 ) ? 0u : ( ( LightingChannelMask & 0x2 ) ? 1u : 2u ) ;
}
constexpr uint8 GetLightingChannelStencilValue ( uint32 LightingChannel )
{
// LightingChannel_0 has an inverted bit in the stencil. 0 - means LightingChannel_0 is enabled. See FPrimitiveSceneProxy::GetLightingChannelStencilValue()
return ( LightingChannel = = 0u ? 0u : ( 1u < < LightingChannel ) ) ;
}
2020-12-11 14:21:20 -04:00
struct FCachedLightMaterial
{
const FMaterial * Material ;
const FMaterialRenderProxy * MaterialProxy ;
} ;
template < class ShaderType >
static void GetLightMaterial ( const FCachedLightMaterial & DefaultLightMaterial , const FMaterialRenderProxy * MaterialProxy , int32 PermutationId , FCachedLightMaterial & OutLightMaterial , TShaderRef < ShaderType > & OutShader )
{
FMaterialShaderTypes ShaderTypes ;
ShaderTypes . AddShaderType < ShaderType > ( PermutationId ) ;
FMaterialShaders Shaders ;
if ( MaterialProxy )
{
const FMaterial * Material = MaterialProxy - > GetMaterialNoFallback ( ERHIFeatureLevel : : ES3_1 ) ;
if ( Material & & Material - > IsLightFunction ( ) )
{
OutLightMaterial . Material = Material ;
OutLightMaterial . MaterialProxy = MaterialProxy ;
if ( Material - > TryGetShaders ( ShaderTypes , nullptr , Shaders ) )
{
Shaders . TryGetPixelShader ( OutShader ) ;
return ;
}
}
}
// use default material
OutLightMaterial . Material = DefaultLightMaterial . Material ;
OutLightMaterial . MaterialProxy = DefaultLightMaterial . MaterialProxy ;
const FMaterialShaderMap * MaterialShaderMap = OutLightMaterial . Material - > GetRenderingThreadShaderMap ( ) ;
OutShader = MaterialShaderMap - > GetShader < ShaderType > ( PermutationId ) ;
}
2022-04-13 01:56:42 -04:00
void RenderReflectionEnvironmentSkyLighting ( FRHICommandListImmediate & RHICmdList , const FScene & Scene , const FViewInfo & View )
2020-09-24 00:43:27 -04:00
{
2022-04-13 01:56:42 -04:00
// Skylights with static lighting already had their diffuse contribution baked into lightmaps
const bool bSkyLight = Scene . SkyLight & & ! Scene . SkyLight - > bHasStaticLighting & & View . Family - > EngineShowFlags . SkyLighting ;
const bool bClustredReflection = ( View . NumBoxReflectionCaptures + View . NumSphereReflectionCaptures ) > 0 ;
2022-05-12 00:00:22 -04:00
const bool bPlanarReflection = Scene . GetForwardPassGlobalPlanarReflection ( ) ! = nullptr ;
if ( ! ( bSkyLight | | bClustredReflection | | bPlanarReflection ) )
2020-12-11 14:21:20 -04:00
{
2022-04-13 01:56:42 -04:00
return ;
2020-12-11 14:21:20 -04:00
}
2022-04-13 01:56:42 -04:00
SCOPED_DRAW_EVENT ( RHICmdList , ReflectionEnvironmentSkyLighting ) ;
2020-12-11 14:21:20 -04:00
2022-04-13 01:56:42 -04:00
FGraphicsPipelineStateInitializer GraphicsPSOInit ;
RHICmdList . ApplyCachedRenderTargets ( GraphicsPSOInit ) ;
// Add to emissive in SceneColor
GraphicsPSOInit . BlendState = TStaticBlendState < CW_RGB , BO_Add , BF_One , BF_One > : : GetRHI ( ) ;
GraphicsPSOInit . RasterizerState = TStaticRasterizerState < > : : GetRHI ( ) ;
GraphicsPSOInit . DepthStencilState = TStaticDepthStencilState <
false , CF_Always ,
true , CF_Equal , SO_Keep , SO_Keep , SO_Keep ,
false , CF_Always , SO_Keep , SO_Keep , SO_Keep ,
GET_STENCIL_MOBILE_SM_MASK ( 0xff ) , 0x00 > : : GetRHI ( ) ;
FMobileReflectionEnvironmentSkyLightingPS : : FParameters PassParameters ;
PassParameters . View = GetShaderBinding ( View . ViewUniformBuffer ) ;
2022-04-28 06:34:43 -04:00
PassParameters . MobileReflectionCaptureData = GetShaderBinding ( View . MobileReflectionCaptureUniformBuffer ) ;
2022-04-13 01:56:42 -04:00
2022-04-22 01:15:27 -04:00
TShaderMapRef < FPostProcessVS > VertexShader ( View . ShaderMap ) ;
// Do two passes, first masking DefautLit, second masking all other shading models
2022-05-11 03:17:42 -04:00
int32 NumPasses = MobileUsesGBufferCustomData ( Scene . GetShaderPlatform ( ) ) ? 2 : 1 ;
2022-04-22 01:15:27 -04:00
uint8 PassShadingModelStencilValue [ 2 ] =
{
GetMobileShadingModelStencilValue ( MSM_DefaultLit ) ,
GetMobileShadingModelStencilValue ( FMaterialShadingModelField ( ) )
} ;
for ( int32 PassIndex = 0 ; PassIndex < NumPasses ; PassIndex + + )
{
const bool bEnableShadingModelSupport = ( PassIndex > 0 ) ;
FMobileReflectionEnvironmentSkyLightingPS : : FPermutationDomain PermutationVector ;
PermutationVector . Set < FMobileReflectionEnvironmentSkyLightingPS : : FEnableShadingModelSupport > ( bEnableShadingModelSupport ) ;
PermutationVector . Set < FMobileReflectionEnvironmentSkyLightingPS : : FEnableClustredReflection > ( bClustredReflection ) ;
2022-05-12 00:00:22 -04:00
PermutationVector . Set < FMobileReflectionEnvironmentSkyLightingPS : : FEnablePlanarReflection > ( bPlanarReflection ) ;
2022-04-22 01:15:27 -04:00
PermutationVector . Set < FMobileReflectionEnvironmentSkyLightingPS : : FEnableSkyLight > ( bSkyLight ) ;
TShaderMapRef < FMobileReflectionEnvironmentSkyLightingPS > PixelShader ( View . ShaderMap , PermutationVector ) ;
GraphicsPSOInit . BoundShaderState . VertexDeclarationRHI = GFilterVertexDeclaration . VertexDeclarationRHI ;
GraphicsPSOInit . BoundShaderState . VertexShaderRHI = VertexShader . GetVertexShader ( ) ;
GraphicsPSOInit . BoundShaderState . PixelShaderRHI = PixelShader . GetPixelShader ( ) ;
GraphicsPSOInit . PrimitiveType = PT_TriangleList ;
uint8 StencilRef = GET_STENCIL_MOBILE_SM_MASK ( PassShadingModelStencilValue [ PassIndex ] ) ;
SetGraphicsPipelineState ( RHICmdList , GraphicsPSOInit , StencilRef ) ;
SetShaderParameters ( RHICmdList , PixelShader , PixelShader . GetPixelShader ( ) , PassParameters ) ;
UE5_MAIN: Multi-view-family scene renderer refactor, part 2. Move FSceneTextures singleton out of RDG blackboard and FSceneTexturesConfig global variable singleton, into FViewFamilyInfo. This is necessary to allow multiple view families to render in a single render graph and a single scene renderer call.
* Existing calls to CreateSceneTextureShaderParameters and similar functions use "GetSceneTexturesChecked", which allows for the possibility that they are reached in a code path where scene textures haven't been initialized, and nullptr is returned instead of asserting. The shader parameter setup functions then fill in dummy defaults for that case. The goal was to precisely match the original behavior, which queried the RDG blackboard, and gracefully handled null if scene textures weren't there. This definitely appears to occur in FNiagaraGpuComputeDispatch::ProcessPendingTicksFlush, which can be called with a dummy scene with no scene textures. In the future, I may change this so dummy defaults are filled in for FSceneTextures at construction time, so the structure is never in an uninitialized state, but I would like to set up a test case for the Niagara code path before doing that, and the checks aren't harmful in the meantime.
* I marked as deprecated global functions which query values from FSceneTexturesConfig, but they'll still work with the caveat that if you use multi-view-family rendering, the results will be indeterminate (whatever view family rendered last). There was only one case outside the scene renderer that accessed the globals (depth clear value), which I removed, noting that there is nowhere in the code where we modify the depth clear value from its global default. I would like to permanently deprecate or remove these at some point. Display Cluster is the only code that's currently using the multi-view-family code path, and as a new (still incomplete) feature, third party code can't be using it, and won't be affected.
#jira NONE
#rb chris.kulla zach.bethel mihnea.balta
#preflight 6261aca76119a1a496bd2644
[CL 19873983 by jason hoerner in ue5-main branch]
2022-04-22 17:33:02 -04:00
const FIntPoint TargetSize = View . GetSceneTexturesConfig ( ) . Extent ;
2022-04-22 01:15:27 -04:00
DrawRectangle (
RHICmdList ,
0 , 0 ,
View . ViewRect . Width ( ) , View . ViewRect . Height ( ) ,
View . ViewRect . Min . X , View . ViewRect . Min . Y ,
View . ViewRect . Width ( ) , View . ViewRect . Height ( ) ,
FIntPoint ( View . ViewRect . Width ( ) , View . ViewRect . Height ( ) ) ,
TargetSize ,
VertexShader ) ;
}
2022-04-13 01:56:42 -04:00
}
template < uint32 LightingChannelIdx >
static void SetDirectionalLightDepthStencilState ( FGraphicsPipelineStateInitializer & GraphicsPSOInit )
{
GraphicsPSOInit . DepthStencilState = TStaticDepthStencilState <
false , CF_Always ,
true , CF_Equal , SO_Keep , SO_Keep , SO_Keep ,
false , CF_Always , SO_Keep , SO_Keep , SO_Keep ,
GET_STENCIL_MOBILE_SM_MASK ( 0xff ) | STENCIL_LIGHTING_CHANNELS_MASK ( 1u < < LightingChannelIdx ) , 0x00 > : : GetRHI ( ) ;
}
static void RenderDirectionalLight ( FRHICommandListImmediate & RHICmdList , const FScene & Scene , const FViewInfo & View , const FCachedLightMaterial & DefaultLightMaterial , const FLightSceneInfo & DirectionalLight , uint32 LightingChannel , bool bInlineReflectionAndSky )
{
FString LightNameWithLevel ;
FSceneRenderer : : GetLightNameForDrawEvent ( DirectionalLight . Proxy , LightNameWithLevel ) ;
2022-02-02 09:54:34 -05:00
SCOPED_DRAW_EVENTF ( RHICmdList , DirectionalLight , TEXT ( " %s " ) , * LightNameWithLevel ) ;
2020-09-24 00:43:27 -04:00
FGraphicsPipelineStateInitializer GraphicsPSOInit ;
RHICmdList . ApplyCachedRenderTargets ( GraphicsPSOInit ) ;
// Add to emissive in SceneColor
GraphicsPSOInit . BlendState = TStaticBlendState < CW_RGB , BO_Add , BF_One , BF_One > : : GetRHI ( ) ;
GraphicsPSOInit . RasterizerState = TStaticRasterizerState < > : : GetRHI ( ) ;
2022-04-13 01:56:42 -04:00
uint8 LightingChannelStencilValue = GetLightingChannelStencilValue ( LightingChannel ) ;
if ( LightingChannel = = 1u )
{
SetDirectionalLightDepthStencilState < 1u > ( GraphicsPSOInit ) ;
}
else if ( LightingChannel = = 2u )
{
SetDirectionalLightDepthStencilState < 2u > ( GraphicsPSOInit ) ;
}
else
{
SetDirectionalLightDepthStencilState < 0u > ( GraphicsPSOInit ) ;
}
2020-09-24 00:43:27 -04:00
TShaderMapRef < FPostProcessVS > VertexShader ( View . ShaderMap ) ;
2020-12-11 14:21:20 -04:00
const FMaterialRenderProxy * LightFunctionMaterialProxy = nullptr ;
2022-04-13 01:56:42 -04:00
if ( View . Family - > EngineShowFlags . LightFunctions )
2020-12-11 14:21:20 -04:00
{
2022-04-13 01:56:42 -04:00
LightFunctionMaterialProxy = DirectionalLight . Proxy - > GetLightFunctionMaterial ( ) ;
2020-12-11 14:21:20 -04:00
}
2022-04-13 01:56:42 -04:00
FMobileDirectionalLightFunctionPS : : FParameters PassParameters ;
2022-04-22 01:15:27 -04:00
PassParameters . MobileDirectionalLight = Scene . UniformBuffers . MobileDirectionalLightUniformBuffers [ LightingChannel + 1 ] ;
2022-04-28 06:34:43 -04:00
PassParameters . MobileReflectionCaptureData = GetShaderBinding ( View . MobileReflectionCaptureUniformBuffer ) ;
2021-09-22 10:01:48 -04:00
PassParameters . LightFunctionParameters = FVector4f ( 1.0f , 1.0f , 0.0f , 0.0f ) ;
2021-06-19 10:07:01 -04:00
2022-04-18 09:09:40 -04:00
const bool bMobileUsesShadowMaskTexture = MobileUsesShadowMaskTexture ( View . GetShaderPlatform ( ) ) ;
if ( bMobileUsesShadowMaskTexture & & GScreenSpaceShadowMaskTextureMobileOutputs . ScreenSpaceShadowMaskTextureMobile . IsValid ( ) )
2021-08-09 06:21:58 -04:00
{
2022-04-06 18:24:24 -04:00
PassParameters . ScreenSpaceShadowMaskTexture = GScreenSpaceShadowMaskTextureMobileOutputs . ScreenSpaceShadowMaskTextureMobile - > GetRHI ( ) ;
2021-08-09 06:21:58 -04:00
PassParameters . ScreenSpaceShadowMaskSampler = TStaticSamplerState < SF_Point , AM_Clamp , AM_Clamp , AM_Clamp > : : GetRHI ( ) ;
}
else
{
2022-04-06 18:24:24 -04:00
PassParameters . ScreenSpaceShadowMaskTexture = GSystemTextures . WhiteDummy - > GetRHI ( ) ;
2021-08-09 06:21:58 -04:00
PassParameters . ScreenSpaceShadowMaskSampler = TStaticSamplerState < SF_Point , AM_Clamp , AM_Clamp , AM_Clamp > : : GetRHI ( ) ;
}
2022-04-22 01:15:27 -04:00
2021-04-08 14:32:07 -04:00
{
2022-04-13 01:56:42 -04:00
const bool bUseMovableLight = ! DirectionalLight . Proxy - > HasStaticShadowing ( ) ;
PassParameters . LightFunctionParameters2 = FVector3f ( DirectionalLight . Proxy - > GetLightFunctionFadeDistance ( ) , DirectionalLight . Proxy - > GetLightFunctionDisabledBrightness ( ) , bUseMovableLight ? 1.0f : 0.0f ) ;
const FVector Scale = DirectionalLight . Proxy - > GetLightFunctionScale ( ) ;
2021-04-08 14:32:07 -04:00
// Switch x and z so that z of the user specified scale affects the distance along the light direction
const FVector InverseScale = FVector ( 1.f / Scale . Z , 1.f / Scale . Y , 1.f / Scale . X ) ;
2022-04-13 01:56:42 -04:00
const FMatrix WorldToLight = DirectionalLight . Proxy - > GetWorldToLight ( ) * FScaleMatrix ( FVector ( InverseScale ) ) ;
2022-01-26 13:56:31 -05:00
PassParameters . TranslatedWorldToLight = FMatrix44f ( FTranslationMatrix ( - View . ViewMatrices . GetPreViewTranslation ( ) ) * WorldToLight ) ;
2021-04-08 14:32:07 -04:00
}
2022-04-22 01:15:27 -04:00
// Skylights with static lighting already had their diffuse contribution baked into lightmaps
const bool bSkyLight = Scene . SkyLight & & ! Scene . SkyLight - > bHasStaticLighting & & View . Family - > EngineShowFlags . SkyLighting ;
const bool bDynamicShadows = DirectionalLight . Proxy - > CastsDynamicShadow ( ) & & ( LightingChannel = = 0u ) & & View . Family - > EngineShowFlags . DynamicShadows ;
2022-05-12 00:00:22 -04:00
const bool bPlanarReflection = Scene . GetForwardPassGlobalPlanarReflection ( ) ! = nullptr ;
2022-04-22 01:15:27 -04:00
// Do two passes, first masking DefautLit, second masking all other shading models
2022-05-11 03:17:42 -04:00
int32 NumPasses = MobileUsesGBufferCustomData ( Scene . GetShaderPlatform ( ) ) ? 2 : 1 ;
2022-04-22 01:15:27 -04:00
uint8 PassShadingModelStencilValue [ 2 ] =
{
GetMobileShadingModelStencilValue ( MSM_DefaultLit ) ,
GetMobileShadingModelStencilValue ( FMaterialShadingModelField ( ) )
} ;
2020-12-11 14:21:20 -04:00
2022-04-22 01:15:27 -04:00
for ( int32 PassIndex = 0 ; PassIndex < NumPasses ; + + PassIndex )
{
const bool bEnableShadingModelSupport = ( PassIndex > 0 ) ;
FMobileDirectionalLightFunctionPS : : FPermutationDomain PermutationVector = FMobileDirectionalLightFunctionPS : : BuildPermutationVector (
View ,
bInlineReflectionAndSky ,
bEnableShadingModelSupport ,
bDynamicShadows ,
2022-05-12 00:00:22 -04:00
bSkyLight ,
bPlanarReflection
2022-04-22 01:15:27 -04:00
) ;
FCachedLightMaterial LightMaterial ;
TShaderRef < FMobileDirectionalLightFunctionPS > PixelShader ;
GetLightMaterial ( DefaultLightMaterial , LightFunctionMaterialProxy , PermutationVector . ToDimensionValueId ( ) , LightMaterial , PixelShader ) ;
uint8 StencilRef =
GET_STENCIL_MOBILE_SM_MASK ( PassShadingModelStencilValue [ PassIndex ] ) |
STENCIL_LIGHTING_CHANNELS_MASK ( LightingChannelStencilValue ) ;
GraphicsPSOInit . BoundShaderState . VertexDeclarationRHI = GFilterVertexDeclaration . VertexDeclarationRHI ;
GraphicsPSOInit . BoundShaderState . VertexShaderRHI = VertexShader . GetVertexShader ( ) ;
GraphicsPSOInit . BoundShaderState . PixelShaderRHI = PixelShader . GetPixelShader ( ) ;
GraphicsPSOInit . PrimitiveType = PT_TriangleList ;
SetGraphicsPipelineState ( RHICmdList , GraphicsPSOInit , StencilRef ) ;
FMobileDirectionalLightFunctionPS : : SetParameters ( RHICmdList , PixelShader , View , LightMaterial . MaterialProxy , * LightMaterial . Material , PassParameters ) ;
UE5_MAIN: Multi-view-family scene renderer refactor, part 2. Move FSceneTextures singleton out of RDG blackboard and FSceneTexturesConfig global variable singleton, into FViewFamilyInfo. This is necessary to allow multiple view families to render in a single render graph and a single scene renderer call.
* Existing calls to CreateSceneTextureShaderParameters and similar functions use "GetSceneTexturesChecked", which allows for the possibility that they are reached in a code path where scene textures haven't been initialized, and nullptr is returned instead of asserting. The shader parameter setup functions then fill in dummy defaults for that case. The goal was to precisely match the original behavior, which queried the RDG blackboard, and gracefully handled null if scene textures weren't there. This definitely appears to occur in FNiagaraGpuComputeDispatch::ProcessPendingTicksFlush, which can be called with a dummy scene with no scene textures. In the future, I may change this so dummy defaults are filled in for FSceneTextures at construction time, so the structure is never in an uninitialized state, but I would like to set up a test case for the Niagara code path before doing that, and the checks aren't harmful in the meantime.
* I marked as deprecated global functions which query values from FSceneTexturesConfig, but they'll still work with the caveat that if you use multi-view-family rendering, the results will be indeterminate (whatever view family rendered last). There was only one case outside the scene renderer that accessed the globals (depth clear value), which I removed, noting that there is nowhere in the code where we modify the depth clear value from its global default. I would like to permanently deprecate or remove these at some point. Display Cluster is the only code that's currently using the multi-view-family code path, and as a new (still incomplete) feature, third party code can't be using it, and won't be affected.
#jira NONE
#rb chris.kulla zach.bethel mihnea.balta
#preflight 6261aca76119a1a496bd2644
[CL 19873983 by jason hoerner in ue5-main branch]
2022-04-22 17:33:02 -04:00
const FIntPoint TargetSize = View . GetSceneTexturesConfig ( ) . Extent ;
2022-04-22 01:15:27 -04:00
DrawRectangle (
RHICmdList ,
0 , 0 ,
View . ViewRect . Width ( ) , View . ViewRect . Height ( ) ,
View . ViewRect . Min . X , View . ViewRect . Min . Y ,
View . ViewRect . Width ( ) , View . ViewRect . Height ( ) ,
FIntPoint ( View . ViewRect . Width ( ) , View . ViewRect . Height ( ) ) ,
TargetSize ,
VertexShader ) ;
}
2020-09-24 00:43:27 -04:00
}
2022-04-13 01:56:42 -04:00
static void RenderDirectionalLights ( FRHICommandListImmediate & RHICmdList , const FScene & Scene , const FViewInfo & View , const FCachedLightMaterial & DefaultLightMaterial )
2020-12-11 14:21:20 -04:00
{
2022-04-13 01:56:42 -04:00
uint32 NumLights = 0 ;
for ( uint32 ChannelIdx = 0 ; ChannelIdx < UE_ARRAY_COUNT ( Scene . MobileDirectionalLights ) ; ChannelIdx + + )
{
NumLights + = ( Scene . MobileDirectionalLights [ ChannelIdx ] ? 1 : 0 ) ;
}
// We can merge reflection and skylight pass with a sole directional light pass
const bool bInlineReflectionAndSky = ( NumLights = = 1 ) ;
for ( uint32 ChannelIdx = 0 ; ChannelIdx < UE_ARRAY_COUNT ( Scene . MobileDirectionalLights ) ; ChannelIdx + + )
{
FLightSceneInfo * DirectionalLight = Scene . MobileDirectionalLights [ ChannelIdx ] ;
if ( DirectionalLight )
{
RenderDirectionalLight ( RHICmdList , Scene , View , DefaultLightMaterial , * DirectionalLight , ChannelIdx , bInlineReflectionAndSky ) ;
}
}
if ( ! bInlineReflectionAndSky )
{
RenderReflectionEnvironmentSkyLighting ( RHICmdList , Scene , View ) ;
}
2020-12-11 14:21:20 -04:00
}
2022-04-13 01:56:42 -04:00
template < uint32 LightingChannel , bool bWithStencilCulling >
2020-09-24 00:43:27 -04:00
static void SetLocalLightRasterizerAndDepthState ( FGraphicsPipelineStateInitializer & GraphicsPSOInit , const FViewInfo & View , const FSphere & LightBounds )
{
2022-04-13 01:56:42 -04:00
if ( bWithStencilCulling )
2020-09-24 00:43:27 -04:00
{
2022-04-13 01:56:42 -04:00
// Render backfaces with depth and stencil tests
// and clear stencil to zero for next light mask
2020-09-24 00:43:27 -04:00
GraphicsPSOInit . RasterizerState = View . bReverseCulling ? TStaticRasterizerState < FM_Solid , CM_CW > : : GetRHI ( ) : TStaticRasterizerState < FM_Solid , CM_CCW > : : GetRHI ( ) ;
GraphicsPSOInit . DepthStencilState = TStaticDepthStencilState <
2022-04-13 01:56:42 -04:00
false , CF_LessEqual ,
false , CF_Equal , SO_Keep , SO_Keep , SO_Keep ,
true , CF_Equal , SO_Zero , SO_Keep , SO_Zero ,
GET_STENCIL_MOBILE_SM_MASK ( 0xff ) | STENCIL_LIGHTING_CHANNELS_MASK ( 1u < < LightingChannel ) | STENCIL_SANDBOX_MASK ,
STENCIL_SANDBOX_MASK
> : : GetRHI ( ) ;
2020-09-24 00:43:27 -04:00
}
else
{
2022-04-13 01:56:42 -04:00
const bool bCameraInsideLightGeometry = ( ( FVector ) View . ViewMatrices . GetViewOrigin ( ) - LightBounds . Center ) . SizeSquared ( ) < FMath : : Square ( LightBounds . W * 1.05f + View . NearClippingDistance * 2.0f )
// Always draw backfaces in ortho
//@todo - accurate ortho camera / light intersection
| | ! View . IsPerspectiveProjection ( ) ;
if ( bCameraInsideLightGeometry )
{
// Render backfaces with depth tests disabled since the camera is inside (or close to inside) the light geometry
GraphicsPSOInit . RasterizerState = View . bReverseCulling ? TStaticRasterizerState < FM_Solid , CM_CW > : : GetRHI ( ) : TStaticRasterizerState < FM_Solid , CM_CCW > : : GetRHI ( ) ;
GraphicsPSOInit . DepthStencilState = TStaticDepthStencilState <
false , CF_Always ,
true , CF_Equal , SO_Keep , SO_Keep , SO_Keep ,
false , CF_Always , SO_Keep , SO_Keep , SO_Keep ,
GET_STENCIL_MOBILE_SM_MASK ( 0xff ) | STENCIL_LIGHTING_CHANNELS_MASK ( 1u < < LightingChannel ) , 0x00 > : : GetRHI ( ) ;
}
else
{
// Render frontfaces with depth tests on to get the speedup from HiZ since the camera is outside the light geometry
GraphicsPSOInit . RasterizerState = View . bReverseCulling ? TStaticRasterizerState < FM_Solid , CM_CCW > : : GetRHI ( ) : TStaticRasterizerState < FM_Solid , CM_CW > : : GetRHI ( ) ;
GraphicsPSOInit . DepthStencilState = TStaticDepthStencilState <
false , CF_DepthNearOrEqual ,
true , CF_Equal , SO_Keep , SO_Keep , SO_Keep ,
false , CF_Always , SO_Keep , SO_Keep , SO_Keep ,
GET_STENCIL_MOBILE_SM_MASK ( 0xff ) | STENCIL_LIGHTING_CHANNELS_MASK ( 1u < < LightingChannel ) , 0x00 > : : GetRHI ( ) ;
}
}
}
template < uint32 LightingChannel >
static void SetLocalLightRasterizerAndDepthState ( FGraphicsPipelineStateInitializer & GraphicsPSOInit , const FViewInfo & View , const FSphere & LightBounds )
{
if ( GMobileUseLightStencilCulling ! = 0 )
{
SetLocalLightRasterizerAndDepthState < LightingChannel , true > ( GraphicsPSOInit , View , LightBounds ) ;
}
else
{
SetLocalLightRasterizerAndDepthState < LightingChannel , false > ( GraphicsPSOInit , View , LightBounds ) ;
2020-09-24 00:43:27 -04:00
}
}
2020-12-11 14:21:20 -04:00
static void RenderLocalLight_StencilMask ( FRHICommandListImmediate & RHICmdList , const FScene & Scene , const FViewInfo & View , const FLightSceneInfo & LightSceneInfo )
2020-09-24 00:43:27 -04:00
{
const uint8 LightType = LightSceneInfo . Proxy - > GetLightType ( ) ;
FGraphicsPipelineStateInitializer GraphicsPSOInit ;
RHICmdList . ApplyCachedRenderTargets ( GraphicsPSOInit ) ;
GraphicsPSOInit . PrimitiveType = PT_TriangleList ;
GraphicsPSOInit . BlendState = TStaticBlendStateWriteMask < CW_NONE , CW_NONE , CW_NONE , CW_NONE , CW_NONE , CW_NONE , CW_NONE , CW_NONE > : : GetRHI ( ) ;
GraphicsPSOInit . RasterizerState = View . bReverseCulling ? TStaticRasterizerState < FM_Solid , CM_CCW > : : GetRHI ( ) : TStaticRasterizerState < FM_Solid , CM_CW > : : GetRHI ( ) ;
// set stencil to 1 where depth test fails
GraphicsPSOInit . DepthStencilState = TStaticDepthStencilState <
false , CF_DepthNearOrEqual ,
true , CF_Always , SO_Keep , SO_Replace , SO_Keep ,
false , CF_Always , SO_Keep , SO_Keep , SO_Keep ,
0x00 , STENCIL_SANDBOX_MASK > : : GetRHI ( ) ;
2021-12-08 10:44:20 -05:00
FDeferredLightVS : : FPermutationDomain PermutationVector ;
PermutationVector . Set < FDeferredLightVS : : FRadialLight > ( true ) ;
TShaderMapRef < FDeferredLightVS > VertexShader ( View . ShaderMap , PermutationVector ) ;
2020-09-24 00:43:27 -04:00
GraphicsPSOInit . BoundShaderState . VertexDeclarationRHI = GetVertexDeclarationFVector4 ( ) ;
GraphicsPSOInit . BoundShaderState . VertexShaderRHI = VertexShader . GetVertexShader ( ) ;
GraphicsPSOInit . BoundShaderState . PixelShaderRHI = nullptr ;
2021-09-03 12:04:52 -04:00
SetGraphicsPipelineState ( RHICmdList , GraphicsPSOInit , 1 ) ;
2021-12-09 02:45:53 -05:00
FDeferredLightVS : : FParameters ParametersVS = FDeferredLightVS : : GetParameters ( View , & LightSceneInfo ) ;
SetShaderParameters ( RHICmdList , VertexShader , VertexShader . GetVertexShader ( ) , ParametersVS ) ;
2020-09-24 00:43:27 -04:00
if ( LightType = = LightType_Point )
{
StencilingGeometry : : DrawSphere ( RHICmdList ) ;
}
else // LightType_Spot
{
StencilingGeometry : : DrawCone ( RHICmdList ) ;
}
}
2020-12-11 14:21:20 -04:00
static void RenderLocalLight (
FRHICommandListImmediate & RHICmdList ,
const FScene & Scene ,
const FViewInfo & View ,
const FLightSceneInfo & LightSceneInfo ,
2022-04-18 09:09:40 -04:00
const FCachedLightMaterial & DefaultLightMaterial ,
const TArray < FVisibleLightInfo , SceneRenderingAllocator > & VisibleLightInfos )
2020-09-24 00:43:27 -04:00
{
2022-04-13 01:56:42 -04:00
uint8 LightingChannelMask = LightSceneInfo . Proxy - > GetLightingChannelMask ( ) ;
if ( ! LightSceneInfo . ShouldRenderLight ( View ) | | LightingChannelMask = = 0 )
2020-09-24 00:43:27 -04:00
{
return ;
}
2022-04-13 01:56:42 -04:00
2020-09-24 00:43:27 -04:00
const uint8 LightType = LightSceneInfo . Proxy - > GetLightType ( ) ;
2020-12-11 14:21:20 -04:00
const bool bIsSpotLight = LightType = = LightType_Spot ;
const bool bIsPointLight = LightType = = LightType_Point ;
if ( ! bIsSpotLight & & ! bIsPointLight )
2020-09-24 00:43:27 -04:00
{
return ;
}
2022-02-02 09:54:34 -05:00
FString LightNameWithLevel ;
FSceneRenderer : : GetLightNameForDrawEvent ( LightSceneInfo . Proxy , LightNameWithLevel ) ;
SCOPED_DRAW_EVENTF ( RHICmdList , LocalLight , TEXT ( " %s " ) , * LightNameWithLevel ) ;
2022-04-18 09:09:40 -04:00
check ( LightSceneInfo . Proxy - > IsLocalLight ( ) ) ;
2020-09-24 00:43:27 -04:00
if ( GMobileUseLightStencilCulling ! = 0 )
{
2020-12-11 14:21:20 -04:00
RenderLocalLight_StencilMask ( RHICmdList , Scene , View , LightSceneInfo ) ;
2020-09-24 00:43:27 -04:00
}
2020-11-24 18:42:39 -04:00
bool bUseIESTexture = false ;
FTexture * IESTextureResource = GWhiteTexture ;
if ( View . Family - > EngineShowFlags . TexturedLightProfiles & & LightSceneInfo . Proxy - > GetIESTextureResource ( ) )
{
IESTextureResource = LightSceneInfo . Proxy - > GetIESTextureResource ( ) ;
bUseIESTexture = true ;
}
2022-04-13 01:56:42 -04:00
2020-09-24 00:43:27 -04:00
FGraphicsPipelineStateInitializer GraphicsPSOInit ;
RHICmdList . ApplyCachedRenderTargets ( GraphicsPSOInit ) ;
GraphicsPSOInit . BlendState = TStaticBlendState < CW_RGBA , BO_Add , BF_One , BF_One , BO_Add , BF_One , BF_One > : : GetRHI ( ) ;
GraphicsPSOInit . PrimitiveType = PT_TriangleList ;
const FSphere LightBounds = LightSceneInfo . Proxy - > GetBoundingSphere ( ) ;
2022-04-13 01:56:42 -04:00
uint32 LightingChannel = GetLightingChannel ( LightingChannelMask ) ;
uint8 LightingChannelStencilValue = GetLightingChannelStencilValue ( LightingChannel ) ;
// TODO: support multi-channel ligths?
if ( LightingChannel = = 1u )
2020-12-11 14:21:20 -04:00
{
2022-04-13 01:56:42 -04:00
SetLocalLightRasterizerAndDepthState < 1u > ( GraphicsPSOInit , View , LightBounds ) ;
}
else if ( LightingChannel = = 2u )
{
SetLocalLightRasterizerAndDepthState < 2u > ( GraphicsPSOInit , View , LightBounds ) ;
2020-12-11 14:21:20 -04:00
}
else
{
2022-04-13 01:56:42 -04:00
SetLocalLightRasterizerAndDepthState < 0u > ( GraphicsPSOInit , View , LightBounds ) ;
2020-12-11 14:21:20 -04:00
}
2021-12-08 10:44:20 -05:00
FDeferredLightVS : : FPermutationDomain PermutationVectorVS ;
PermutationVectorVS . Set < FDeferredLightVS : : FRadialLight > ( true ) ;
TShaderMapRef < FDeferredLightVS > VertexShader ( View . ShaderMap , PermutationVectorVS ) ;
2022-04-22 01:15:27 -04:00
FDeferredLightVS : : FParameters ParametersVS = FDeferredLightVS : : GetParameters ( View , & LightSceneInfo ) ;
2020-12-11 14:21:20 -04:00
const FMaterialRenderProxy * LightFunctionMaterialProxy = nullptr ;
if ( View . Family - > EngineShowFlags . LightFunctions )
{
LightFunctionMaterialProxy = LightSceneInfo . Proxy - > GetLightFunctionMaterial ( ) ;
}
2022-04-22 01:15:27 -04:00
2022-04-18 09:09:40 -04:00
FMobileRadialLightFunctionPS : : FParameters PassParameters ;
const bool bShouldCastShadow = LightSceneInfo . SetupMobileMovableLocalLightShadowParameters ( View , VisibleLightInfos , PassParameters . MobileMovableLocalLightShadow ) ;
2020-12-11 14:21:20 -04:00
2020-09-24 00:43:27 -04:00
PassParameters . DeferredLightUniforms = TUniformBufferRef < FDeferredLightUniformStruct > : : CreateUniformBufferImmediate ( GetDeferredLightParameters ( View , LightSceneInfo ) , EUniformBufferUsage : : UniformBuffer_SingleFrame ) ;
2020-11-24 18:42:39 -04:00
PassParameters . IESTexture = IESTextureResource - > TextureRHI ;
PassParameters . IESTextureSampler = IESTextureResource - > SamplerStateRHI ;
2020-12-11 14:21:20 -04:00
const float TanOuterAngle = bIsSpotLight ? FMath : : Tan ( LightSceneInfo . Proxy - > GetOuterConeAngle ( ) ) : 1.0f ;
2021-09-22 10:01:48 -04:00
PassParameters . LightFunctionParameters = FVector4f ( TanOuterAngle , 1.0f /*ShadowFadeFraction*/ , bIsSpotLight ? 1.0f : 0.0f , bIsPointLight ? 1.0f : 0.0f ) ;
2022-04-18 09:09:40 -04:00
PassParameters . LightFunctionParameters2 = FVector3f ( LightSceneInfo . Proxy - > GetLightFunctionFadeDistance ( ) , LightSceneInfo . Proxy - > GetLightFunctionDisabledBrightness ( ) , IsMobileMovableSpotlightShadowsEnabled ( Scene . GetShaderPlatform ( ) ) ? 1.0f : 0.0f ) ;
2020-12-11 14:21:20 -04:00
const FVector Scale = LightSceneInfo . Proxy - > GetLightFunctionScale ( ) ;
// Switch x and z so that z of the user specified scale affects the distance along the light direction
const FVector InverseScale = FVector ( 1.f / Scale . Z , 1.f / Scale . Y , 1.f / Scale . X ) ;
2022-01-26 13:56:31 -05:00
const FMatrix WorldToLight = LightSceneInfo . Proxy - > GetWorldToLight ( ) * FScaleMatrix ( FVector ( InverseScale ) ) ;
PassParameters . TranslatedWorldToLight = FMatrix44f ( FTranslationMatrix ( - View . ViewMatrices . GetPreViewTranslation ( ) ) * WorldToLight ) ;
2020-09-24 00:43:27 -04:00
2022-04-22 01:15:27 -04:00
// Do two passes, first masking DefautLit, second masking all other shading models
2022-05-11 03:17:42 -04:00
int32 NumPasses = MobileUsesGBufferCustomData ( Scene . GetShaderPlatform ( ) ) ? 2 : 1 ;
2022-04-22 01:15:27 -04:00
uint8 PassShadingModelStencilValue [ 2 ] =
2020-09-24 00:43:27 -04:00
{
2022-04-22 01:15:27 -04:00
GetMobileShadingModelStencilValue ( MSM_DefaultLit ) ,
GetMobileShadingModelStencilValue ( FMaterialShadingModelField ( ) )
} ;
for ( int32 PassIndex = 0 ; PassIndex < NumPasses ; PassIndex + + )
2020-09-24 00:43:27 -04:00
{
2022-04-22 01:15:27 -04:00
const bool bEnableShadingModelSupport = ( PassIndex > 0 ) ;
FMobileRadialLightFunctionPS : : FPermutationDomain PermutationVector ;
PermutationVector . Set < FMobileRadialLightFunctionPS : : FEnableShadingModelSupport > ( bEnableShadingModelSupport ) ;
PermutationVector . Set < FMobileRadialLightFunctionPS : : FSpotLightDim > ( bIsSpotLight ) ;
PermutationVector . Set < FMobileRadialLightFunctionPS : : FIESProfileDim > ( bUseIESTexture ) ;
PermutationVector . Set < FMobileRadialLightFunctionPS : : FSpotLightShadowDim > ( bShouldCastShadow ) ;
FCachedLightMaterial LightMaterial ;
TShaderRef < FMobileRadialLightFunctionPS > PixelShader ;
GetLightMaterial ( DefaultLightMaterial , LightFunctionMaterialProxy , PermutationVector . ToDimensionValueId ( ) , LightMaterial , PixelShader ) ;
GraphicsPSOInit . BoundShaderState . VertexDeclarationRHI = GetVertexDeclarationFVector4 ( ) ;
GraphicsPSOInit . BoundShaderState . VertexShaderRHI = VertexShader . GetVertexShader ( ) ;
GraphicsPSOInit . BoundShaderState . PixelShaderRHI = PixelShader . GetPixelShader ( ) ;
uint8 StencilRef =
GET_STENCIL_MOBILE_SM_MASK ( PassShadingModelStencilValue [ PassIndex ] ) |
STENCIL_LIGHTING_CHANNELS_MASK ( LightingChannelStencilValue ) ;
SetGraphicsPipelineState ( RHICmdList , GraphicsPSOInit , StencilRef ) ;
SetShaderParameters ( RHICmdList , VertexShader , VertexShader . GetVertexShader ( ) , ParametersVS ) ;
FMobileRadialLightFunctionPS : : SetParameters ( RHICmdList , PixelShader , View , LightMaterial . MaterialProxy , * LightMaterial . Material , PassParameters ) ;
if ( LightType = = LightType_Point )
{
StencilingGeometry : : DrawSphere ( RHICmdList ) ;
}
else // LightType_Spot
{
StencilingGeometry : : DrawCone ( RHICmdList ) ;
}
2020-09-24 00:43:27 -04:00
}
}
2020-12-11 14:21:20 -04:00
static void RenderSimpleLights (
FRHICommandListImmediate & RHICmdList ,
const FScene & Scene ,
2021-03-09 00:23:43 -04:00
int32 ViewIndex ,
int32 NumViews ,
const FViewInfo & View ,
2020-12-11 14:21:20 -04:00
const FSortedLightSetSceneInfo & SortedLightSet ,
const FCachedLightMaterial & DefaultMaterial )
{
const FSimpleLightArray & SimpleLights = SortedLightSet . SimpleLights ;
2022-02-02 09:54:34 -05:00
if ( SimpleLights . InstanceData . Num ( ) = = 0 )
{
return ;
}
SCOPED_DRAW_EVENT ( RHICmdList , SimpleLights ) ;
2020-12-11 14:21:20 -04:00
2021-12-08 10:44:20 -05:00
FDeferredLightVS : : FPermutationDomain PermutationVectorVS ;
PermutationVectorVS . Set < FDeferredLightVS : : FRadialLight > ( true ) ;
TShaderMapRef < FDeferredLightVS > VertexShader ( View . ShaderMap , PermutationVectorVS ) ;
2020-12-11 14:21:20 -04:00
// Setup stencil mask PSO
FGraphicsPipelineStateInitializer GraphicsPSOLightMask ;
{
RHICmdList . ApplyCachedRenderTargets ( GraphicsPSOLightMask ) ;
GraphicsPSOLightMask . PrimitiveType = PT_TriangleList ;
GraphicsPSOLightMask . BlendState = TStaticBlendStateWriteMask < CW_NONE , CW_NONE , CW_NONE , CW_NONE , CW_NONE , CW_NONE , CW_NONE , CW_NONE > : : GetRHI ( ) ;
2021-03-09 00:23:43 -04:00
GraphicsPSOLightMask . RasterizerState = View . bReverseCulling ? TStaticRasterizerState < FM_Solid , CM_CCW > : : GetRHI ( ) : TStaticRasterizerState < FM_Solid , CM_CW > : : GetRHI ( ) ;
2020-12-11 14:21:20 -04:00
// set stencil to 1 where depth test fails
GraphicsPSOLightMask . DepthStencilState = TStaticDepthStencilState <
false , CF_DepthNearOrEqual ,
true , CF_Always , SO_Keep , SO_Replace , SO_Keep ,
false , CF_Always , SO_Keep , SO_Keep , SO_Keep ,
0x00 , STENCIL_SANDBOX_MASK > : : GetRHI ( ) ;
GraphicsPSOLightMask . BoundShaderState . VertexDeclarationRHI = GetVertexDeclarationFVector4 ( ) ;
GraphicsPSOLightMask . BoundShaderState . VertexShaderRHI = VertexShader . GetVertexShader ( ) ;
GraphicsPSOLightMask . BoundShaderState . PixelShaderRHI = nullptr ;
}
2022-04-22 01:15:27 -04:00
const FMaterialShaderMap * MaterialShaderMap = DefaultMaterial . Material - > GetRenderingThreadShaderMap ( ) ;
// Setup PSOs we going to use for light rendering
// Do two passes, first masking DefautLit, second masking all other shading models
2022-05-11 03:17:42 -04:00
int32 NumPasses = MobileUsesGBufferCustomData ( Scene . GetShaderPlatform ( ) ) ? 2 : 1 ;
2022-04-22 01:15:27 -04:00
uint8 PassShadingModelStencilValue [ 2 ] =
{
GetMobileShadingModelStencilValue ( MSM_DefaultLit ) ,
GetMobileShadingModelStencilValue ( FMaterialShadingModelField ( ) )
} ;
TShaderRef < FMobileRadialLightFunctionPS > PassPixelShaders [ 2 ] ;
FGraphicsPipelineStateInitializer GraphicsPSOLight [ 2 ] ;
for ( int32 PassIndex = 0 ; PassIndex < NumPasses ; + + PassIndex )
{
const bool bEnableShadingModelSupport = ( PassIndex > 0 ) ;
RHICmdList . ApplyCachedRenderTargets ( GraphicsPSOLight [ PassIndex ] ) ;
// Use additive blending for color
GraphicsPSOLight [ PassIndex ] . BlendState = TStaticBlendState < CW_RGBA , BO_Add , BF_One , BF_One , BO_Add , BF_One , BF_One > : : GetRHI ( ) ;
GraphicsPSOLight [ PassIndex ] . PrimitiveType = PT_TriangleList ;
GraphicsPSOLight [ PassIndex ] . BoundShaderState . VertexDeclarationRHI = GetVertexDeclarationFVector4 ( ) ;
GraphicsPSOLight [ PassIndex ] . BoundShaderState . VertexShaderRHI = VertexShader . GetVertexShader ( ) ;
SetLocalLightRasterizerAndDepthState < 0u , true > ( GraphicsPSOLight [ PassIndex ] , View , FSphere ( ) ) ;
TShaderRef < FMobileRadialLightFunctionPS > PixelShader ;
FMobileRadialLightFunctionPS : : FPermutationDomain PermutationVector ;
PermutationVector . Set < FMobileRadialLightFunctionPS : : FEnableShadingModelSupport > ( bEnableShadingModelSupport ) ;
PermutationVector . Set < FMobileRadialLightFunctionPS : : FSpotLightDim > ( false ) ;
PermutationVector . Set < FMobileRadialLightFunctionPS : : FIESProfileDim > ( false ) ;
PassPixelShaders [ PassIndex ] = MaterialShaderMap - > GetShader < FMobileRadialLightFunctionPS > ( PermutationVector ) ;
GraphicsPSOLight [ PassIndex ] . BoundShaderState . PixelShaderRHI = PassPixelShaders [ PassIndex ] . GetPixelShader ( ) ;
}
2020-12-11 14:21:20 -04:00
for ( int32 LightIndex = 0 ; LightIndex < SimpleLights . InstanceData . Num ( ) ; LightIndex + + )
{
const FSimpleLightEntry & SimpleLight = SimpleLights . InstanceData [ LightIndex ] ;
2021-03-09 00:23:43 -04:00
const FSimpleLightPerViewEntry & SimpleLightPerViewData = SimpleLights . GetViewDependentData ( LightIndex , ViewIndex , NumViews ) ;
const FSphere LightBounds ( SimpleLightPerViewData . Position , SimpleLight . Radius ) ;
if ( NumViews > 1 )
2020-12-11 14:21:20 -04:00
{
2021-03-09 00:23:43 -04:00
// set viewports only we we have more than one
// otherwise it is set at the start of the pass
RHICmdList . SetViewport ( View . ViewRect . Min . X , View . ViewRect . Min . Y , 0.0f , View . ViewRect . Max . X , View . ViewRect . Max . Y , 1.0f ) ;
2020-12-11 14:21:20 -04:00
}
2021-03-09 00:23:43 -04:00
// Render light mask
2021-09-03 12:04:52 -04:00
SetGraphicsPipelineState ( RHICmdList , GraphicsPSOLightMask , 1 ) ;
2021-12-09 02:45:53 -05:00
FDeferredLightVS : : FParameters ParametersVS = FDeferredLightVS : : GetParameters ( View , LightBounds ) ;
SetShaderParameters ( RHICmdList , VertexShader , VertexShader . GetVertexShader ( ) , ParametersVS ) ;
2021-03-09 00:23:43 -04:00
StencilingGeometry : : DrawSphere ( RHICmdList ) ;
// Render light
FMobileRadialLightFunctionPS : : FParameters PassParameters ;
2022-01-26 13:56:31 -05:00
FDeferredLightUniformStruct DeferredLightUniformsValue = GetSimpleDeferredLightParameters ( View , SimpleLight , SimpleLightPerViewData ) ;
2021-03-09 00:23:43 -04:00
PassParameters . DeferredLightUniforms = TUniformBufferRef < FDeferredLightUniformStruct > : : CreateUniformBufferImmediate ( DeferredLightUniformsValue , EUniformBufferUsage : : UniformBuffer_SingleFrame ) ;
PassParameters . IESTexture = GWhiteTexture - > TextureRHI ;
PassParameters . IESTextureSampler = GWhiteTexture - > SamplerStateRHI ;
2021-09-03 12:04:52 -04:00
2022-04-22 01:15:27 -04:00
for ( int32 PassIndex = 0 ; PassIndex < NumPasses ; + + PassIndex )
2021-03-09 00:23:43 -04:00
{
2022-04-22 01:15:27 -04:00
uint8 StencilRef = GET_STENCIL_MOBILE_SM_MASK ( PassShadingModelStencilValue [ PassIndex ] ) ;
SetGraphicsPipelineState ( RHICmdList , GraphicsPSOLight [ PassIndex ] , StencilRef ) ;
FMobileRadialLightFunctionPS : : SetParameters ( RHICmdList , PassPixelShaders [ PassIndex ] , View , DefaultMaterial . MaterialProxy , * DefaultMaterial . Material , PassParameters ) ;
2021-03-09 00:23:43 -04:00
2022-04-22 01:15:27 -04:00
// Apply the point or spot light with some approximately bounding geometry,
// So we can get speedups from depth testing and not processing pixels outside of the light's influence.
StencilingGeometry : : DrawSphere ( RHICmdList ) ;
}
2020-12-11 14:21:20 -04:00
}
}
void MobileDeferredShadingPass (
2021-03-09 00:23:43 -04:00
FRHICommandListImmediate & RHICmdList ,
int32 ViewIndex ,
int32 NumViews ,
const FViewInfo & View ,
2020-12-11 14:21:20 -04:00
const FScene & Scene ,
2022-04-18 09:09:40 -04:00
const FSortedLightSetSceneInfo & SortedLightSet ,
const TArray < FVisibleLightInfo , SceneRenderingAllocator > & VisibleLightInfos )
2020-09-24 00:43:27 -04:00
{
2022-02-02 09:54:34 -05:00
SCOPED_DRAW_EVENT ( RHICmdList , DeferredShading ) ;
2021-03-09 00:23:43 -04:00
RHICmdList . SetViewport ( View . ViewRect . Min . X , View . ViewRect . Min . Y , 0.0f , View . ViewRect . Max . X , View . ViewRect . Max . Y , 1.0f ) ;
2020-09-24 00:43:27 -04:00
2021-03-09 00:23:43 -04:00
// Default material for light rendering
FCachedLightMaterial DefaultMaterial ;
DefaultMaterial . MaterialProxy = UMaterial : : GetDefaultMaterial ( MD_LightFunction ) - > GetRenderProxy ( ) ;
DefaultMaterial . Material = DefaultMaterial . MaterialProxy - > GetMaterialNoFallback ( ERHIFeatureLevel : : ES3_1 ) ;
check ( DefaultMaterial . Material ) ;
2022-04-13 01:56:42 -04:00
RenderDirectionalLights ( RHICmdList , Scene , View , DefaultMaterial ) ;
2021-03-09 00:23:43 -04:00
if ( GMobileUseClusteredDeferredShading = = 0 )
2020-09-24 00:43:27 -04:00
{
2021-03-09 00:23:43 -04:00
// Render non-clustered simple lights
RenderSimpleLights ( RHICmdList , Scene , ViewIndex , NumViews , View , SortedLightSet , DefaultMaterial ) ;
}
2020-12-04 12:07:09 -04:00
2021-03-09 00:23:43 -04:00
// Render non-clustered local lights
int32 NumLights = SortedLightSet . SortedLights . Num ( ) ;
2022-04-18 09:09:40 -04:00
const int32 UnbatchedLightStart = SortedLightSet . UnbatchedLightStart ;
2021-03-09 00:23:43 -04:00
int32 StandardDeferredStart = SortedLightSet . SimpleLightsEnd ;
if ( GMobileUseClusteredDeferredShading ! = 0 )
{
StandardDeferredStart = SortedLightSet . ClusteredSupportedEnd ;
}
2020-12-11 14:21:20 -04:00
2022-04-18 09:09:40 -04:00
// Draw non-shadowed non-light function lights
for ( int32 LightIdx = StandardDeferredStart ; LightIdx < UnbatchedLightStart ; + + LightIdx )
2021-03-09 00:23:43 -04:00
{
const FSortedLightSceneInfo & SortedLight = SortedLightSet . SortedLights [ LightIdx ] ;
const FLightSceneInfo & LightSceneInfo = * SortedLight . LightSceneInfo ;
2022-04-18 09:09:40 -04:00
RenderLocalLight ( RHICmdList , Scene , View , LightSceneInfo , DefaultMaterial , VisibleLightInfos ) ;
}
// Draw shadowed and light function lights
for ( int32 LightIdx = UnbatchedLightStart ; LightIdx < NumLights ; + + LightIdx )
{
const FSortedLightSceneInfo & SortedLight = SortedLightSet . SortedLights [ LightIdx ] ;
const FLightSceneInfo & LightSceneInfo = * SortedLight . LightSceneInfo ;
RenderLocalLight ( RHICmdList , Scene , View , LightSceneInfo , DefaultMaterial , VisibleLightInfos ) ;
2021-03-09 00:23:43 -04:00
}
2020-09-24 00:43:27 -04:00
}