2014-12-07 19:09:38 -05:00
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
2014-03-14 14:13:41 -04:00
/*=============================================================================
Reflection Environment - feature that provides HDR glossy reflections on any surfaces , leveraging precomputation to prefilter cubemaps of the scene
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
# include "RendererPrivate.h"
# include "ScenePrivate.h"
# include "SceneFilterRendering.h"
# include "PostProcessing.h"
# include "UniformBuffer.h"
# include "ShaderParameters.h"
# include "ScreenRendering.h"
# include "ScreenSpaceReflections.h"
# include "PostProcessTemporalAA.h"
# include "PostProcessDownsample.h"
# include "ReflectionEnvironment.h"
2014-06-05 16:38:54 -04:00
# include "ShaderParameterUtils.h"
2014-03-14 14:13:41 -04:00
# include "LightRendering.h"
2014-08-21 06:03:00 -04:00
# include "SceneUtils.h"
2014-03-14 14:13:41 -04:00
/** Tile size for the reflection environment compute shader, tweaked for 680 GTX. */
const int32 GReflectionEnvironmentTileSizeX = 16 ;
const int32 GReflectionEnvironmentTileSizeY = 16 ;
extern ENGINE_API int32 GReflectionCaptureSize ;
2014-05-08 16:17:53 -04:00
static TAutoConsoleVariable < int32 > CVarDiffuseFromCaptures (
2014-04-30 14:14:19 -04:00
TEXT ( " r.DiffuseFromCaptures " ) ,
2014-05-08 16:17:53 -04:00
0 ,
2014-04-30 14:14:19 -04:00
TEXT ( " Apply indirect diffuse lighting from captures instead of lightmaps. \n " )
TEXT ( " 0 is off (default), 1 is on " ) ,
2014-05-08 16:17:53 -04:00
ECVF_RenderThreadSafe ) ;
2014-04-30 14:14:19 -04:00
2014-06-25 05:47:33 -04:00
# if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
static TAutoConsoleVariable < int32 > CVarReflectionEnvironment (
TEXT ( " r.ReflectionEnvironment " ) ,
1 ,
TEXT ( " 0:off, 1:on and blend with scene, 2:on and overwrite scene. \n " )
TEXT ( " Whether to render the reflection environment feature, which implements local reflections through Reflection Capture actors. " ) ,
ECVF_Cheat | ECVF_RenderThreadSafe ) ;
# endif
2014-09-18 17:49:40 -04:00
static TAutoConsoleVariable < int32 > CVarHalfResReflections (
TEXT ( " r.HalfResReflections " ) ,
0 ,
TEXT ( " Compute ReflectionEnvironment samples at half resolution. \n " )
TEXT ( " 0 is off (default), 1 is on " ) ,
ECVF_RenderThreadSafe ) ;
2015-04-08 16:15:25 -04:00
static TAutoConsoleVariable < int32 > CVarDoTiledReflections (
TEXT ( " r.DoTiledReflections " ) ,
1 ,
TEXT ( " Compute Reflection Environment with Tiled compute shader.. \n " )
TEXT ( " 1 is on (default), 1 is on " ) ,
ECVF_RenderThreadSafe ) ;
2014-11-24 17:39:52 -05:00
static TAutoConsoleVariable < float > CVarSkySpecularOcclusionStrength (
TEXT ( " r.SkySpecularOcclusionStrength " ) ,
1 ,
TEXT ( " Strength of skylight specular occlusion from DFAO " ) ,
ECVF_RenderThreadSafe ) ;
2014-03-14 14:13:41 -04:00
// to avoid having direct access from many places
static int GetReflectionEnvironmentCVar ( )
{
# if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
2014-06-25 05:47:33 -04:00
return CVarReflectionEnvironment . GetValueOnAnyThread ( ) ;
2014-03-14 14:13:41 -04:00
# endif
// on, default mode
return 1 ;
}
2014-05-08 09:05:50 -04:00
bool IsReflectionEnvironmentAvailable ( ERHIFeatureLevel : : Type InFeatureLevel )
2014-03-14 14:13:41 -04:00
{
static const auto AllowStaticLightingVar = IConsoleManager : : Get ( ) . FindTConsoleVariableDataInt ( TEXT ( " r.AllowStaticLighting " ) ) ;
const bool bAllowStaticLighting = ( ! AllowStaticLightingVar | | AllowStaticLightingVar - > GetValueOnAnyThread ( ) ! = 0 ) ;
2014-05-08 09:05:50 -04:00
return ( InFeatureLevel > = ERHIFeatureLevel : : SM4 ) & & ( GetReflectionEnvironmentCVar ( ) ! = 0 ) & & bAllowStaticLighting ;
2014-03-14 14:13:41 -04:00
}
void FReflectionEnvironmentCubemapArray : : InitDynamicRHI ( )
{
2014-07-10 10:39:54 -04:00
if ( GetFeatureLevel ( ) > = ERHIFeatureLevel : : SM5 )
2014-03-14 14:13:41 -04:00
{
const int32 NumReflectionCaptureMips = FMath : : CeilLogTwo ( GReflectionCaptureSize ) + 1 ;
ReleaseCubeArray ( ) ;
FPooledRenderTargetDesc Desc ( FPooledRenderTargetDesc : : CreateCubemapDesc (
2014-06-05 16:38:54 -04:00
GReflectionCaptureSize ,
//@todo - get rid of the alpha channel (currently stores brightness which is a constant), could use PF_FloatRGB for half memory, would need to implement RHIReadSurface support
PF_FloatRGBA ,
TexCreate_None ,
TexCreate_None ,
false ,
// Cubemap array of 1 produces a regular cubemap, so guarantee it will be allocated as an array
FMath : : Max < uint32 > ( MaxCubemaps , 2 ) ,
NumReflectionCaptureMips ) ) ;
2014-03-14 14:13:41 -04:00
// Allocate TextureCubeArray for the scene's reflection captures
GRenderTargetPool . FindFreeElement ( Desc , ReflectionEnvs , TEXT ( " ReflectionEnvs " ) ) ;
}
}
void FReflectionEnvironmentCubemapArray : : ReleaseCubeArray ( )
{
// it's unlikely we can reuse the TextureCubeArray so when we release it we want to really remove it
GRenderTargetPool . FreeUnusedResource ( ReflectionEnvs ) ;
}
void FReflectionEnvironmentCubemapArray : : ReleaseDynamicRHI ( )
{
ReleaseCubeArray ( ) ;
}
void FReflectionEnvironmentCubemapArray : : UpdateMaxCubemaps ( uint32 InMaxCubemaps )
{
MaxCubemaps = InMaxCubemaps ;
// Reallocate the cubemap array
if ( IsInitialized ( ) )
{
UpdateRHI ( ) ;
}
else
{
InitResource ( ) ;
}
}
2014-08-28 13:54:31 -04:00
class FDistanceFieldAOSpecularOcclusionParameters
{
public :
void Bind ( const FShaderParameterMap & ParameterMap )
{
BentNormalAOTexture . Bind ( ParameterMap , TEXT ( " BentNormalAOTexture " ) ) ;
BentNormalAOSampler . Bind ( ParameterMap , TEXT ( " BentNormalAOSampler " ) ) ;
ApplyBentNormalAO . Bind ( ParameterMap , TEXT ( " ApplyBentNormalAO " ) ) ;
2014-11-24 17:39:52 -05:00
InvSkySpecularOcclusionStrength . Bind ( ParameterMap , TEXT ( " InvSkySpecularOcclusionStrength " ) ) ;
2015-02-19 16:22:43 -05:00
MinSkySpecularOcclusion . Bind ( ParameterMap , TEXT ( " MinSkySpecularOcclusion " ) ) ;
2014-08-28 13:54:31 -04:00
}
template < typename ShaderRHIParamRef >
2015-02-19 16:22:43 -05:00
void SetParameters ( FRHICommandList & RHICmdList , const ShaderRHIParamRef & ShaderRHI , const TRefCountPtr < IPooledRenderTarget > & DynamicBentNormalAO , float SkySpecularOcclusionStrength , float MinOcclusionValue )
2014-08-28 13:54:31 -04:00
{
FTextureRHIParamRef BentNormalAO = GWhiteTexture - > TextureRHI ;
bool bApplyBentNormalAO = false ;
if ( DynamicBentNormalAO )
{
BentNormalAO = DynamicBentNormalAO - > GetRenderTargetItem ( ) . ShaderResourceTexture ;
bApplyBentNormalAO = true ;
}
SetTextureParameter ( RHICmdList , ShaderRHI , BentNormalAOTexture , BentNormalAOSampler , TStaticSamplerState < SF_Point > : : GetRHI ( ) , BentNormalAO ) ;
SetShaderValue ( RHICmdList , ShaderRHI , ApplyBentNormalAO , bApplyBentNormalAO ? 1.0f : 0.0f ) ;
2014-11-24 17:39:52 -05:00
SetShaderValue ( RHICmdList , ShaderRHI , InvSkySpecularOcclusionStrength , 1.0f / FMath : : Max ( SkySpecularOcclusionStrength , .1f ) ) ;
2015-02-19 16:22:43 -05:00
SetShaderValue ( RHICmdList , ShaderRHI , MinSkySpecularOcclusion , MinOcclusionValue ) ;
2014-08-28 13:54:31 -04:00
}
friend FArchive & operator < < ( FArchive & Ar , FDistanceFieldAOSpecularOcclusionParameters & P )
{
2015-02-19 16:22:43 -05:00
Ar < < P . BentNormalAOTexture < < P . BentNormalAOSampler < < P . ApplyBentNormalAO < < P . InvSkySpecularOcclusionStrength < < P . MinSkySpecularOcclusion ;
2014-08-28 13:54:31 -04:00
return Ar ;
}
private :
FShaderResourceParameter BentNormalAOTexture ;
FShaderResourceParameter BentNormalAOSampler ;
FShaderParameter ApplyBentNormalAO ;
2014-11-24 17:39:52 -05:00
FShaderParameter InvSkySpecularOcclusionStrength ;
2015-02-19 16:22:43 -05:00
FShaderParameter MinSkySpecularOcclusion ;
2014-08-28 13:54:31 -04:00
} ;
2014-03-14 14:13:41 -04:00
struct FReflectionCaptureSortData
{
uint32 Guid ;
2014-09-10 19:20:06 -04:00
int32 CaptureIndex ;
2014-03-14 14:13:41 -04:00
FVector4 PositionAndRadius ;
FVector4 CaptureProperties ;
FMatrix BoxTransform ;
FVector4 BoxScales ;
FTexture * SM4FullHDRCubemap ;
bool operator < ( const FReflectionCaptureSortData & Other ) const
{
if ( PositionAndRadius . W ! = Other . PositionAndRadius . W )
{
return PositionAndRadius . W < Other . PositionAndRadius . W ;
}
else
{
return Guid < Other . Guid ;
}
}
} ;
/** Per-reflection capture data needed by the shader. */
BEGIN_UNIFORM_BUFFER_STRUCT ( FReflectionCaptureData , )
DECLARE_UNIFORM_BUFFER_STRUCT_MEMBER_ARRAY ( FVector4 , PositionAndRadius , [ GMaxNumReflectionCaptures ] )
// R is brightness, G is array index, B is shape
DECLARE_UNIFORM_BUFFER_STRUCT_MEMBER_ARRAY ( FVector4 , CaptureProperties , [ GMaxNumReflectionCaptures ] )
// Stores the box transform for a box shape, other data is packed for other shapes
DECLARE_UNIFORM_BUFFER_STRUCT_MEMBER_ARRAY ( FMatrix , BoxTransform , [ GMaxNumReflectionCaptures ] )
DECLARE_UNIFORM_BUFFER_STRUCT_MEMBER_ARRAY ( FVector4 , BoxScales , [ GMaxNumReflectionCaptures ] )
END_UNIFORM_BUFFER_STRUCT ( FReflectionCaptureData )
IMPLEMENT_UNIFORM_BUFFER_STRUCT ( FReflectionCaptureData , TEXT ( " ReflectionCapture " ) ) ;
/** Compute shader that does tiled deferred culling of reflection captures, then sorts and composites them. */
class FReflectionEnvironmentTiledDeferredCS : public FGlobalShader
{
DECLARE_SHADER_TYPE ( FReflectionEnvironmentTiledDeferredCS , Global )
public :
static bool ShouldCache ( EShaderPlatform Platform )
{
return IsFeatureLevelSupported ( Platform , ERHIFeatureLevel : : SM5 ) ;
}
static void ModifyCompilationEnvironment ( EShaderPlatform Platform , FShaderCompilerEnvironment & OutEnvironment )
{
FGlobalShader : : ModifyCompilationEnvironment ( Platform , OutEnvironment ) ;
OutEnvironment . SetDefine ( TEXT ( " THREADGROUP_SIZEX " ) , GReflectionEnvironmentTileSizeX ) ;
OutEnvironment . SetDefine ( TEXT ( " THREADGROUP_SIZEY " ) , GReflectionEnvironmentTileSizeY ) ;
OutEnvironment . SetDefine ( TEXT ( " MAX_CAPTURES " ) , GMaxNumReflectionCaptures ) ;
OutEnvironment . SetDefine ( TEXT ( " TILED_DEFERRED_CULL_SHADER " ) , 1 ) ;
OutEnvironment . CompilerFlags . Add ( CFLAG_StandardOptimization ) ;
}
FReflectionEnvironmentTiledDeferredCS ( const ShaderMetaType : : CompiledShaderInitializerType & Initializer )
: FGlobalShader ( Initializer )
{
DeferredParameters . Bind ( Initializer . ParameterMap ) ;
ReflectionEnvironmentColorTexture . Bind ( Initializer . ParameterMap , TEXT ( " ReflectionEnvironmentColorTexture " ) ) ;
ReflectionEnvironmentColorSampler . Bind ( Initializer . ParameterMap , TEXT ( " ReflectionEnvironmentColorSampler " ) ) ;
2014-04-30 14:14:19 -04:00
ScreenSpaceReflections . Bind ( Initializer . ParameterMap , TEXT ( " ScreenSpaceReflections " ) ) ;
InSceneColor . Bind ( Initializer . ParameterMap , TEXT ( " InSceneColor " ) ) ;
OutSceneColor . Bind ( Initializer . ParameterMap , TEXT ( " OutSceneColor " ) ) ;
2014-03-14 14:13:41 -04:00
NumCaptures . Bind ( Initializer . ParameterMap , TEXT ( " NumCaptures " ) ) ;
ViewDimensionsParameter . Bind ( Initializer . ParameterMap , TEXT ( " ViewDimensions " ) ) ;
PreIntegratedGF . Bind ( Initializer . ParameterMap , TEXT ( " PreIntegratedGF " ) ) ;
PreIntegratedGFSampler . Bind ( Initializer . ParameterMap , TEXT ( " PreIntegratedGFSampler " ) ) ;
SkyLightParameters . Bind ( Initializer . ParameterMap ) ;
2014-08-28 13:54:31 -04:00
SpecularOcclusionParameters . Bind ( Initializer . ParameterMap ) ;
2014-03-14 14:13:41 -04:00
}
FReflectionEnvironmentTiledDeferredCS ( )
{
}
2015-04-08 16:15:25 -04:00
void SetParameters ( FRHICommandList & RHICmdList , const FSceneView & View , FTextureRHIParamRef SSRTexture , TArray < FReflectionCaptureSortData > & SortData , FUnorderedAccessViewRHIParamRef OutSceneColorUAV , const TRefCountPtr < IPooledRenderTarget > & DynamicBentNormalAO )
2014-03-14 14:13:41 -04:00
{
const FComputeShaderRHIParamRef ShaderRHI = GetComputeShader ( ) ;
2014-06-05 16:38:54 -04:00
FGlobalShader : : SetParameters ( RHICmdList , ShaderRHI , View ) ;
DeferredParameters . Set ( RHICmdList , ShaderRHI , View ) ;
2014-03-14 14:13:41 -04:00
FScene * Scene = ( FScene * ) View . Family - > Scene ;
2014-05-08 16:17:53 -04:00
check ( Scene - > ReflectionSceneData . CubemapArray . IsValid ( ) ) ;
check ( Scene - > ReflectionSceneData . CubemapArray . GetRenderTarget ( ) . IsValid ( ) ) ;
2014-03-14 14:13:41 -04:00
FSceneRenderTargetItem & CubemapArray = Scene - > ReflectionSceneData . CubemapArray . GetRenderTarget ( ) ;
SetTextureParameter (
2014-06-05 16:38:54 -04:00
RHICmdList ,
2014-03-14 14:13:41 -04:00
ShaderRHI ,
ReflectionEnvironmentColorTexture ,
ReflectionEnvironmentColorSampler ,
TStaticSamplerState < SF_Trilinear , AM_Clamp , AM_Clamp , AM_Clamp > : : GetRHI ( ) ,
2014-05-08 16:17:53 -04:00
CubemapArray . ShaderResourceTexture ) ;
2014-03-14 14:13:41 -04:00
2014-06-05 16:38:54 -04:00
SetTextureParameter ( RHICmdList , ShaderRHI , ScreenSpaceReflections , SSRTexture ) ;
2014-04-30 14:14:19 -04:00
2014-06-05 16:38:54 -04:00
SetTextureParameter ( RHICmdList , ShaderRHI , InSceneColor , GSceneRenderTargets . GetSceneColor ( ) - > GetRenderTargetItem ( ) . ShaderResourceTexture ) ;
OutSceneColor . SetTexture ( RHICmdList , ShaderRHI , NULL , OutSceneColorUAV ) ;
2014-03-14 14:13:41 -04:00
2014-06-05 16:38:54 -04:00
SetShaderValue ( RHICmdList , ShaderRHI , ViewDimensionsParameter , View . ViewRect ) ;
2014-03-14 14:13:41 -04:00
FReflectionCaptureData SamplePositionsBuffer ;
for ( int32 CaptureIndex = 0 ; CaptureIndex < SortData . Num ( ) ; CaptureIndex + + )
{
SamplePositionsBuffer . PositionAndRadius [ CaptureIndex ] = SortData [ CaptureIndex ] . PositionAndRadius ;
SamplePositionsBuffer . CaptureProperties [ CaptureIndex ] = SortData [ CaptureIndex ] . CaptureProperties ;
SamplePositionsBuffer . BoxTransform [ CaptureIndex ] = SortData [ CaptureIndex ] . BoxTransform ;
SamplePositionsBuffer . BoxScales [ CaptureIndex ] = SortData [ CaptureIndex ] . BoxScales ;
}
2014-06-05 16:38:54 -04:00
SetUniformBufferParameterImmediate ( RHICmdList , ShaderRHI , GetUniformBufferParameter < FReflectionCaptureData > ( ) , SamplePositionsBuffer ) ;
SetShaderValue ( RHICmdList , ShaderRHI , NumCaptures , SortData . Num ( ) ) ;
2014-03-14 14:13:41 -04:00
2014-06-05 16:38:54 -04:00
SetTextureParameter ( RHICmdList , ShaderRHI , PreIntegratedGF , PreIntegratedGFSampler , TStaticSamplerState < SF_Bilinear , AM_Clamp , AM_Clamp , AM_Clamp > : : GetRHI ( ) , GSystemTextures . PreintegratedGF - > GetRenderTargetItem ( ) . ShaderResourceTexture ) ;
2014-03-14 14:13:41 -04:00
2014-06-05 16:38:54 -04:00
SkyLightParameters . SetParameters ( RHICmdList , ShaderRHI , Scene , View . Family - > EngineShowFlags . SkyLighting ) ;
2015-02-19 16:22:43 -05:00
const float MinOcclusion = Scene - > SkyLight ? Scene - > SkyLight - > MinOcclusion : 0 ;
SpecularOcclusionParameters . SetParameters ( RHICmdList , ShaderRHI , DynamicBentNormalAO , CVarSkySpecularOcclusionStrength . GetValueOnRenderThread ( ) , MinOcclusion ) ;
2014-03-14 14:13:41 -04:00
}
2014-06-12 07:13:34 -04:00
void UnsetParameters ( FRHICommandList & RHICmdList )
2014-03-14 14:13:41 -04:00
{
const FComputeShaderRHIParamRef ShaderRHI = GetComputeShader ( ) ;
2014-06-12 07:13:34 -04:00
OutSceneColor . UnsetUAV ( RHICmdList , ShaderRHI ) ;
2014-03-14 14:13:41 -04:00
}
2015-04-01 07:20:55 -04:00
virtual bool Serialize ( FArchive & Ar ) override
2014-03-14 14:13:41 -04:00
{
bool bShaderHasOutdatedParameters = FGlobalShader : : Serialize ( Ar ) ;
Ar < < DeferredParameters ;
Ar < < ReflectionEnvironmentColorTexture ;
Ar < < ReflectionEnvironmentColorSampler ;
2014-04-30 14:14:19 -04:00
Ar < < ScreenSpaceReflections ;
Ar < < InSceneColor ;
Ar < < OutSceneColor ;
2014-03-14 14:13:41 -04:00
Ar < < NumCaptures ;
Ar < < ViewDimensionsParameter ;
Ar < < PreIntegratedGF ;
Ar < < PreIntegratedGFSampler ;
Ar < < SkyLightParameters ;
2014-08-28 13:54:31 -04:00
Ar < < SpecularOcclusionParameters ;
2014-03-14 14:13:41 -04:00
return bShaderHasOutdatedParameters ;
}
private :
FDeferredPixelShaderParameters DeferredParameters ;
FShaderResourceParameter ReflectionEnvironmentColorTexture ;
FShaderResourceParameter ReflectionEnvironmentColorSampler ;
2014-04-30 14:14:19 -04:00
FShaderResourceParameter ScreenSpaceReflections ;
FShaderResourceParameter InSceneColor ;
FRWShaderParameter OutSceneColor ;
2014-03-14 14:13:41 -04:00
FShaderParameter NumCaptures ;
FShaderParameter ViewDimensionsParameter ;
FShaderResourceParameter PreIntegratedGF ;
FShaderResourceParameter PreIntegratedGFSampler ;
FSkyLightReflectionParameters SkyLightParameters ;
2014-08-28 13:54:31 -04:00
FDistanceFieldAOSpecularOcclusionParameters SpecularOcclusionParameters ;
2014-03-14 14:13:41 -04:00
} ;
2015-04-08 16:15:25 -04:00
template < uint32 bUseLightmaps , uint32 bUseClearCoat , uint32 bBoxCapturesOnly , uint32 bSphereCapturesOnly >
2014-04-30 14:14:19 -04:00
class TReflectionEnvironmentTiledDeferredCS : public FReflectionEnvironmentTiledDeferredCS
{
DECLARE_SHADER_TYPE ( TReflectionEnvironmentTiledDeferredCS , Global ) ;
2014-03-14 14:13:41 -04:00
2014-04-30 14:14:19 -04:00
/** Default constructor. */
TReflectionEnvironmentTiledDeferredCS ( ) { }
public :
TReflectionEnvironmentTiledDeferredCS ( const ShaderMetaType : : CompiledShaderInitializerType & Initializer )
: FReflectionEnvironmentTiledDeferredCS ( Initializer )
{ }
2014-03-14 14:13:41 -04:00
2014-04-30 14:14:19 -04:00
static void ModifyCompilationEnvironment ( EShaderPlatform Platform , FShaderCompilerEnvironment & OutEnvironment )
{
FReflectionEnvironmentTiledDeferredCS : : ModifyCompilationEnvironment ( Platform , OutEnvironment ) ;
OutEnvironment . SetDefine ( TEXT ( " USE_LIGHTMAPS " ) , bUseLightmaps ) ;
2015-04-08 16:15:25 -04:00
OutEnvironment . SetDefine ( TEXT ( " USE_CLEARCOAT " ) , bUseClearCoat ) ;
OutEnvironment . SetDefine ( TEXT ( " HAS_BOX_CAPTURES " ) , bBoxCapturesOnly ) ;
OutEnvironment . SetDefine ( TEXT ( " HAS_SPHERE_CAPTURES " ) , bSphereCapturesOnly ) ;
2014-04-30 14:14:19 -04:00
}
} ;
2014-09-18 17:49:40 -04:00
// Typedef is necessary because the C preprocessor thinks the comma in the template parameter list is a comma in the macro parameter list.
2015-04-08 16:15:25 -04:00
# define IMPLEMENT_REFLECTION_COMPUTESHADER_TYPE(A, B, C, D) \
typedef TReflectionEnvironmentTiledDeferredCS < A , B , C , D > TReflectionEnvironmentTiledDeferredCS # # A # # B # # C # # D ; \
IMPLEMENT_SHADER_TYPE ( template < > , TReflectionEnvironmentTiledDeferredCS # # A # # B # # C # # D , TEXT ( " ReflectionEnvironmentComputeShaders " ) , TEXT ( " ReflectionEnvironmentTiledDeferredMain " ) , SF_Compute )
IMPLEMENT_REFLECTION_COMPUTESHADER_TYPE ( 0 , 0 , 0 , 0 ) ;
IMPLEMENT_REFLECTION_COMPUTESHADER_TYPE ( 0 , 0 , 0 , 1 ) ;
IMPLEMENT_REFLECTION_COMPUTESHADER_TYPE ( 0 , 0 , 1 , 0 ) ;
IMPLEMENT_REFLECTION_COMPUTESHADER_TYPE ( 0 , 0 , 1 , 1 ) ;
IMPLEMENT_REFLECTION_COMPUTESHADER_TYPE ( 0 , 1 , 0 , 0 ) ;
IMPLEMENT_REFLECTION_COMPUTESHADER_TYPE ( 0 , 1 , 0 , 1 ) ;
IMPLEMENT_REFLECTION_COMPUTESHADER_TYPE ( 0 , 1 , 1 , 0 ) ;
IMPLEMENT_REFLECTION_COMPUTESHADER_TYPE ( 0 , 1 , 1 , 1 ) ;
IMPLEMENT_REFLECTION_COMPUTESHADER_TYPE ( 1 , 0 , 0 , 0 ) ;
IMPLEMENT_REFLECTION_COMPUTESHADER_TYPE ( 1 , 0 , 0 , 1 ) ;
IMPLEMENT_REFLECTION_COMPUTESHADER_TYPE ( 1 , 0 , 1 , 0 ) ;
IMPLEMENT_REFLECTION_COMPUTESHADER_TYPE ( 1 , 0 , 1 , 1 ) ;
IMPLEMENT_REFLECTION_COMPUTESHADER_TYPE ( 1 , 1 , 0 , 0 ) ;
IMPLEMENT_REFLECTION_COMPUTESHADER_TYPE ( 1 , 1 , 0 , 1 ) ;
IMPLEMENT_REFLECTION_COMPUTESHADER_TYPE ( 1 , 1 , 1 , 0 ) ;
IMPLEMENT_REFLECTION_COMPUTESHADER_TYPE ( 1 , 1 , 1 , 1 ) ;
2014-09-18 17:49:40 -04:00
2014-04-30 14:14:19 -04:00
template < uint32 bSSR , uint32 bReflectionEnv , uint32 bSkylight >
2014-03-14 14:13:41 -04:00
class FReflectionApplyPS : public FGlobalShader
{
DECLARE_SHADER_TYPE ( FReflectionApplyPS , Global ) ;
2014-08-28 13:54:31 -04:00
public :
2014-03-14 14:13:41 -04:00
static bool ShouldCache ( EShaderPlatform Platform )
{
return IsFeatureLevelSupported ( Platform , ERHIFeatureLevel : : SM4 ) ;
}
2014-04-30 14:14:19 -04:00
static void ModifyCompilationEnvironment ( EShaderPlatform Platform , FShaderCompilerEnvironment & OutEnvironment )
{
FGlobalShader : : ModifyCompilationEnvironment ( Platform , OutEnvironment ) ;
OutEnvironment . SetDefine ( TEXT ( " APPLY_SSR " ) , bSSR ) ;
OutEnvironment . SetDefine ( TEXT ( " APPLY_REFLECTION_ENV " ) , bReflectionEnv ) ;
OutEnvironment . SetDefine ( TEXT ( " APPLY_SKYLIGHT " ) , bSkylight ) ;
}
2014-03-14 14:13:41 -04:00
/** Default constructor. */
FReflectionApplyPS ( ) { }
/** Initialization constructor. */
FReflectionApplyPS ( const ShaderMetaType : : CompiledShaderInitializerType & Initializer )
: FGlobalShader ( Initializer )
{
DeferredParameters . Bind ( Initializer . ParameterMap ) ;
2014-04-30 14:14:19 -04:00
SkyLightParameters . Bind ( Initializer . ParameterMap ) ;
2014-03-14 14:13:41 -04:00
ReflectionEnvTexture . Bind ( Initializer . ParameterMap , TEXT ( " ReflectionEnvTexture " ) ) ;
ReflectionEnvSampler . Bind ( Initializer . ParameterMap , TEXT ( " ReflectionEnvSampler " ) ) ;
ScreenSpaceReflectionsTexture . Bind ( Initializer . ParameterMap , TEXT ( " ScreenSpaceReflectionsTexture " ) ) ;
ScreenSpaceReflectionsSampler . Bind ( Initializer . ParameterMap , TEXT ( " ScreenSpaceReflectionsSampler " ) ) ;
PreIntegratedGF . Bind ( Initializer . ParameterMap , TEXT ( " PreIntegratedGF " ) ) ;
PreIntegratedGFSampler . Bind ( Initializer . ParameterMap , TEXT ( " PreIntegratedGFSampler " ) ) ;
2014-08-28 13:54:31 -04:00
SpecularOcclusionParameters . Bind ( Initializer . ParameterMap ) ;
2014-03-14 14:13:41 -04:00
}
2014-08-28 13:54:31 -04:00
void SetParameters ( FRHICommandList & RHICmdList , const FSceneView & View , FTextureRHIParamRef ReflectionEnv , FTextureRHIParamRef ScreenSpaceReflections , const TRefCountPtr < IPooledRenderTarget > & DynamicBentNormalAO )
2014-03-14 14:13:41 -04:00
{
const FPixelShaderRHIParamRef ShaderRHI = GetPixelShader ( ) ;
2014-06-05 16:38:54 -04:00
FGlobalShader : : SetParameters ( RHICmdList , ShaderRHI , View ) ;
DeferredParameters . Set ( RHICmdList , ShaderRHI , View ) ;
SkyLightParameters . SetParameters ( RHICmdList , ShaderRHI , ( FScene * ) View . Family - > Scene , true ) ;
2014-03-14 14:13:41 -04:00
2014-06-05 16:38:54 -04:00
SetTextureParameter ( RHICmdList , ShaderRHI , ReflectionEnvTexture , ReflectionEnvSampler , TStaticSamplerState < SF_Point > : : GetRHI ( ) , ReflectionEnv ) ;
SetTextureParameter ( RHICmdList , ShaderRHI , ScreenSpaceReflectionsTexture , ScreenSpaceReflectionsSampler , TStaticSamplerState < SF_Point > : : GetRHI ( ) , ScreenSpaceReflections ) ;
SetTextureParameter ( RHICmdList , ShaderRHI , PreIntegratedGF , PreIntegratedGFSampler , TStaticSamplerState < SF_Bilinear , AM_Clamp , AM_Clamp , AM_Clamp > : : GetRHI ( ) , GSystemTextures . PreintegratedGF - > GetRenderTargetItem ( ) . ShaderResourceTexture ) ;
2014-08-28 13:54:31 -04:00
2015-02-19 16:22:43 -05:00
FScene * Scene = ( FScene * ) View . Family - > Scene ;
const float MinOcclusion = Scene - > SkyLight ? Scene - > SkyLight - > MinOcclusion : 0 ;
SpecularOcclusionParameters . SetParameters ( RHICmdList , ShaderRHI , DynamicBentNormalAO , CVarSkySpecularOcclusionStrength . GetValueOnRenderThread ( ) , MinOcclusion ) ;
2014-03-14 14:13:41 -04:00
}
// FShader interface.
2015-04-01 07:20:55 -04:00
virtual bool Serialize ( FArchive & Ar ) override
2014-03-14 14:13:41 -04:00
{
bool bShaderHasOutdatedParameters = FGlobalShader : : Serialize ( Ar ) ;
Ar < < DeferredParameters ;
2014-04-30 14:14:19 -04:00
Ar < < SkyLightParameters ;
2014-03-14 14:13:41 -04:00
Ar < < ReflectionEnvTexture ;
Ar < < ReflectionEnvSampler ;
Ar < < ScreenSpaceReflectionsTexture ;
Ar < < ScreenSpaceReflectionsSampler ;
Ar < < PreIntegratedGF ;
Ar < < PreIntegratedGFSampler ;
2014-08-28 13:54:31 -04:00
Ar < < SpecularOcclusionParameters ;
2014-03-14 14:13:41 -04:00
return bShaderHasOutdatedParameters ;
}
2014-08-28 13:54:31 -04:00
private :
FDeferredPixelShaderParameters DeferredParameters ;
FSkyLightReflectionParameters SkyLightParameters ;
FShaderResourceParameter ReflectionEnvTexture ;
FShaderResourceParameter ReflectionEnvSampler ;
FShaderResourceParameter ScreenSpaceReflectionsTexture ;
FShaderResourceParameter ScreenSpaceReflectionsSampler ;
FShaderResourceParameter PreIntegratedGF ;
FShaderResourceParameter PreIntegratedGFSampler ;
FDistanceFieldAOSpecularOcclusionParameters SpecularOcclusionParameters ;
2014-03-14 14:13:41 -04:00
} ;
2014-04-30 14:14:19 -04:00
// Typedef is necessary because the C preprocessor thinks the comma in the template parameter list is a comma in the macro parameter list.
# define IMPLEMENT_REFLECTION_APPLY_PIXELSHADER_TYPE(A, B, C) \
typedef FReflectionApplyPS < A , B , C > FReflectionApplyPS # # A # # B # # C ; \
IMPLEMENT_SHADER_TYPE ( template < > , FReflectionApplyPS # # A # # B # # C , TEXT ( " ReflectionEnvironmentShaders " ) , TEXT ( " ReflectionApplyPS " ) , SF_Pixel ) ;
IMPLEMENT_REFLECTION_APPLY_PIXELSHADER_TYPE ( 0 , 0 , 0 ) ;
IMPLEMENT_REFLECTION_APPLY_PIXELSHADER_TYPE ( 0 , 0 , 1 ) ;
IMPLEMENT_REFLECTION_APPLY_PIXELSHADER_TYPE ( 0 , 1 , 0 ) ;
IMPLEMENT_REFLECTION_APPLY_PIXELSHADER_TYPE ( 0 , 1 , 1 ) ;
IMPLEMENT_REFLECTION_APPLY_PIXELSHADER_TYPE ( 1 , 0 , 0 ) ;
IMPLEMENT_REFLECTION_APPLY_PIXELSHADER_TYPE ( 1 , 0 , 1 ) ;
IMPLEMENT_REFLECTION_APPLY_PIXELSHADER_TYPE ( 1 , 1 , 0 ) ;
IMPLEMENT_REFLECTION_APPLY_PIXELSHADER_TYPE ( 1 , 1 , 1 ) ;
2014-03-14 14:13:41 -04:00
class FReflectionCaptureSpecularBouncePS : public FGlobalShader
{
DECLARE_SHADER_TYPE ( FReflectionCaptureSpecularBouncePS , Global ) ;
static bool ShouldCache ( EShaderPlatform Platform )
{
return IsFeatureLevelSupported ( Platform , ERHIFeatureLevel : : SM4 ) ;
}
2014-06-05 16:38:54 -04:00
static void ModifyCompilationEnvironment ( EShaderPlatform Platform , FShaderCompilerEnvironment & OutEnvironment )
{
FGlobalShader : : ModifyCompilationEnvironment ( Platform , OutEnvironment ) ;
}
2014-03-14 14:13:41 -04:00
/** Default constructor. */
FReflectionCaptureSpecularBouncePS ( ) { }
public :
FDeferredPixelShaderParameters DeferredParameters ;
/** Initialization constructor. */
FReflectionCaptureSpecularBouncePS ( const ShaderMetaType : : CompiledShaderInitializerType & Initializer )
: FGlobalShader ( Initializer )
{
DeferredParameters . Bind ( Initializer . ParameterMap ) ;
}
2014-06-10 07:29:49 -04:00
void SetParameters ( FRHICommandList & RHICmdList , const FSceneView & View )
2014-03-14 14:13:41 -04:00
{
const FPixelShaderRHIParamRef ShaderRHI = GetPixelShader ( ) ;
2014-06-05 16:38:54 -04:00
FGlobalShader : : SetParameters ( RHICmdList , ShaderRHI , View ) ;
2014-03-14 14:13:41 -04:00
2014-06-05 16:38:54 -04:00
DeferredParameters . Set ( RHICmdList , ShaderRHI , View ) ;
2014-03-14 14:13:41 -04:00
}
// FShader interface.
2015-04-01 07:20:55 -04:00
virtual bool Serialize ( FArchive & Ar ) override
2014-03-14 14:13:41 -04:00
{
bool bShaderHasOutdatedParameters = FGlobalShader : : Serialize ( Ar ) ;
Ar < < DeferredParameters ;
return bShaderHasOutdatedParameters ;
}
} ;
IMPLEMENT_SHADER_TYPE ( , FReflectionCaptureSpecularBouncePS , TEXT ( " ReflectionEnvironmentShaders " ) , TEXT ( " SpecularBouncePS " ) , SF_Pixel ) ;
template < bool bSphereCapture >
class TStandardDeferredReflectionPS : public FGlobalShader
{
DECLARE_SHADER_TYPE ( TStandardDeferredReflectionPS , Global ) ;
public :
static bool ShouldCache ( EShaderPlatform Platform )
{
return IsFeatureLevelSupported ( Platform , ERHIFeatureLevel : : SM4 ) ;
}
static void ModifyCompilationEnvironment ( EShaderPlatform Platform , FShaderCompilerEnvironment & OutEnvironment )
{
FGlobalShader : : ModifyCompilationEnvironment ( Platform , OutEnvironment ) ;
OutEnvironment . SetDefine ( TEXT ( " SPHERE_CAPTURE " ) , ( uint32 ) bSphereCapture ) ;
OutEnvironment . SetDefine ( TEXT ( " BOX_CAPTURE " ) , ( uint32 ) ! bSphereCapture ) ;
}
/** Default constructor. */
TStandardDeferredReflectionPS ( ) { }
/** Initialization constructor. */
TStandardDeferredReflectionPS ( const ShaderMetaType : : CompiledShaderInitializerType & Initializer )
: FGlobalShader ( Initializer )
{
CapturePositionAndRadius . Bind ( Initializer . ParameterMap , TEXT ( " CapturePositionAndRadius " ) ) ;
CaptureProperties . Bind ( Initializer . ParameterMap , TEXT ( " CaptureProperties " ) ) ;
CaptureBoxTransform . Bind ( Initializer . ParameterMap , TEXT ( " CaptureBoxTransform " ) ) ;
CaptureBoxScales . Bind ( Initializer . ParameterMap , TEXT ( " CaptureBoxScales " ) ) ;
2014-09-10 19:20:06 -04:00
CaptureArrayIndex . Bind ( Initializer . ParameterMap , TEXT ( " CaptureArrayIndex " ) ) ;
2014-03-14 14:13:41 -04:00
ReflectionEnvironmentColorTexture . Bind ( Initializer . ParameterMap , TEXT ( " ReflectionEnvironmentColorTexture " ) ) ;
2014-09-10 19:20:06 -04:00
ReflectionEnvironmentColorTextureArray . Bind ( Initializer . ParameterMap , TEXT ( " ReflectionEnvironmentColorTextureArray " ) ) ;
2014-03-14 14:13:41 -04:00
ReflectionEnvironmentColorSampler . Bind ( Initializer . ParameterMap , TEXT ( " ReflectionEnvironmentColorSampler " ) ) ;
DeferredParameters . Bind ( Initializer . ParameterMap ) ;
}
2014-06-10 07:29:49 -04:00
void SetParameters ( FRHICommandList & RHICmdList , const FSceneView & View , const FReflectionCaptureSortData & SortData )
2014-03-14 14:13:41 -04:00
{
const FPixelShaderRHIParamRef ShaderRHI = GetPixelShader ( ) ;
2014-06-05 16:38:54 -04:00
FGlobalShader : : SetParameters ( RHICmdList , ShaderRHI , View ) ;
2014-03-14 14:13:41 -04:00
2014-10-01 09:08:51 -04:00
if ( View . GetFeatureLevel ( ) > = ERHIFeatureLevel : : SM5 )
2014-09-10 19:20:06 -04:00
{
FScene * Scene = ( FScene * ) View . Family - > Scene ;
check ( Scene - > ReflectionSceneData . CubemapArray . IsValid ( ) ) ;
check ( Scene - > ReflectionSceneData . CubemapArray . GetRenderTarget ( ) . IsValid ( ) ) ;
FSceneRenderTargetItem & CubemapArray = Scene - > ReflectionSceneData . CubemapArray . GetRenderTarget ( ) ;
SetTextureParameter ( RHICmdList , ShaderRHI , ReflectionEnvironmentColorTextureArray , ReflectionEnvironmentColorSampler , TStaticSamplerState < SF_Trilinear , AM_Clamp , AM_Clamp , AM_Clamp > : : GetRHI ( ) , CubemapArray . ShaderResourceTexture ) ;
SetShaderValue ( RHICmdList , ShaderRHI , CaptureArrayIndex , SortData . CaptureIndex ) ;
}
else
{
2014-10-06 10:06:04 -04:00
SetTextureParameter ( RHICmdList , ShaderRHI , ReflectionEnvironmentColorTexture , ReflectionEnvironmentColorSampler , TStaticSamplerState < SF_Trilinear , AM_Clamp , AM_Clamp , AM_Clamp > : : GetRHI ( ) , SortData . SM4FullHDRCubemap - > TextureRHI ) ;
2014-09-10 19:20:06 -04:00
}
2014-03-14 14:13:41 -04:00
2014-06-05 16:38:54 -04:00
DeferredParameters . Set ( RHICmdList , ShaderRHI , View ) ;
SetShaderValue ( RHICmdList , ShaderRHI , CapturePositionAndRadius , SortData . PositionAndRadius ) ;
SetShaderValue ( RHICmdList , ShaderRHI , CaptureProperties , SortData . CaptureProperties ) ;
SetShaderValue ( RHICmdList , ShaderRHI , CaptureBoxTransform , SortData . BoxTransform ) ;
SetShaderValue ( RHICmdList , ShaderRHI , CaptureBoxScales , SortData . BoxScales ) ;
2014-03-14 14:13:41 -04:00
}
// FShader interface.
2015-04-01 07:20:55 -04:00
virtual bool Serialize ( FArchive & Ar ) override
2014-03-14 14:13:41 -04:00
{
bool bShaderHasOutdatedParameters = FGlobalShader : : Serialize ( Ar ) ;
Ar < < CapturePositionAndRadius ;
Ar < < CaptureProperties ;
Ar < < CaptureBoxTransform ;
Ar < < CaptureBoxScales ;
2014-09-10 19:20:06 -04:00
Ar < < CaptureArrayIndex ;
2014-03-14 14:13:41 -04:00
Ar < < ReflectionEnvironmentColorTexture ;
2014-09-10 19:20:06 -04:00
Ar < < ReflectionEnvironmentColorTextureArray ;
2014-03-14 14:13:41 -04:00
Ar < < ReflectionEnvironmentColorSampler ;
Ar < < DeferredParameters ;
return bShaderHasOutdatedParameters ;
}
private :
FShaderParameter CapturePositionAndRadius ;
FShaderParameter CaptureProperties ;
FShaderParameter CaptureBoxTransform ;
FShaderParameter CaptureBoxScales ;
2014-09-10 19:20:06 -04:00
FShaderParameter CaptureArrayIndex ;
2014-03-14 14:13:41 -04:00
FShaderResourceParameter ReflectionEnvironmentColorTexture ;
2014-09-10 19:20:06 -04:00
FShaderResourceParameter ReflectionEnvironmentColorTextureArray ;
2014-03-14 14:13:41 -04:00
FShaderResourceParameter ReflectionEnvironmentColorSampler ;
FDeferredPixelShaderParameters DeferredParameters ;
} ;
IMPLEMENT_SHADER_TYPE ( template < > , TStandardDeferredReflectionPS < true > , TEXT ( " ReflectionEnvironmentShaders " ) , TEXT ( " StandardDeferredReflectionPS " ) , SF_Pixel ) ;
IMPLEMENT_SHADER_TYPE ( template < > , TStandardDeferredReflectionPS < false > , TEXT ( " ReflectionEnvironmentShaders " ) , TEXT ( " StandardDeferredReflectionPS " ) , SF_Pixel ) ;
2014-06-27 11:07:13 -04:00
void FDeferredShadingSceneRenderer : : RenderReflectionCaptureSpecularBounceForAllViews ( FRHICommandListImmediate & RHICmdList )
2014-06-05 16:38:54 -04:00
{
2015-04-08 15:33:28 -04:00
GSceneRenderTargets . BeginRenderingSceneColor ( RHICmdList , ESimpleRenderTargetMode : : EUninitializedColorExistingDepth , FExclusiveDepthStencil : : DepthRead_StencilWrite ) ;
2014-06-12 07:13:34 -04:00
RHICmdList . SetRasterizerState ( TStaticRasterizerState < FM_Solid , CM_None > : : GetRHI ( ) ) ;
RHICmdList . SetDepthStencilState ( TStaticDepthStencilState < false , CF_Always > : : GetRHI ( ) ) ;
RHICmdList . SetBlendState ( TStaticBlendState < CW_RGB , BO_Add , BF_One , BF_One > : : GetRHI ( ) ) ;
2014-03-14 14:13:41 -04:00
2014-08-28 06:22:54 -04:00
auto ShaderMap = GetGlobalShaderMap ( FeatureLevel ) ;
TShaderMapRef < FPostProcessVS > VertexShader ( ShaderMap ) ;
TShaderMapRef < FReflectionCaptureSpecularBouncePS > PixelShader ( ShaderMap ) ;
2014-03-14 14:13:41 -04:00
2014-05-08 16:17:53 -04:00
static FGlobalBoundShaderState BoundShaderState ;
2014-06-27 11:07:13 -04:00
2014-08-19 10:41:34 -04:00
SetGlobalBoundShaderState ( RHICmdList , FeatureLevel , BoundShaderState , GFilterVertexDeclaration . VertexDeclarationRHI , * VertexShader , * PixelShader ) ;
2014-05-08 16:17:53 -04:00
for ( int32 ViewIndex = 0 , Num = Views . Num ( ) ; ViewIndex < Num ; ViewIndex + + )
2014-04-30 14:14:19 -04:00
{
const FViewInfo & View = Views [ ViewIndex ] ;
2014-06-12 07:13:34 -04:00
RHICmdList . SetViewport ( View . ViewRect . Min . X , View . ViewRect . Min . Y , 0.0f , View . ViewRect . Max . X , View . ViewRect . Max . Y , 1.0f ) ;
2014-05-08 16:17:53 -04:00
2014-06-27 11:07:13 -04:00
2014-06-12 07:13:34 -04:00
PixelShader - > SetParameters ( RHICmdList , View ) ;
2014-05-08 16:17:53 -04:00
DrawRectangle (
2014-06-12 07:13:34 -04:00
RHICmdList ,
2014-06-05 16:38:54 -04:00
0 , 0 ,
2014-05-08 16:17:53 -04:00
View . ViewRect . Width ( ) , View . ViewRect . Height ( ) ,
2014-06-05 16:38:54 -04:00
0 , 0 ,
2014-05-08 16:17:53 -04:00
View . ViewRect . Width ( ) , View . ViewRect . Height ( ) ,
FIntPoint ( View . ViewRect . Width ( ) , View . ViewRect . Height ( ) ) ,
GSceneRenderTargets . GetBufferSizeXY ( ) ,
* VertexShader ,
EDRF_UseTriangleOptimization ) ;
}
2015-01-27 16:14:50 -05:00
GSceneRenderTargets . FinishRenderingSceneColor ( RHICmdList ) ;
2014-05-08 16:17:53 -04:00
}
bool FDeferredShadingSceneRenderer : : ShouldDoReflectionEnvironment ( ) const
{
2014-05-08 09:05:50 -04:00
const ERHIFeatureLevel : : Type FeatureLevel = Scene - > GetFeatureLevel ( ) ;
2014-05-08 16:17:53 -04:00
return IsReflectionEnvironmentAvailable ( FeatureLevel )
2014-04-30 14:14:19 -04:00
& & Scene - > ReflectionSceneData . RegisteredReflectionCaptures . Num ( )
2014-09-10 20:40:27 -04:00
& & ViewFamily . EngineShowFlags . ReflectionEnvironment
& & ( FeatureLevel = = ERHIFeatureLevel : : SM4 | | Scene - > ReflectionSceneData . CubemapArray . IsValid ( ) ) ;
2014-05-08 16:17:53 -04:00
}
2014-04-30 14:14:19 -04:00
2015-04-08 16:15:25 -04:00
void GatherAndSortReflectionCaptures ( const FScene * Scene , TArray < FReflectionCaptureSortData > & OutSortData , int32 & OutNumBoxCaptures , int32 & OutNumSphereCaptures )
{
OutSortData . Reset ( Scene - > ReflectionSceneData . RegisteredReflectionCaptures . Num ( ) ) ;
OutNumBoxCaptures = 0 ;
OutNumSphereCaptures = 0 ;
const int32 MaxCubemaps = Scene - > ReflectionSceneData . CubemapArray . GetMaxCubemaps ( ) ;
// Pack only visible reflection captures into the uniform buffer, each with an index to its cubemap array entry
for ( int32 ReflectionProxyIndex = 0 ; ReflectionProxyIndex < Scene - > ReflectionSceneData . RegisteredReflectionCaptures . Num ( ) & & OutSortData . Num ( ) < GMaxNumReflectionCaptures ; ReflectionProxyIndex + + )
{
FReflectionCaptureProxy * CurrentCapture = Scene - > ReflectionSceneData . RegisteredReflectionCaptures [ ReflectionProxyIndex ] ;
// Find the cubemap index this component was allocated with
const FCaptureComponentSceneState * ComponentStatePtr = Scene - > ReflectionSceneData . AllocatedReflectionCaptureState . Find ( CurrentCapture - > Component ) ;
if ( ComponentStatePtr )
{
int32 CubemapIndex = ComponentStatePtr - > CaptureIndex ;
check ( CubemapIndex < MaxCubemaps ) ;
FReflectionCaptureSortData NewSortEntry ;
NewSortEntry . CaptureIndex = CubemapIndex ;
NewSortEntry . SM4FullHDRCubemap = NULL ;
NewSortEntry . Guid = CurrentCapture - > Guid ;
NewSortEntry . PositionAndRadius = FVector4 ( CurrentCapture - > Position , CurrentCapture - > InfluenceRadius ) ;
float ShapeTypeValue = ( float ) CurrentCapture - > Shape ;
NewSortEntry . CaptureProperties = FVector4 ( CurrentCapture - > Brightness , CubemapIndex , ShapeTypeValue , 0 ) ;
if ( CurrentCapture - > Shape = = EReflectionCaptureShape : : Plane )
{
//planes count as boxes in the compute shader.
+ + OutNumBoxCaptures ;
NewSortEntry . BoxTransform = FMatrix (
FPlane ( CurrentCapture - > ReflectionPlane ) ,
FPlane ( CurrentCapture - > ReflectionXAxisAndYScale ) ,
FPlane ( 0 , 0 , 0 , 0 ) ,
FPlane ( 0 , 0 , 0 , 0 ) ) ;
NewSortEntry . BoxScales = FVector4 ( 0 ) ;
}
else if ( CurrentCapture - > Shape = = EReflectionCaptureShape : : Sphere )
{
+ + OutNumSphereCaptures ;
}
else
{
+ + OutNumBoxCaptures ;
NewSortEntry . BoxTransform = CurrentCapture - > BoxTransform ;
NewSortEntry . BoxScales = FVector4 ( CurrentCapture - > BoxScales , CurrentCapture - > BoxTransitionDistance ) ;
}
OutSortData . Add ( NewSortEntry ) ;
}
}
OutSortData . Sort ( ) ;
}
FReflectionEnvironmentTiledDeferredCS * SelectReflectionEnvironmentTiledDeferredCS ( TShaderMap < FGlobalShaderType > * ShaderMap , bool bUseLightmaps , bool bUseClearCoat , bool bHasBoxCaptures , bool bHasSphereCaptures )
{
FReflectionEnvironmentTiledDeferredCS * ComputeShader = nullptr ;
if ( bUseLightmaps )
{
if ( bUseClearCoat )
{
if ( bHasBoxCaptures & & bHasSphereCaptures )
{
ComputeShader = * TShaderMapRef < TReflectionEnvironmentTiledDeferredCS < 1 , 1 , 1 , 1 > > ( ShaderMap ) ;
}
else if ( bHasBoxCaptures )
{
ComputeShader = * TShaderMapRef < TReflectionEnvironmentTiledDeferredCS < 1 , 1 , 1 , 0 > > ( ShaderMap ) ;
}
else if ( bHasSphereCaptures )
{
ComputeShader = * TShaderMapRef < TReflectionEnvironmentTiledDeferredCS < 1 , 1 , 0 , 1 > > ( ShaderMap ) ;
}
else
{
ComputeShader = * TShaderMapRef < TReflectionEnvironmentTiledDeferredCS < 1 , 1 , 0 , 0 > > ( ShaderMap ) ;
}
}
else
{
if ( bHasBoxCaptures & & bHasSphereCaptures )
{
ComputeShader = * TShaderMapRef < TReflectionEnvironmentTiledDeferredCS < 1 , 0 , 1 , 1 > > ( ShaderMap ) ;
}
else if ( bHasBoxCaptures )
{
ComputeShader = * TShaderMapRef < TReflectionEnvironmentTiledDeferredCS < 1 , 0 , 1 , 0 > > ( ShaderMap ) ;
}
else if ( bHasSphereCaptures )
{
ComputeShader = * TShaderMapRef < TReflectionEnvironmentTiledDeferredCS < 1 , 0 , 0 , 1 > > ( ShaderMap ) ;
}
else
{
ComputeShader = * TShaderMapRef < TReflectionEnvironmentTiledDeferredCS < 1 , 0 , 0 , 0 > > ( ShaderMap ) ;
}
}
}
else
{
if ( bUseClearCoat )
{
if ( bHasBoxCaptures & & bHasSphereCaptures )
{
ComputeShader = * TShaderMapRef < TReflectionEnvironmentTiledDeferredCS < 0 , 1 , 1 , 1 > > ( ShaderMap ) ;
}
else if ( bHasBoxCaptures )
{
ComputeShader = * TShaderMapRef < TReflectionEnvironmentTiledDeferredCS < 0 , 1 , 1 , 0 > > ( ShaderMap ) ;
}
else if ( bHasSphereCaptures )
{
ComputeShader = * TShaderMapRef < TReflectionEnvironmentTiledDeferredCS < 0 , 1 , 0 , 1 > > ( ShaderMap ) ;
}
else
{
ComputeShader = * TShaderMapRef < TReflectionEnvironmentTiledDeferredCS < 0 , 1 , 0 , 0 > > ( ShaderMap ) ;
}
}
else
{
if ( bHasBoxCaptures & & bHasSphereCaptures )
{
ComputeShader = * TShaderMapRef < TReflectionEnvironmentTiledDeferredCS < 0 , 0 , 1 , 1 > > ( ShaderMap ) ;
}
else if ( bHasBoxCaptures )
{
ComputeShader = * TShaderMapRef < TReflectionEnvironmentTiledDeferredCS < 0 , 0 , 1 , 0 > > ( ShaderMap ) ;
}
else if ( bHasSphereCaptures )
{
ComputeShader = * TShaderMapRef < TReflectionEnvironmentTiledDeferredCS < 0 , 0 , 0 , 1 > > ( ShaderMap ) ;
}
else
{
ComputeShader = * TShaderMapRef < TReflectionEnvironmentTiledDeferredCS < 0 , 0 , 0 , 0 > > ( ShaderMap ) ;
}
}
}
check ( ComputeShader ) ;
return ComputeShader ;
}
2014-09-10 19:20:06 -04:00
void FDeferredShadingSceneRenderer : : RenderTiledDeferredImageBasedReflections ( FRHICommandListImmediate & RHICmdList , const TRefCountPtr < IPooledRenderTarget > & DynamicBentNormalAO )
2014-05-08 16:17:53 -04:00
{
2015-04-08 16:15:25 -04:00
const bool bUseLightmaps = CVarDiffuseFromCaptures . GetValueOnRenderThread ( ) = = 0 ;
2014-09-18 17:49:40 -04:00
const uint32 bHalfRes = CVarHalfResReflections . GetValueOnRenderThread ( ) ! = 0 ;
2014-04-30 14:14:19 -04:00
2014-05-08 16:17:53 -04:00
TRefCountPtr < IPooledRenderTarget > NewSceneColor ;
2014-04-30 14:14:19 -04:00
{
2014-06-27 11:07:13 -04:00
GSceneRenderTargets . ResolveSceneColor ( RHICmdList , FResolveRect ( 0 , 0 , ViewFamily . FamilySizeX , ViewFamily . FamilySizeY ) ) ;
2014-04-30 14:14:19 -04:00
2014-05-06 11:27:50 -04:00
FPooledRenderTargetDesc Desc = GSceneRenderTargets . GetSceneColor ( ) - > GetDesc ( ) ;
2014-05-06 17:45:03 -04:00
Desc . TargetableFlags | = TexCreate_UAV ;
2014-04-30 14:14:19 -04:00
2014-07-02 16:54:50 -04:00
// we don't create a new name to make it easier to use "vis SceneColor" and get the last HDRSceneColor
GRenderTargetPool . FindFreeElement ( Desc , NewSceneColor , TEXT ( " SceneColor " ) ) ;
2014-04-30 14:14:19 -04:00
}
2014-08-28 13:54:31 -04:00
// If we are in SM5, use the compute shader gather method
2014-05-08 16:17:53 -04:00
for ( int32 ViewIndex = 0 , Num = Views . Num ( ) ; ViewIndex < Num ; ViewIndex + + )
2014-04-30 14:14:19 -04:00
{
2014-08-12 18:24:52 -04:00
FViewInfo & View = Views [ ViewIndex ] ;
2014-04-30 14:14:19 -04:00
2014-05-08 16:17:53 -04:00
const uint32 bSSR = DoScreenSpaceReflections ( Views [ ViewIndex ] ) ;
TRefCountPtr < IPooledRenderTarget > SSROutput = GSystemTextures . BlackDummy ;
if ( bSSR )
2014-03-14 14:13:41 -04:00
{
2014-06-27 11:07:13 -04:00
ScreenSpaceReflections ( RHICmdList , View , SSROutput ) ;
2014-04-30 14:14:19 -04:00
}
2014-05-08 16:17:53 -04:00
2014-05-09 18:13:51 -04:00
// ReflectionEnv is assumed to be on when going into this method
2014-04-30 14:14:19 -04:00
{
2014-05-08 16:17:53 -04:00
// Render the reflection environment with tiled deferred culling
2014-10-20 10:43:43 -04:00
SCOPED_DRAW_EVENT ( RHICmdList , ReflectionEnvironmentGather ) ;
2014-04-30 14:14:19 -04:00
2014-06-12 07:13:34 -04:00
SetRenderTarget ( RHICmdList , NULL , NULL ) ;
2014-04-30 14:14:19 -04:00
2014-05-08 16:17:53 -04:00
FReflectionEnvironmentTiledDeferredCS * ComputeShader = NULL ;
2014-09-18 17:49:40 -04:00
uint32 AdjustedReflectionTileSizeX = GReflectionEnvironmentTileSizeX ;
2015-04-08 16:15:25 -04:00
if ( bHalfRes )
2014-03-14 14:13:41 -04:00
{
2014-09-18 17:49:40 -04:00
AdjustedReflectionTileSizeX * = 2 ;
2014-05-08 16:17:53 -04:00
}
2015-04-08 16:15:25 -04:00
TArray < FReflectionCaptureSortData > SortData ;
int32 NumBoxCaptures = 0 ;
int32 NumSphereCaptures = 0 ;
GatherAndSortReflectionCaptures ( Scene , SortData , NumBoxCaptures , NumSphereCaptures ) ;
bool bHasBoxCaptures = ( NumBoxCaptures > 0 ) ;
bool bHasSphereCaptures = ( NumSphereCaptures > 0 ) ;
2015-04-13 17:01:36 -04:00
bool bNeedsClearCoat = ( View . ShadingModelMaskInView & ( 1 < < MSM_ClearCoat ) ) ! = 0 ;
2015-04-08 16:15:25 -04:00
ComputeShader = SelectReflectionEnvironmentTiledDeferredCS ( View . ShaderMap , bUseLightmaps , bNeedsClearCoat , bHasBoxCaptures , bHasSphereCaptures ) ;
2014-03-14 14:13:41 -04:00
2014-06-12 07:13:34 -04:00
RHICmdList . SetComputeShader ( ComputeShader - > GetComputeShader ( ) ) ;
2014-05-08 16:17:53 -04:00
2015-04-08 16:15:25 -04:00
ComputeShader - > SetParameters ( RHICmdList , View , SSROutput - > GetRenderTargetItem ( ) . ShaderResourceTexture , SortData , NewSceneColor - > GetRenderTargetItem ( ) . UAV , DynamicBentNormalAO ) ;
2014-05-08 16:17:53 -04:00
2014-09-18 17:49:40 -04:00
uint32 GroupSizeX = ( View . ViewRect . Size ( ) . X + AdjustedReflectionTileSizeX - 1 ) / AdjustedReflectionTileSizeX ;
2014-05-08 16:17:53 -04:00
uint32 GroupSizeY = ( View . ViewRect . Size ( ) . Y + GReflectionEnvironmentTileSizeY - 1 ) / GReflectionEnvironmentTileSizeY ;
2014-06-05 16:38:54 -04:00
DispatchComputeShader ( RHICmdList , ComputeShader , GroupSizeX , GroupSizeY , 1 ) ;
2014-05-08 16:17:53 -04:00
2014-06-12 07:13:34 -04:00
ComputeShader - > UnsetParameters ( RHICmdList ) ;
2014-05-08 16:17:53 -04:00
}
}
GSceneRenderTargets . SetSceneColor ( NewSceneColor ) ;
check ( GSceneRenderTargets . GetSceneColor ( ) ) ;
}
2014-09-10 19:20:06 -04:00
void FDeferredShadingSceneRenderer : : RenderStandardDeferredImageBasedReflections ( FRHICommandListImmediate & RHICmdList , bool bReflectionEnv , const TRefCountPtr < IPooledRenderTarget > & DynamicBentNormalAO )
2014-05-08 16:17:53 -04:00
{
const bool bSkyLight = Scene - > SkyLight
& & Scene - > SkyLight - > ProcessedTexture
& & ViewFamily . EngineShowFlags . SkyLighting ;
2014-05-09 18:13:51 -04:00
static TArray < FReflectionCaptureSortData > SortData ;
2014-06-05 16:38:54 -04:00
if ( bReflectionEnv )
2014-05-09 18:13:51 -04:00
{
2014-05-09 18:14:03 -04:00
// shared for multiple views
2014-05-09 18:13:51 -04:00
SortData . Reset ( Scene - > ReflectionSceneData . RegisteredReflectionCaptures . Num ( ) ) ;
// Gather visible reflection capture data
for ( int32 ReflectionProxyIndex = 0 ; ReflectionProxyIndex < Scene - > ReflectionSceneData . RegisteredReflectionCaptures . Num ( ) & & SortData . Num ( ) < GMaxNumReflectionCaptures ; ReflectionProxyIndex + + )
{
FReflectionCaptureProxy * CurrentCapture = Scene - > ReflectionSceneData . RegisteredReflectionCaptures [ ReflectionProxyIndex ] ;
FReflectionCaptureSortData NewSortEntry ;
2014-09-10 19:20:06 -04:00
NewSortEntry . CaptureIndex = - 1 ;
2014-10-01 09:08:51 -04:00
if ( FeatureLevel > = ERHIFeatureLevel : : SM5 )
2014-09-10 19:20:06 -04:00
{
const FCaptureComponentSceneState * ComponentStatePtr = Scene - > ReflectionSceneData . AllocatedReflectionCaptureState . Find ( CurrentCapture - > Component ) ;
NewSortEntry . CaptureIndex = ComponentStatePtr ? ComponentStatePtr - > CaptureIndex : - 1 ;
}
2014-05-09 18:13:51 -04:00
NewSortEntry . SM4FullHDRCubemap = CurrentCapture - > SM4FullHDRCubemap ;
NewSortEntry . Guid = CurrentCapture - > Guid ;
NewSortEntry . PositionAndRadius = FVector4 ( CurrentCapture - > Position , CurrentCapture - > InfluenceRadius ) ;
float ShapeTypeValue = ( float ) CurrentCapture - > Shape ;
NewSortEntry . CaptureProperties = FVector4 ( CurrentCapture - > Brightness , 0 , ShapeTypeValue , 0 ) ;
if ( CurrentCapture - > Shape = = EReflectionCaptureShape : : Plane )
{
NewSortEntry . BoxTransform = FMatrix (
2014-06-05 16:38:54 -04:00
FPlane ( CurrentCapture - > ReflectionPlane ) ,
FPlane ( CurrentCapture - > ReflectionXAxisAndYScale ) ,
FPlane ( 0 , 0 , 0 , 0 ) ,
2014-05-09 18:13:51 -04:00
FPlane ( 0 , 0 , 0 , 0 ) ) ;
NewSortEntry . BoxScales = FVector4 ( 0 ) ;
}
else
{
NewSortEntry . BoxTransform = CurrentCapture - > BoxTransform ;
NewSortEntry . BoxScales = FVector4 ( CurrentCapture - > BoxScales , CurrentCapture - > BoxTransitionDistance ) ;
}
SortData . Add ( NewSortEntry ) ;
}
SortData . Sort ( ) ;
}
2014-09-10 19:20:06 -04:00
// Use standard deferred shading to composite reflection capture contribution
2014-05-08 16:17:53 -04:00
for ( int32 ViewIndex = 0 , Num = Views . Num ( ) ; ViewIndex < Num ; ViewIndex + + )
{
2014-08-12 18:24:52 -04:00
FViewInfo & View = Views [ ViewIndex ] ;
2014-05-08 16:17:53 -04:00
bool bRequiresApply = bSkyLight ;
const bool bSSR = DoScreenSpaceReflections ( View ) ;
TRefCountPtr < IPooledRenderTarget > SSROutput = GSystemTextures . BlackDummy ;
2014-06-05 16:38:54 -04:00
if ( bSSR )
2014-05-08 16:17:53 -04:00
{
bRequiresApply = true ;
2014-05-09 18:14:03 -04:00
2014-06-27 11:07:13 -04:00
ScreenSpaceReflections ( RHICmdList , View , SSROutput ) ;
2014-05-08 16:17:53 -04:00
}
2014-07-02 16:54:50 -04:00
TRefCountPtr < IPooledRenderTarget > LightAccumulation ;
2014-06-05 16:38:54 -04:00
if ( bReflectionEnv )
2014-05-08 16:17:53 -04:00
{
bRequiresApply = true ;
2014-10-20 10:43:43 -04:00
SCOPED_DRAW_EVENT ( RHICmdList , StandardDeferredReflectionEnvironment ) ;
2014-05-08 16:17:53 -04:00
2014-07-02 16:54:50 -04:00
{
FPooledRenderTargetDesc Desc = GSceneRenderTargets . GetSceneColor ( ) - > GetDesc ( ) ;
2014-08-28 13:54:31 -04:00
// Make sure we get an alpha channel
Desc . Format = PF_FloatRGBA ;
2014-07-02 16:54:50 -04:00
GRenderTargetPool . FindFreeElement ( Desc , LightAccumulation , TEXT ( " LightAccumulation " ) ) ;
}
2014-05-08 16:17:53 -04:00
// Clear to no reflection contribution, alpha of 1 indicates full background contribution
2015-03-19 14:09:16 -04:00
SetRenderTarget ( RHICmdList , LightAccumulation - > GetRenderTargetItem ( ) . TargetableTexture , NULL , ESimpleRenderTargetMode : : EClearColorToBlackWithFullAlpha ) ;
2014-05-08 16:17:53 -04:00
2014-06-12 07:13:34 -04:00
RHICmdList . SetViewport ( View . ViewRect . Min . X , View . ViewRect . Min . Y , 0.0f , View . ViewRect . Max . X , View . ViewRect . Max . Y , 1.0f ) ;
2014-05-08 16:17:53 -04:00
// rgb accumulates reflection contribution front to back, alpha accumulates (1 - alpha0) * (1 - alpha 1)...
2014-06-12 07:13:34 -04:00
RHICmdList . SetBlendState ( TStaticBlendState < CW_RGBA , BO_Add , BF_DestAlpha , BF_One , BO_Add , BF_Zero , BF_InverseSourceAlpha > : : GetRHI ( ) ) ;
2014-05-08 16:17:53 -04:00
for ( int32 ReflectionCaptureIndex = 0 ; ReflectionCaptureIndex < SortData . Num ( ) ; ReflectionCaptureIndex + + )
{
const FReflectionCaptureSortData & ReflectionCapture = SortData [ ReflectionCaptureIndex ] ;
2014-10-01 09:08:51 -04:00
if ( FeatureLevel > = ERHIFeatureLevel : : SM5 | | ReflectionCapture . SM4FullHDRCubemap )
2014-05-08 16:17:53 -04:00
{
const FSphere LightBounds ( ReflectionCapture . PositionAndRadius , ReflectionCapture . PositionAndRadius . W ) ;
2014-08-28 06:22:54 -04:00
TShaderMapRef < TDeferredLightVS < true > > VertexShader ( View . ShaderMap ) ;
2014-05-08 16:17:53 -04:00
// Use the appropriate shader for the capture shape
if ( ReflectionCapture . CaptureProperties . Z = = 0 )
2014-03-14 14:13:41 -04:00
{
2014-08-28 06:22:54 -04:00
TShaderMapRef < TStandardDeferredReflectionPS < true > > PixelShader ( View . ShaderMap ) ;
2014-03-14 14:13:41 -04:00
2014-05-08 16:17:53 -04:00
static FGlobalBoundShaderState BoundShaderState ;
2014-06-27 11:07:13 -04:00
2014-08-19 10:41:34 -04:00
SetGlobalBoundShaderState ( RHICmdList , FeatureLevel , BoundShaderState , GFilterVertexDeclaration . VertexDeclarationRHI , * VertexShader , * PixelShader ) ;
2014-03-14 14:13:41 -04:00
2014-06-05 16:38:54 -04:00
PixelShader - > SetParameters ( RHICmdList , View , ReflectionCapture ) ;
2014-05-08 16:17:53 -04:00
}
2014-06-05 16:38:54 -04:00
else
2014-05-08 16:17:53 -04:00
{
2014-08-28 06:22:54 -04:00
TShaderMapRef < TStandardDeferredReflectionPS < false > > PixelShader ( View . ShaderMap ) ;
2014-03-14 14:13:41 -04:00
2014-05-08 16:17:53 -04:00
static FGlobalBoundShaderState BoundShaderState ;
2014-06-27 11:07:13 -04:00
2014-08-19 10:41:34 -04:00
SetGlobalBoundShaderState ( RHICmdList , FeatureLevel , BoundShaderState , GFilterVertexDeclaration . VertexDeclarationRHI , * VertexShader , * PixelShader ) ;
2014-03-14 14:13:41 -04:00
2014-06-05 16:38:54 -04:00
PixelShader - > SetParameters ( RHICmdList , View , ReflectionCapture ) ;
2014-03-14 14:13:41 -04:00
}
2014-06-12 07:13:34 -04:00
SetBoundingGeometryRasterizerAndDepthState ( RHICmdList , View , LightBounds ) ;
2014-06-05 16:38:54 -04:00
VertexShader - > SetSimpleLightParameters ( RHICmdList , View , LightBounds ) ;
2014-06-12 07:13:34 -04:00
StencilingGeometry : : DrawSphere ( RHICmdList ) ;
2014-03-14 14:13:41 -04:00
}
}
2014-05-08 16:17:53 -04:00
2014-06-12 07:13:34 -04:00
GRenderTargetPool . VisualizeTexture . SetCheckPoint ( RHICmdList , LightAccumulation ) ;
2014-05-09 18:13:51 -04:00
}
2014-05-08 16:17:53 -04:00
2014-06-05 16:38:54 -04:00
if ( bRequiresApply )
2014-05-09 18:13:51 -04:00
{
// Apply reflections to screen
2014-10-20 10:43:43 -04:00
SCOPED_DRAW_EVENT ( RHICmdList , ReflectionApply ) ;
2014-05-09 18:13:51 -04:00
2015-04-08 15:33:28 -04:00
GSceneRenderTargets . BeginRenderingSceneColor ( RHICmdList , ESimpleRenderTargetMode : : EUninitializedColorExistingDepth , FExclusiveDepthStencil : : DepthRead_StencilWrite ) ;
2014-05-09 18:13:51 -04:00
2014-06-12 07:13:34 -04:00
RHICmdList . SetViewport ( View . ViewRect . Min . X , View . ViewRect . Min . Y , 0.0f , View . ViewRect . Max . X , View . ViewRect . Max . Y , 1.0f ) ;
RHICmdList . SetRasterizerState ( TStaticRasterizerState < FM_Solid , CM_None > : : GetRHI ( ) ) ;
RHICmdList . SetDepthStencilState ( TStaticDepthStencilState < false , CF_Always > : : GetRHI ( ) ) ;
2014-05-09 18:13:51 -04:00
if ( GetReflectionEnvironmentCVar ( ) = = 2 )
2014-03-14 14:13:41 -04:00
{
2014-05-09 18:13:51 -04:00
// override scene color for debugging
2014-06-12 07:13:34 -04:00
RHICmdList . SetBlendState ( TStaticBlendState < > : : GetRHI ( ) ) ;
2014-05-09 18:13:51 -04:00
}
else
{
// additive to scene color
2014-06-12 07:13:34 -04:00
RHICmdList . SetBlendState ( TStaticBlendState < CW_RGBA , BO_Add , BF_One , BF_One , BO_Add , BF_One , BF_One > : : GetRHI ( ) ) ;
2014-05-09 18:13:51 -04:00
}
2014-03-14 14:13:41 -04:00
2014-08-28 06:22:54 -04:00
TShaderMapRef < FPostProcessVS > VertexShader ( View . ShaderMap ) ;
2014-03-14 14:13:41 -04:00
2014-07-02 16:54:50 -04:00
if ( ! LightAccumulation )
{
// should never be used but during debugging it can happen
LightAccumulation = GSystemTextures . WhiteDummy ;
}
2014-06-12 07:13:34 -04:00
2014-05-08 16:17:53 -04:00
# define CASE(A,B,C) \
2014-06-05 16:38:54 -04:00
case ( ( A < < 2 ) | ( B < < 1 ) | C ) : \
2014-05-09 18:13:51 -04:00
{ \
2014-08-28 06:22:54 -04:00
TShaderMapRef < FReflectionApplyPS < A , B , C > > PixelShader ( View . ShaderMap ) ; \
2014-05-09 18:13:51 -04:00
static FGlobalBoundShaderState BoundShaderState ; \
2014-08-19 10:41:34 -04:00
SetGlobalBoundShaderState ( RHICmdList , FeatureLevel , BoundShaderState , GFilterVertexDeclaration . VertexDeclarationRHI , * VertexShader , * PixelShader ) ; \
2014-08-28 13:54:31 -04:00
PixelShader - > SetParameters ( RHICmdList , View , LightAccumulation - > GetRenderTargetItem ( ) . ShaderResourceTexture , SSROutput - > GetRenderTargetItem ( ) . ShaderResourceTexture , DynamicBentNormalAO ) ; \
2014-05-09 18:13:51 -04:00
} ; \
break
2014-04-30 14:14:19 -04:00
2014-06-05 16:38:54 -04:00
switch ( ( ( uint32 ) bSSR < < 2 ) | ( ( uint32 ) bReflectionEnv < < 1 ) | ( uint32 ) bSkyLight )
2014-05-09 18:13:51 -04:00
{
2014-06-05 16:38:54 -04:00
CASE ( 0 , 0 , 0 ) ;
CASE ( 0 , 0 , 1 ) ;
CASE ( 0 , 1 , 0 ) ;
CASE ( 0 , 1 , 1 ) ;
CASE ( 1 , 0 , 0 ) ;
CASE ( 1 , 0 , 1 ) ;
CASE ( 1 , 1 , 0 ) ;
CASE ( 1 , 1 , 1 ) ;
2014-05-09 18:13:51 -04:00
}
2014-05-08 16:17:53 -04:00
# undef CASE
2014-03-14 14:13:41 -04:00
2014-06-05 16:38:54 -04:00
DrawRectangle (
2014-06-12 07:13:34 -04:00
RHICmdList ,
2014-06-05 16:38:54 -04:00
0 , 0 ,
2014-05-09 18:13:51 -04:00
View . ViewRect . Width ( ) , View . ViewRect . Height ( ) ,
2014-06-05 16:38:54 -04:00
View . ViewRect . Min . X , View . ViewRect . Min . Y ,
2014-05-09 18:13:51 -04:00
View . ViewRect . Width ( ) , View . ViewRect . Height ( ) ,
FIntPoint ( View . ViewRect . Width ( ) , View . ViewRect . Height ( ) ) ,
GSceneRenderTargets . GetBufferSizeXY ( ) ,
* VertexShader ) ;
2015-01-27 16:14:50 -05:00
GSceneRenderTargets . FinishRenderingSceneColor ( RHICmdList ) ;
2014-03-14 14:13:41 -04:00
}
2014-04-29 21:59:35 -04:00
}
2014-03-14 14:13:41 -04:00
}
2014-05-08 16:17:53 -04:00
2014-08-28 13:54:31 -04:00
void FDeferredShadingSceneRenderer : : RenderDeferredReflections ( FRHICommandListImmediate & RHICmdList , const TRefCountPtr < IPooledRenderTarget > & DynamicBentNormalAO )
2014-05-08 16:17:53 -04:00
{
if ( IsSimpleDynamicLightingEnabled ( ) | | ViewFamily . EngineShowFlags . VisualizeLightCulling )
{
return ;
}
bool bAnyViewIsReflectionCapture = false ;
for ( int32 ViewIndex = 0 , Num = Views . Num ( ) ; ViewIndex < Num ; ViewIndex + + )
{
const FViewInfo & View = Views [ ViewIndex ] ;
bAnyViewIsReflectionCapture = bAnyViewIsReflectionCapture | | View . bIsReflectionCapture ;
}
2014-08-28 13:54:31 -04:00
// If we're currently capturing a reflection capture, output SpecularColor * IndirectIrradiance for metals so they are not black in reflections,
// Since we don't have multiple bounce specular reflections
2014-05-08 16:17:53 -04:00
if ( bAnyViewIsReflectionCapture )
{
2014-06-12 07:13:34 -04:00
RenderReflectionCaptureSpecularBounceForAllViews ( RHICmdList ) ;
2014-05-08 16:17:53 -04:00
}
else
{
2015-04-08 16:15:25 -04:00
const uint32 bDoTiledReflections = CVarDoTiledReflections . GetValueOnRenderThread ( ) ! = 0 ;
2014-09-10 20:40:27 -04:00
const bool bReflectionEnvironment = ShouldDoReflectionEnvironment ( ) ;
2015-04-08 16:15:25 -04:00
const bool bReflectionsWithCompute = bDoTiledReflections & & ( FeatureLevel > = ERHIFeatureLevel : : SM5 ) & & bReflectionEnvironment & & Scene - > ReflectionSceneData . CubemapArray . IsValid ( ) ;
2015-01-27 16:14:50 -05:00
2014-10-06 10:06:04 -04:00
if ( bReflectionsWithCompute )
2014-05-08 16:17:53 -04:00
{
2014-09-10 19:20:06 -04:00
RenderTiledDeferredImageBasedReflections ( RHICmdList , DynamicBentNormalAO ) ;
2014-05-08 16:17:53 -04:00
}
else
{
2014-09-10 20:40:27 -04:00
RenderStandardDeferredImageBasedReflections ( RHICmdList , bReflectionEnvironment , DynamicBentNormalAO ) ;
2014-05-08 16:17:53 -04:00
}
}
2015-04-01 07:20:55 -04:00
}