2016-01-07 08:17:16 -05:00
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
2014-03-14 14:13:41 -04:00
/*=============================================================================
DeferredShadingRenderer.cpp: Top level rendering loop for deferred shading
=============================================================================*/
# include "RendererPrivate.h"
2014-05-20 07:27:59 -04:00
# include "Engine.h"
2014-03-14 14:13:41 -04:00
# include "ScenePrivate.h"
# include "ScreenRendering.h"
# include "SceneFilterRendering.h"
2015-04-09 19:14:28 -04:00
# include "ScreenSpaceReflections.h"
2014-03-14 14:13:41 -04:00
# include "VisualizeTexture.h"
# include "CompositionLighting.h"
# include "FXSystem.h"
# include "OneColorShader.h"
# include "CompositionLighting/PostProcessDeferredDecals.h"
# include "LightPropagationVolume.h"
2014-08-21 06:03:00 -04:00
# include "DeferredShadingRenderer.h"
# include "SceneUtils.h"
2014-09-18 15:13:07 -04:00
# include "DistanceFieldSurfaceCacheLighting.h"
2015-05-11 20:04:15 -04:00
# include "GlobalDistanceField.h"
2014-09-03 07:26:17 -04:00
# include "PostProcess/PostProcessing.h"
2014-11-21 22:32:16 -05:00
# include "DistanceFieldAtlas.h"
2015-07-14 19:56:43 -04:00
# include "EngineModule.h"
2015-07-24 15:06:10 -04:00
# include "IHeadMountedDisplay.h"
2016-01-08 11:12:28 -05:00
# include "GPUSkinCache.h"
2014-03-14 14:13:41 -04:00
TAutoConsoleVariable < int32 > CVarEarlyZPass (
TEXT ( " r.EarlyZPass " ) ,
3 ,
TEXT ( " Whether to use a depth only pass to initialize Z culling for the base pass. Cannot be changed at runtime. \n " )
TEXT ( " Note: also look at r.EarlyZPassMovable \n " )
TEXT ( " 0: off \n " )
2016-06-08 16:02:23 -04:00
TEXT ( " 1: good occluders only: not masked, and large on screen \n " )
2014-03-14 14:13:41 -04:00
TEXT ( " 2: all opaque (including masked) \n " )
2014-11-20 12:36:32 -05:00
TEXT ( " x: use built in heuristic (default is 3) " ) ,
2016-06-02 13:13:43 -04:00
ECVF_Scalability ) ;
2014-03-14 14:13:41 -04:00
int32 GEarlyZPassMovable = 0 ;
/** Affects static draw lists so must reload level to propagate. */
static FAutoConsoleVariableRef CVarEarlyZPassMovable (
TEXT ( " r.EarlyZPassMovable " ) ,
GEarlyZPassMovable ,
TEXT ( " Whether to render movable objects into the depth only pass. Movable objects are typically not good occluders so this defaults to off. \n " )
TEXT ( " Note: also look at r.EarlyZPass " ) ,
2016-06-02 13:13:43 -04:00
ECVF_RenderThreadSafe | ECVF_Scalability
2014-03-14 14:13:41 -04:00
) ;
2016-06-08 16:02:23 -04:00
static TAutoConsoleVariable < int32 > CVarStencilForLODDither (
TEXT ( " r.StencilForLODDither " ) ,
0 ,
TEXT ( " Whether to use stencil tests in the prepass, and depth-equal tests in the base pass to implement LOD dithering. \n " )
TEXT ( " If disabled, LOD dithering will be done through clip() instructions in the prepass and base pass, which disables EarlyZ. \n " )
TEXT ( " Forces a full prepass when enabled. " ) ,
ECVF_RenderThreadSafe | ECVF_ReadOnly ) ;
2016-01-14 08:11:47 -05:00
TAutoConsoleVariable < int32 > CVarCustomDepthOrder (
TEXT ( " r.CustomDepth.Order " ) ,
1 ,
TEXT ( " When CustomDepth (and CustomStencil) is getting rendered \n " )
TEXT ( " 0: Before GBuffer (can be more efficient with AsyncCompute, allows using it in DBuffer pass, no GBuffer blending decals allow GBuffer compression) \n " )
TEXT ( " 1: After Base Pass (default) " ) ,
ECVF_RenderThreadSafe ) ;
2014-03-14 14:13:41 -04:00
# if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
2014-06-25 05:47:33 -04:00
static TAutoConsoleVariable < int32 > CVarVisualizeTexturePool (
TEXT ( " r.VisualizeTexturePool " ) ,
0 ,
TEXT ( " Allows to enable the visualize the texture pool (currently only on console). \n " )
2016-01-14 08:11:47 -05:00
TEXT ( " 0: off (default) \n " )
2014-06-25 05:47:33 -04:00
TEXT ( " 1: on " ) ,
ECVF_Cheat | ECVF_RenderThreadSafe ) ;
2014-03-14 14:13:41 -04:00
# endif
2016-05-01 17:37:41 -04:00
static TAutoConsoleVariable < int32 > CVarClearCoatNormal (
TEXT ( " r.ClearCoatNormal " ) ,
0 ,
TEXT ( " 0 to disable clear coat normal. \n " )
TEXT ( " 0: off \n " )
TEXT ( " 1: on " ) ,
ECVF_ReadOnly ) ;
2016-01-27 07:18:43 -05:00
static TAutoConsoleVariable < int32 > CVarFXSystemPreRenderAfterPrepass (
TEXT ( " r.FXSystemPreRenderAfterPrepass " ) ,
0 ,
TEXT ( " If > 0, then do the FX prerender after the prepass. This improves pipelining for greater performance. Experiemental option. " ) ,
ECVF_RenderThreadSafe
) ;
2016-07-11 18:51:20 -04:00
int32 GbEnableAsyncComputeTranslucencyLightingVolumeClear = 1 ;
static FAutoConsoleVariableRef CVarEnableAsyncComputeTranslucencyLightingVolumeClear (
TEXT ( " r.EnableAsyncComputeTranslucencyLightingVolumeClear " ) ,
GbEnableAsyncComputeTranslucencyLightingVolumeClear ,
TEXT ( " Whether to clear the translucency lighting volume using async compute. \n " ) ,
ECVF_RenderThreadSafe | ECVF_Scalability
) ;
2015-12-02 16:42:06 -05:00
DECLARE_CYCLE_STAT ( TEXT ( " PostInitViews FlushDel " ) , STAT_PostInitViews_FlushDel , STATGROUP_InitViews ) ;
DECLARE_CYCLE_STAT ( TEXT ( " InitViews Intentional Stall " ) , STAT_InitViews_Intentional_Stall , STATGROUP_InitViews ) ;
2016-06-27 13:42:20 -04:00
DEFINE_STAT ( STAT_FDeferredShadingSceneRenderer_AsyncSortBasePassStaticData ) ;
2015-12-02 16:42:06 -05:00
DECLARE_CYCLE_STAT ( TEXT ( " DeferredShadingSceneRenderer UpdateDownsampledDepthSurface " ) , STAT_FDeferredShadingSceneRenderer_UpdateDownsampledDepthSurface , STATGROUP_SceneRendering ) ;
DECLARE_CYCLE_STAT ( TEXT ( " DeferredShadingSceneRenderer Render Init " ) , STAT_FDeferredShadingSceneRenderer_Render_Init , STATGROUP_SceneRendering ) ;
DECLARE_CYCLE_STAT ( TEXT ( " DeferredShadingSceneRenderer Render ServiceLocalQueue " ) , STAT_FDeferredShadingSceneRenderer_Render_ServiceLocalQueue , STATGROUP_SceneRendering ) ;
DECLARE_CYCLE_STAT ( TEXT ( " DeferredShadingSceneRenderer DistanceFieldAO Init " ) , STAT_FDeferredShadingSceneRenderer_DistanceFieldAO_Init , STATGROUP_SceneRendering ) ;
DECLARE_CYCLE_STAT ( TEXT ( " DeferredShadingSceneRenderer FGlobalDynamicVertexBuffer Commit " ) , STAT_FDeferredShadingSceneRenderer_FGlobalDynamicVertexBuffer_Commit , STATGROUP_SceneRendering ) ;
DECLARE_CYCLE_STAT ( TEXT ( " DeferredShadingSceneRenderer MotionBlurStartFrame " ) , STAT_FDeferredShadingSceneRenderer_MotionBlurStartFrame , STATGROUP_SceneRendering ) ;
DECLARE_CYCLE_STAT ( TEXT ( " DeferredShadingSceneRenderer FXSystem PreRender " ) , STAT_FDeferredShadingSceneRenderer_FXSystem_PreRender , STATGROUP_SceneRendering ) ;
DECLARE_CYCLE_STAT ( TEXT ( " DeferredShadingSceneRenderer AllocGBufferTargets " ) , STAT_FDeferredShadingSceneRenderer_AllocGBufferTargets , STATGROUP_SceneRendering ) ;
DECLARE_CYCLE_STAT ( TEXT ( " DeferredShadingSceneRenderer ClearLPVs " ) , STAT_FDeferredShadingSceneRenderer_ClearLPVs , STATGROUP_SceneRendering ) ;
DECLARE_CYCLE_STAT ( TEXT ( " DeferredShadingSceneRenderer DBuffer " ) , STAT_FDeferredShadingSceneRenderer_DBuffer , STATGROUP_SceneRendering ) ;
DECLARE_CYCLE_STAT ( TEXT ( " DeferredShadingSceneRenderer SetAndClearViewGBuffer " ) , STAT_FDeferredShadingSceneRenderer_SetAndClearViewGBuffer , STATGROUP_SceneRendering ) ;
DECLARE_CYCLE_STAT ( TEXT ( " DeferredShadingSceneRenderer ClearGBufferAtMaxZ " ) , STAT_FDeferredShadingSceneRenderer_ClearGBufferAtMaxZ , STATGROUP_SceneRendering ) ;
DECLARE_CYCLE_STAT ( TEXT ( " DeferredShadingSceneRenderer ResolveDepth After Basepass " ) , STAT_FDeferredShadingSceneRenderer_ResolveDepth_After_Basepass , STATGROUP_SceneRendering ) ;
DECLARE_CYCLE_STAT ( TEXT ( " DeferredShadingSceneRenderer Resolve After Basepass " ) , STAT_FDeferredShadingSceneRenderer_Resolve_After_Basepass , STATGROUP_SceneRendering ) ;
DECLARE_CYCLE_STAT ( TEXT ( " DeferredShadingSceneRenderer FXSystem PostRenderOpaque " ) , STAT_FDeferredShadingSceneRenderer_FXSystem_PostRenderOpaque , STATGROUP_SceneRendering ) ;
DECLARE_CYCLE_STAT ( TEXT ( " DeferredShadingSceneRenderer AfterBasePass " ) , STAT_FDeferredShadingSceneRenderer_AfterBasePass , STATGROUP_SceneRendering ) ;
DECLARE_CYCLE_STAT ( TEXT ( " DeferredShadingSceneRenderer Lighting " ) , STAT_FDeferredShadingSceneRenderer_Lighting , STATGROUP_SceneRendering ) ;
DECLARE_CYCLE_STAT ( TEXT ( " DeferredShadingSceneRenderer RenderLightShaftOcclusion " ) , STAT_FDeferredShadingSceneRenderer_RenderLightShaftOcclusion , STATGROUP_SceneRendering ) ;
DECLARE_CYCLE_STAT ( TEXT ( " DeferredShadingSceneRenderer RenderAtmosphere " ) , STAT_FDeferredShadingSceneRenderer_RenderAtmosphere , STATGROUP_SceneRendering ) ;
DECLARE_CYCLE_STAT ( TEXT ( " DeferredShadingSceneRenderer RenderFog " ) , STAT_FDeferredShadingSceneRenderer_RenderFog , STATGROUP_SceneRendering ) ;
DECLARE_CYCLE_STAT ( TEXT ( " DeferredShadingSceneRenderer RenderLightShaftBloom " ) , STAT_FDeferredShadingSceneRenderer_RenderLightShaftBloom , STATGROUP_SceneRendering ) ;
DECLARE_CYCLE_STAT ( TEXT ( " DeferredShadingSceneRenderer UpdateMotionBlurCache " ) , STAT_FDeferredShadingSceneRenderer_UpdateMotionBlurCache , STATGROUP_SceneRendering ) ;
DECLARE_CYCLE_STAT ( TEXT ( " DeferredShadingSceneRenderer RenderFinish " ) , STAT_FDeferredShadingSceneRenderer_RenderFinish , STATGROUP_SceneRendering ) ;
DECLARE_CYCLE_STAT ( TEXT ( " OcclusionSubmittedFence Dispatch " ) , STAT_OcclusionSubmittedFence_Dispatch , STATGROUP_SceneRendering ) ;
DECLARE_CYCLE_STAT ( TEXT ( " OcclusionSubmittedFence Wait " ) , STAT_OcclusionSubmittedFence_Wait , STATGROUP_SceneRendering ) ;
2016-07-18 17:17:08 -04:00
DECLARE_FLOAT_COUNTER_STAT ( TEXT ( " Postprocessing " ) , Stat_GPU_Postprocessing , STATGROUP_GPU ) ;
DECLARE_FLOAT_COUNTER_STAT ( TEXT ( " HZB " ) , Stat_GPU_HZB , STATGROUP_GPU ) ;
DECLARE_FLOAT_COUNTER_STAT ( TEXT ( " [unaccounted] " ) , Stat_GPU_Unaccounted , STATGROUP_GPU ) ;
2016-07-11 18:51:20 -04:00
bool ShouldForceFullDepthPass ( ERHIFeatureLevel : : Type FeatureLevel )
{
static IConsoleVariable * CDBufferVar = IConsoleManager : : Get ( ) . FindConsoleVariable ( TEXT ( " r.DBuffer " ) ) ;
bool bDBufferAllowed = CDBufferVar ? CDBufferVar - > GetInt ( ) ! = 0 : false ;
static const auto StencilLODDitherCVar = IConsoleManager : : Get ( ) . FindTConsoleVariableDataInt ( TEXT ( " r.StencilForLODDither " ) ) ;
bool bStencilLODDither = StencilLODDitherCVar - > GetValueOnAnyThread ( ) ! = 0 ;
// Note: ShouldForceFullDepthPass affects which static draw lists meshes go into, so nothing it depends on can change at runtime, unless you do a FGlobalComponentRecreateRenderStateContext to propagate the cvar change
return bDBufferAllowed | | bStencilLODDither | | IsForwardShadingEnabled ( FeatureLevel ) ;
}
const TCHAR * GetDepthPassReason ( bool bDitheredLODTransitionsUseStencil , ERHIFeatureLevel : : Type FeatureLevel )
{
if ( IsForwardShadingEnabled ( FeatureLevel ) )
{
return TEXT ( " (Forced by ForwardShading) " ) ;
}
static IConsoleVariable * CDBufferVar = IConsoleManager : : Get ( ) . FindConsoleVariable ( TEXT ( " r.DBuffer " ) ) ;
bool bDBufferAllowed = CDBufferVar ? CDBufferVar - > GetInt ( ) ! = 0 : false ;
if ( bDBufferAllowed )
{
return TEXT ( " (Forced by DBuffer) " ) ;
}
if ( bDitheredLODTransitionsUseStencil )
{
return TEXT ( " (Forced by StencilLODDither) " ) ;
}
return TEXT ( " " ) ;
}
2015-12-02 16:42:06 -05:00
2014-03-14 14:13:41 -04:00
/*-----------------------------------------------------------------------------
FDeferredShadingSceneRenderer
-----------------------------------------------------------------------------*/
FDeferredShadingSceneRenderer : : FDeferredShadingSceneRenderer ( const FSceneViewFamily * InViewFamily , FHitProxyConsumer * HitProxyConsumer )
: FSceneRenderer ( InViewFamily , HitProxyConsumer )
, EarlyZPassMode ( DDM_NonMaskedOnly )
2016-06-02 13:13:43 -04:00
, bEarlyZPassMovable ( false )
2014-03-14 14:13:41 -04:00
{
if ( FPlatformProperties : : SupportsWindowedMode ( ) )
{
// Use a depth only pass if we are using full blown HQ lightmaps
// Otherwise base pass pixel shaders will be cheap and there will be little benefit to rendering a depth only pass
2014-07-24 05:23:50 -04:00
if ( AllowHighQualityLightmaps ( FeatureLevel ) | | ! ViewFamily . EngineShowFlags . Lighting )
2014-03-14 14:13:41 -04:00
{
EarlyZPassMode = DDM_None ;
}
}
// developer override, good for profiling, can be useful as project setting
{
2016-06-02 13:13:43 -04:00
const int32 CVarValue = CVarEarlyZPass . GetValueOnGameThread ( ) ;
2014-03-14 14:13:41 -04:00
switch ( CVarValue )
{
case 0 : EarlyZPassMode = DDM_None ; break ;
case 1 : EarlyZPassMode = DDM_NonMaskedOnly ; break ;
case 2 : EarlyZPassMode = DDM_AllOccluders ; break ;
2014-12-18 01:27:13 -05:00
case 3 : break ; // Note: 3 indicates "default behavior" and does not specify an override
2014-03-14 14:13:41 -04:00
}
}
2015-03-12 11:26:29 -04:00
// Shader complexity requires depth only pass to display masked material cost correctly
2016-07-11 18:51:20 -04:00
if ( ViewFamily . UseDebugViewPS ( ) & & ViewFamily . GetDebugViewShaderMode ( ) ! = DVSM_MaterialTexCoordScalesAnalysis )
2015-03-12 11:26:29 -04:00
{
EarlyZPassMode = DDM_AllOpaque ;
}
2015-12-10 21:55:37 -05:00
2016-06-02 13:13:43 -04:00
// Warning: EarlyZPass logic is mirrored in FStaticMesh::AddToDrawLists
bEarlyZPassMovable = GEarlyZPassMovable ! = 0 ;
2016-06-08 16:02:23 -04:00
static const auto StencilLODDitherCVar = IConsoleManager : : Get ( ) . FindTConsoleVariableDataInt ( TEXT ( " r.StencilForLODDither " ) ) ;
bDitheredLODTransitionsUseStencil = StencilLODDitherCVar - > GetValueOnAnyThread ( ) ! = 0 ;
2016-07-11 18:51:20 -04:00
if ( ShouldForceFullDepthPass ( FeatureLevel ) )
2016-06-02 13:13:43 -04:00
{
2016-06-08 16:02:23 -04:00
// DBuffer decals and stencil LOD dithering force a full prepass
2016-06-02 13:13:43 -04:00
EarlyZPassMode = DDM_AllOccluders ;
bEarlyZPassMovable = true ;
}
2014-03-14 14:13:41 -04:00
}
extern FGlobalBoundShaderState GClearMRTBoundShaderState [ 8 ] ;
2016-06-02 13:13:43 -04:00
float GetSceneColorClearAlpha ( )
{
// Scene color alpha is used during scene captures and planar reflections. 1 indicates background should be shown, 0 indicates foreground is fully present.
return 1.0f ;
}
2014-03-14 14:13:41 -04:00
/**
* Clears view where Z is still at the maximum value (ie no geometry rendered)
*/
2014-07-08 10:43:52 -04:00
void FDeferredShadingSceneRenderer : : ClearGBufferAtMaxZ ( FRHICommandList & RHICmdList )
2014-03-14 14:13:41 -04:00
{
// Assumes BeginRenderingSceneColor() has been called before this function
2014-10-20 10:43:43 -04:00
SCOPED_DRAW_EVENT ( RHICmdList , ClearGBufferAtMaxZ ) ;
2014-03-14 14:13:41 -04:00
// Clear the G Buffer render targets
const bool bClearBlack = Views [ 0 ] . Family - > EngineShowFlags . ShaderComplexity | | Views [ 0 ] . Family - > EngineShowFlags . StationaryLightOverlap ;
2016-06-02 13:13:43 -04:00
const float ClearAlpha = GetSceneColorClearAlpha ( ) ;
const FLinearColor ClearColor = bClearBlack ? FLinearColor ( 0 , 0 , 0 , ClearAlpha ) : FLinearColor ( Views [ 0 ] . BackgroundColor . R , Views [ 0 ] . BackgroundColor . G , Views [ 0 ] . BackgroundColor . B , ClearAlpha ) ;
2014-03-14 14:13:41 -04:00
// Same clear color from RHIClearMRT
2015-07-09 15:11:37 -04:00
FLinearColor ClearColors [ MaxSimultaneousRenderTargets ] =
2016-06-02 13:13:43 -04:00
{ ClearColor , FLinearColor ( 0.5f , 0.5f , 0.5f , 0 ) , FLinearColor ( 0 , 0 , 0 , 1 ) , FLinearColor ( 0 , 0 , 0 , 0 ) , FLinearColor ( 0 , 1 , 1 , 1 ) , FLinearColor ( 1 , 1 , 1 , 1 ) , FLinearColor : : Transparent , FLinearColor : : Transparent } ;
2014-03-14 14:13:41 -04:00
2015-05-29 10:47:57 -04:00
uint32 NumActiveRenderTargets = FSceneRenderTargets : : Get ( RHICmdList ) . GetNumGBufferTargets ( ) ;
2014-03-14 14:13:41 -04:00
2014-08-28 06:22:54 -04:00
auto ShaderMap = GetGlobalShaderMap ( FeatureLevel ) ;
TShaderMapRef < TOneColorVS < true > > VertexShader ( ShaderMap ) ;
2014-03-14 14:13:41 -04:00
FOneColorPS * PixelShader = NULL ;
// Assume for now all code path supports SM4, otherwise render target numbers are changed
switch ( NumActiveRenderTargets )
{
case 5 :
{
2014-08-28 06:22:54 -04:00
TShaderMapRef < TOneColorPixelShaderMRT < 5 > > MRTPixelShader ( ShaderMap ) ;
2014-03-14 14:13:41 -04:00
PixelShader = * MRTPixelShader ;
}
break ;
case 6 :
{
2014-08-28 06:22:54 -04:00
TShaderMapRef < TOneColorPixelShaderMRT < 6 > > MRTPixelShader ( ShaderMap ) ;
2014-03-14 14:13:41 -04:00
PixelShader = * MRTPixelShader ;
}
break ;
default :
case 1 :
{
2014-08-28 06:22:54 -04:00
TShaderMapRef < TOneColorPixelShaderMRT < 1 > > MRTPixelShader ( ShaderMap ) ;
2014-03-14 14:13:41 -04:00
PixelShader = * MRTPixelShader ;
}
break ;
}
2014-08-19 10:41:34 -04:00
SetGlobalBoundShaderState ( RHICmdList , FeatureLevel , GClearMRTBoundShaderState [ NumActiveRenderTargets - 1 ] , GetVertexDeclarationFVector4 ( ) , * VertexShader , PixelShader ) ;
2014-03-14 14:13:41 -04:00
// Opaque rendering, depth test but no depth writes
2014-06-12 07:13:34 -04:00
RHICmdList . SetRasterizerState ( TStaticRasterizerState < FM_Solid , CM_None > : : GetRHI ( ) ) ;
RHICmdList . SetBlendState ( TStaticBlendStateWriteMask < > : : GetRHI ( ) ) ;
2015-04-01 10:53:07 -04:00
RHICmdList . SetDepthStencilState ( TStaticDepthStencilState < false , CF_DepthNearOrEqual > : : GetRHI ( ) ) ;
2014-03-14 14:13:41 -04:00
// Clear each viewport by drawing background color at MaxZ depth
for ( int32 ViewIndex = 0 ; ViewIndex < Views . Num ( ) ; ViewIndex + + )
{
2014-10-20 10:43:43 -04:00
SCOPED_CONDITIONAL_DRAW_EVENTF ( RHICmdList , EventView , Views . Num ( ) > 1 , TEXT ( " ClearView%d " ) , ViewIndex ) ;
2014-03-14 14:13:41 -04:00
FViewInfo & View = Views [ ViewIndex ] ;
// Set viewport for this view
2014-06-12 07:13:34 -04:00
RHICmdList . SetViewport ( View . ViewRect . Min . X , View . ViewRect . Min . Y , 0 , View . ViewRect . Max . X , View . ViewRect . Max . Y , 1 ) ;
2014-03-14 14:13:41 -04:00
// Setup PS
2015-07-09 15:11:37 -04:00
PixelShader - > SetColors ( RHICmdList , ClearColors , NumActiveRenderTargets ) ;
2014-03-14 14:13:41 -04:00
// Render quad
2015-03-06 15:13:38 -05:00
static const FVector4 ClearQuadVertices [ 4 ] =
{
2016-06-02 13:13:43 -04:00
FVector4 ( - 1.0f , 1.0f , ( float ) ERHIZBuffer : : FarPlane , 1.0f ) ,
2015-03-31 14:02:45 -04:00
FVector4 ( 1.0f , 1.0f , ( float ) ERHIZBuffer : : FarPlane , 1.0f ) ,
FVector4 ( - 1.0f , - 1.0f , ( float ) ERHIZBuffer : : FarPlane , 1.0f ) ,
FVector4 ( 1.0f , - 1.0f , ( float ) ERHIZBuffer : : FarPlane , 1.0f )
2015-03-06 15:13:38 -05:00
} ;
2014-06-12 07:13:34 -04:00
DrawPrimitiveUP ( RHICmdList , PT_TriangleStrip , 2 , ClearQuadVertices , sizeof ( ClearQuadVertices [ 0 ] ) ) ;
2014-03-14 14:13:41 -04:00
}
}
/** Render the TexturePool texture */
# if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
2014-06-27 11:07:13 -04:00
void FDeferredShadingSceneRenderer : : RenderVisualizeTexturePool ( FRHICommandListImmediate & RHICmdList )
2014-03-14 14:13:41 -04:00
{
TRefCountPtr < IPooledRenderTarget > VisualizeTexturePool ;
/** Resolution for the texture pool visualizer texture. */
enum
{
TexturePoolVisualizerSizeX = 280 ,
TexturePoolVisualizerSizeY = 140 ,
} ;
2015-07-09 15:11:37 -04:00
FPooledRenderTargetDesc Desc ( FPooledRenderTargetDesc : : Create2DDesc ( FIntPoint ( TexturePoolVisualizerSizeX , TexturePoolVisualizerSizeY ) , PF_B8G8R8A8 , FClearValueBinding : : None , TexCreate_None , TexCreate_None , false ) ) ;
2015-09-21 20:07:00 -04:00
GRenderTargetPool . FindFreeElement ( RHICmdList , Desc , VisualizeTexturePool , TEXT ( " VisualizeTexturePool " ) ) ;
2014-03-14 14:13:41 -04:00
uint32 Pitch ;
2014-06-27 11:07:13 -04:00
FColor * TextureData = ( FColor * ) RHICmdList . LockTexture2D ( ( FTexture2DRHIRef & ) VisualizeTexturePool - > GetRenderTargetItem ( ) . ShaderResourceTexture , 0 , RLM_WriteOnly , Pitch , false ) ;
2014-03-14 14:13:41 -04:00
if ( TextureData )
{
// clear with grey to get reliable background color
FMemory : : Memset ( TextureData , 0x88 , TexturePoolVisualizerSizeX * TexturePoolVisualizerSizeY * 4 ) ;
2014-06-27 11:07:13 -04:00
RHICmdList . GetTextureMemoryVisualizeData ( TextureData , TexturePoolVisualizerSizeX , TexturePoolVisualizerSizeY , Pitch , 4096 ) ;
2014-03-14 14:13:41 -04:00
}
2014-06-27 11:07:13 -04:00
RHICmdList . UnlockTexture2D ( ( FTexture2DRHIRef & ) VisualizeTexturePool - > GetRenderTargetItem ( ) . ShaderResourceTexture , 0 , false ) ;
2014-03-14 14:13:41 -04:00
2015-05-29 10:47:57 -04:00
FIntPoint RTExtent = FSceneRenderTargets : : Get ( RHICmdList ) . GetBufferSizeXY ( ) ;
2014-03-14 14:13:41 -04:00
FVector2D Tex00 = FVector2D ( 0 , 0 ) ;
FVector2D Tex11 = FVector2D ( 1 , 1 ) ;
//todo VisualizeTexture(*VisualizeTexturePool, ViewFamily.RenderTarget, FIntRect(0, 0, RTExtent.X, RTExtent.Y), RTExtent, 1.0f, 0.0f, 0.0f, Tex00, Tex11, 1.0f, false);
}
# endif
/**
* Finishes the view family rendering.
*/
2014-06-27 11:07:13 -04:00
void FDeferredShadingSceneRenderer : : RenderFinish ( FRHICommandListImmediate & RHICmdList )
2014-03-14 14:13:41 -04:00
{
# if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
{
2014-06-25 05:47:33 -04:00
if ( CVarVisualizeTexturePool . GetValueOnRenderThread ( ) )
2014-03-14 14:13:41 -04:00
{
2014-06-27 11:07:13 -04:00
RenderVisualizeTexturePool ( RHICmdList ) ;
2014-03-14 14:13:41 -04:00
}
}
# endif //!(UE_BUILD_SHIPPING || UE_BUILD_TEST)
2016-01-08 11:12:28 -05:00
if ( GEnableGPUSkinCache )
{
GGPUSkinCache . TransitionToWriteable ( RHICmdList ) ;
}
2014-06-27 11:07:13 -04:00
FSceneRenderer : : RenderFinish ( RHICmdList ) ;
2014-03-14 14:13:41 -04:00
2014-05-06 17:24:57 -04:00
// Some RT should be released as early as possible to allow sharing of that memory for other purposes.
// SceneColor is be released in tone mapping, if not we want to get access to the HDR scene color after this pass so we keep it.
2014-05-06 11:27:50 -04:00
// This becomes even more important with some limited VRam (XBoxOne).
2015-05-29 10:47:57 -04:00
FSceneRenderTargets : : Get ( RHICmdList ) . SetLightAttenuation ( 0 ) ;
2014-03-14 14:13:41 -04:00
}
2015-01-09 20:56:36 -05:00
void BuildHZB ( FRHICommandListImmediate & RHICmdList , FViewInfo & View ) ;
2014-03-14 14:13:41 -04:00
/**
* Renders the view family.
*/
2014-09-03 10:52:00 -04:00
2016-06-27 13:42:20 -04:00
DEFINE_STAT ( STAT_CLM_PrePass ) ;
2016-02-16 05:48:48 -05:00
DECLARE_CYCLE_STAT ( TEXT ( " FXPreRender " ) , STAT_CLM_FXPreRender , STATGROUP_CommandListMarkers ) ;
2014-10-02 11:20:07 -04:00
DECLARE_CYCLE_STAT ( TEXT ( " AfterPrePass " ) , STAT_CLM_AfterPrePass , STATGROUP_CommandListMarkers ) ;
DECLARE_CYCLE_STAT ( TEXT ( " BasePass " ) , STAT_CLM_BasePass , STATGROUP_CommandListMarkers ) ;
DECLARE_CYCLE_STAT ( TEXT ( " AfterBasePass " ) , STAT_CLM_AfterBasePass , STATGROUP_CommandListMarkers ) ;
DECLARE_CYCLE_STAT ( TEXT ( " Lighting " ) , STAT_CLM_Lighting , STATGROUP_CommandListMarkers ) ;
DECLARE_CYCLE_STAT ( TEXT ( " AfterLighting " ) , STAT_CLM_AfterLighting , STATGROUP_CommandListMarkers ) ;
DECLARE_CYCLE_STAT ( TEXT ( " Translucency " ) , STAT_CLM_Translucency , STATGROUP_CommandListMarkers ) ;
2015-06-08 09:38:50 -04:00
DECLARE_CYCLE_STAT ( TEXT ( " RenderDistortion " ) , STAT_CLM_RenderDistortion , STATGROUP_CommandListMarkers ) ;
2014-10-02 11:20:07 -04:00
DECLARE_CYCLE_STAT ( TEXT ( " AfterTranslucency " ) , STAT_CLM_AfterTranslucency , STATGROUP_CommandListMarkers ) ;
2015-06-08 09:38:50 -04:00
DECLARE_CYCLE_STAT ( TEXT ( " RenderDistanceFieldLighting " ) , STAT_CLM_RenderDistanceFieldLighting , STATGROUP_CommandListMarkers ) ;
DECLARE_CYCLE_STAT ( TEXT ( " LightShaftBloom " ) , STAT_CLM_LightShaftBloom , STATGROUP_CommandListMarkers ) ;
DECLARE_CYCLE_STAT ( TEXT ( " PostProcessing " ) , STAT_CLM_PostProcessing , STATGROUP_CommandListMarkers ) ;
2014-10-02 11:20:07 -04:00
DECLARE_CYCLE_STAT ( TEXT ( " Velocity " ) , STAT_CLM_Velocity , STATGROUP_CommandListMarkers ) ;
DECLARE_CYCLE_STAT ( TEXT ( " AfterVelocity " ) , STAT_CLM_AfterVelocity , STATGROUP_CommandListMarkers ) ;
2015-06-08 09:38:50 -04:00
DECLARE_CYCLE_STAT ( TEXT ( " RenderFinish " ) , STAT_CLM_RenderFinish , STATGROUP_CommandListMarkers ) ;
2014-10-02 11:20:07 -04:00
DECLARE_CYCLE_STAT ( TEXT ( " AfterFrame " ) , STAT_CLM_AfterFrame , STATGROUP_CommandListMarkers ) ;
2015-07-01 10:40:13 -04:00
FGraphEventRef FDeferredShadingSceneRenderer : : OcclusionSubmittedFence [ FOcclusionQueryHelpers : : MaxBufferedOcclusionFrames ] ;
2016-02-24 06:51:42 -05:00
FGraphEventRef FDeferredShadingSceneRenderer : : TranslucencyTimestampQuerySubmittedFence [ FOcclusionQueryHelpers : : MaxBufferedOcclusionFrames + 1 ] ;
2015-03-26 18:31:22 -04:00
2014-10-23 16:31:43 -04:00
/**
* Returns true if the depth Prepass needs to run
*/
static FORCEINLINE bool NeedsPrePass ( const FDeferredShadingSceneRenderer * Renderer )
{
return ( RHIHasTiledGPU ( Renderer - > ViewFamily . GetShaderPlatform ( ) ) = = false ) & &
2016-06-02 13:13:43 -04:00
( Renderer - > EarlyZPassMode ! = DDM_None | | Renderer - > bEarlyZPassMovable ! = 0 ) ;
2014-10-23 16:31:43 -04:00
}
2014-10-02 11:20:07 -04:00
2014-10-27 20:23:51 -04:00
static void SetAndClearViewGBuffer ( FRHICommandListImmediate & RHICmdList , FViewInfo & View , bool bClearDepth )
{
// if we didn't to the prepass above, then we will need to clear now, otherwise, it's already been cleared and rendered to
ERenderTargetLoadAction DepthLoadAction = bClearDepth ? ERenderTargetLoadAction : : EClear : ERenderTargetLoadAction : : ELoad ;
const bool bClearBlack = View . Family - > EngineShowFlags . ShaderComplexity | | View . Family - > EngineShowFlags . StationaryLightOverlap ;
2016-06-02 13:13:43 -04:00
const float ClearAlpha = GetSceneColorClearAlpha ( ) ;
const FLinearColor ClearColor = bClearBlack ? FLinearColor ( 0 , 0 , 0 , ClearAlpha ) : FLinearColor ( View . BackgroundColor . R , View . BackgroundColor . G , View . BackgroundColor . B , ClearAlpha ) ;
2014-10-27 20:23:51 -04:00
// clearing the GBuffer
2015-11-10 17:11:09 -05:00
FSceneRenderTargets : : Get ( RHICmdList ) . BeginRenderingGBuffer ( RHICmdList , ERenderTargetLoadAction : : EClear , DepthLoadAction , View . Family - > EngineShowFlags . ShaderComplexity , ClearColor ) ;
2014-10-27 20:23:51 -04:00
}
2015-03-26 18:31:22 -04:00
static TAutoConsoleVariable < int32 > CVarOcclusionQueryLocation (
TEXT ( " r.OcclusionQueryLocation " ) ,
0 ,
TEXT ( " Controls when occlusion queries are rendered. Rendering before the base pass may give worse occlusion (because not all occluders generally render in the earlyzpass). " )
TEXT ( " However, it may reduce CPU waiting for query result stalls on some platforms and increase overall performance. " )
TEXT ( " 0: After BasePass. " )
TEXT ( " 1: After EarlyZPass, but before BasePass. " ) ) ;
void FDeferredShadingSceneRenderer : : RenderOcclusion ( FRHICommandListImmediate & RHICmdList , bool bRenderQueries , bool bRenderHZB )
{
if ( bRenderQueries | | bRenderHZB )
{
2016-02-04 23:40:42 -05:00
FSceneRenderTargets & SceneContext = FSceneRenderTargets : : Get ( RHICmdList ) ;
2016-07-18 17:17:08 -04:00
SCOPED_GPU_STAT ( RHICmdList , Stat_GPU_HZB ) ;
2015-03-26 18:31:22 -04:00
{
// Update the quarter-sized depth buffer with the current contents of the scene depth texture.
// This needs to happen before occlusion tests, which makes use of the small depth buffer.
2015-12-02 16:42:06 -05:00
SCOPE_CYCLE_COUNTER ( STAT_FDeferredShadingSceneRenderer_UpdateDownsampledDepthSurface ) ;
2015-03-26 18:31:22 -04:00
UpdateDownsampledDepthSurface ( RHICmdList ) ;
}
2015-04-09 19:14:28 -04:00
2016-02-04 23:40:42 -05:00
// Issue occlusion queries
// This is done after the downsampled depth buffer is created so that it can be used for issuing queries
BeginOcclusionTests ( RHICmdList , bRenderQueries ) ;
2015-03-26 18:31:22 -04:00
if ( bRenderHZB )
2016-02-04 23:40:42 -05:00
{
RHICmdList . TransitionResource ( EResourceTransitionAccess : : EReadable , SceneContext . GetSceneDepthSurface ( ) ) ;
2015-04-09 19:14:28 -04:00
static const auto ICVarAO = IConsoleManager : : Get ( ) . FindTConsoleVariableDataInt ( TEXT ( " r.AmbientOcclusionLevels " ) ) ;
static const auto ICVarHZBOcc = IConsoleManager : : Get ( ) . FindConsoleVariable ( TEXT ( " r.HZBOcclusion " ) ) ;
bool bSSAO = ICVarAO - > GetValueOnRenderThread ( ) ! = 0 ;
2016-02-04 23:40:42 -05:00
bool bHZBOcclusion = ICVarHZBOcc - > GetInt ( ) ! = 0 ;
2015-04-09 19:14:28 -04:00
2015-03-26 18:31:22 -04:00
for ( int32 ViewIndex = 0 ; ViewIndex < Views . Num ( ) ; ViewIndex + + )
{
2016-02-04 23:40:42 -05:00
FViewInfo & View = Views [ ViewIndex ] ;
FSceneViewState * ViewState = ( FSceneViewState * ) View . State ;
2015-04-09 19:14:28 -04:00
2016-04-04 18:44:59 -04:00
const uint32 bSSR = ShouldRenderScreenSpaceReflections ( View ) ;
2016-02-04 23:40:42 -05:00
if ( bSSAO | | bHZBOcclusion | | bSSR )
2015-04-09 19:14:28 -04:00
{
BuildHZB ( RHICmdList , Views [ ViewIndex ] ) ;
}
2016-02-04 23:40:42 -05:00
if ( bHZBOcclusion & & ViewState & & ViewState - > HZBOcclusionTests . GetNum ( ) ! = 0 )
{
check ( ViewState - > HZBOcclusionTests . IsValidFrame ( ViewState - > OcclusionFrameCounter ) ) ;
SCOPED_DRAW_EVENT ( RHICmdList , HZB ) ;
ViewState - > HZBOcclusionTests . Submit ( RHICmdList , View ) ;
}
2015-03-26 18:31:22 -04:00
}
2016-01-08 11:12:28 -05:00
//async ssao only requires HZB and depth as inputs so get started ASAP
if ( GCompositionLighting . CanProcessAsyncSSAO ( Views ) )
{
GCompositionLighting . ProcessAsyncSSAO ( RHICmdList , Views ) ;
}
2015-03-26 18:31:22 -04:00
}
2015-04-22 14:16:01 -04:00
// Hint to the RHI to submit commands up to this point to the GPU if possible. Can help avoid CPU stalls next frame waiting
// for these query results on some platforms.
RHICmdList . SubmitCommandsHint ( ) ;
2015-03-26 18:31:22 -04:00
if ( bRenderQueries & & GRHIThread )
{
2015-12-02 16:42:06 -05:00
SCOPE_CYCLE_COUNTER ( STAT_OcclusionSubmittedFence_Dispatch ) ;
2015-06-08 09:38:50 -04:00
int32 NumFrames = FOcclusionQueryHelpers : : GetNumBufferedFrames ( ) ;
for ( int32 Dest = 1 ; Dest < NumFrames ; Dest + + )
{
2016-06-01 12:08:56 -04:00
CA_SUPPRESS ( 6385 ) ;
2015-06-08 09:38:50 -04:00
OcclusionSubmittedFence [ Dest ] = OcclusionSubmittedFence [ Dest - 1 ] ;
2016-02-16 05:48:48 -05:00
}
2015-06-08 09:38:50 -04:00
OcclusionSubmittedFence [ 0 ] = RHICmdList . RHIThreadFence ( ) ;
2016-02-16 05:48:48 -05:00
RHICmdList . ImmediateFlush ( EImmediateFlushType : : DispatchToRHIThread ) ;
2015-03-26 18:31:22 -04:00
}
}
}
2015-05-29 10:47:57 -04:00
// The render thread is involved in sending stuff to the RHI, so we will periodically service that queue
2016-01-08 11:12:28 -05:00
void ServiceLocalQueue ( )
2015-05-29 10:47:57 -04:00
{
2015-12-02 16:42:06 -05:00
SCOPE_CYCLE_COUNTER ( STAT_FDeferredShadingSceneRenderer_Render_ServiceLocalQueue ) ;
2015-05-29 10:47:57 -04:00
FTaskGraphInterface : : Get ( ) . ProcessThreadUntilIdle ( ENamedThreads : : RenderThread_Local ) ;
}
2016-01-14 08:11:47 -05:00
// @return 0/1
static int32 GetCustomDepthPassLocation ( )
{
return FMath : : Clamp ( CVarCustomDepthOrder . GetValueOnRenderThread ( ) , 0 , 1 ) ;
}
2015-10-28 19:18:20 -04:00
extern bool IsLpvIndirectPassRequired ( const FViewInfo & View ) ;
2015-08-03 11:44:45 -04:00
static TAutoConsoleVariable < float > CVarStallInitViews (
TEXT ( " CriticalPathStall.AfterInitViews " ) ,
0.0f ,
TEXT ( " Sleep for the given time after InitViews. Time is given in ms. This is a debug option used for critical path analysis and forcing a change in the critical path. " ) ) ;
2014-06-27 11:07:13 -04:00
void FDeferredShadingSceneRenderer : : Render ( FRHICommandListImmediate & RHICmdList )
2014-03-14 14:13:41 -04:00
{
2015-05-29 10:47:57 -04:00
FSceneRenderTargets & SceneContext = FSceneRenderTargets : : Get ( RHICmdList ) ;
2015-07-29 16:42:44 -04:00
2015-09-21 20:07:00 -04:00
//make sure all the targets we're going to use will be safely writable.
GRenderTargetPool . TransitionTargetsWritable ( RHICmdList ) ;
2015-07-29 16:42:44 -04:00
// this way we make sure the SceneColor format is the correct one and not the one from the end of frame before
SceneContext . ReleaseSceneColor ( ) ;
2015-03-26 18:31:22 -04:00
bool bDBuffer = IsDBufferEnabled ( ) ;
2015-07-14 19:56:43 -04:00
2014-09-03 10:52:00 -04:00
if ( GRHIThread )
{
2015-12-02 16:42:06 -05:00
SCOPE_CYCLE_COUNTER ( STAT_OcclusionSubmittedFence_Wait ) ;
2015-06-08 09:38:50 -04:00
int32 BlockFrame = FOcclusionQueryHelpers : : GetNumBufferedFrames ( ) - 1 ;
FRHICommandListExecutor : : WaitOnRHIThreadFence ( OcclusionSubmittedFence [ BlockFrame ] ) ;
OcclusionSubmittedFence [ BlockFrame ] = nullptr ;
2014-09-03 10:52:00 -04:00
}
2015-07-14 19:56:43 -04:00
if ( ! ViewFamily . EngineShowFlags . Rendering )
2014-03-14 14:13:41 -04:00
{
return ;
}
2014-10-20 10:43:43 -04:00
SCOPED_DRAW_EVENT ( RHICmdList , Scene ) ;
2016-07-18 17:17:08 -04:00
// Anything rendered inside Render() which isn't accounted for will fall into this stat
// This works because child stat events do not contribute to their parents' times (see GPU_STATS_CHILD_TIMES_INCLUDED)
SCOPED_GPU_STAT ( RHICmdList , Stat_GPU_Unaccounted ) ;
2014-09-03 10:52:00 -04:00
2015-03-04 08:31:40 -05:00
{
2015-12-02 16:42:06 -05:00
SCOPE_CYCLE_COUNTER ( STAT_FDeferredShadingSceneRenderer_Render_Init ) ;
2014-03-14 14:13:41 -04:00
2015-03-04 08:31:40 -05:00
// Initialize global system textures (pass-through if already initialized).
GSystemTextures . InitializeTextures ( RHICmdList , FeatureLevel ) ;
2014-03-14 14:13:41 -04:00
2015-03-04 08:31:40 -05:00
// Allocate the maximum scene render target space for the current view family.
2015-09-21 20:07:00 -04:00
SceneContext . Allocate ( RHICmdList , ViewFamily ) ;
2015-03-04 08:31:40 -05:00
}
2015-07-14 19:56:43 -04:00
2016-02-16 05:48:48 -05:00
FGraphEventArray SortEvents ;
FILCUpdatePrimTaskData ILCTaskData ;
2014-03-14 14:13:41 -04:00
// Find the visible primitives.
2016-02-16 05:48:48 -05:00
bool bDoInitViewAftersPrepass = InitViews ( RHICmdList , ILCTaskData , SortEvents ) ;
2016-03-02 13:38:38 -05:00
TGuardValue < bool > LockDrawLists ( GDrawListsLocked , true ) ;
2015-08-03 11:44:45 -04:00
# if !UE_BUILD_SHIPPING
if ( CVarStallInitViews . GetValueOnRenderThread ( ) > 0.0f )
{
2015-12-02 16:42:06 -05:00
SCOPE_CYCLE_COUNTER ( STAT_InitViews_Intentional_Stall ) ;
2015-08-03 11:44:45 -04:00
FPlatformProcess : : Sleep ( CVarStallInitViews . GetValueOnRenderThread ( ) / 1000.0f ) ;
}
# endif
2014-03-14 14:13:41 -04:00
2015-05-29 10:47:57 -04:00
if ( GRHICommandList . UseParallelAlgorithms ( ) )
2014-09-03 10:52:00 -04:00
{
2015-05-29 10:47:57 -04:00
// there are dynamic attempts to get this target during parallel rendering
for ( int32 ViewIndex = 0 ; ViewIndex < Views . Num ( ) ; ViewIndex + + )
2015-07-14 19:56:43 -04:00
{
2015-09-21 20:07:00 -04:00
Views [ ViewIndex ] . GetEyeAdaptation ( RHICmdList ) ;
2015-05-29 10:47:57 -04:00
}
2014-09-03 10:52:00 -04:00
}
2015-05-18 13:21:23 -04:00
if ( ShouldPrepareDistanceFields ( ) )
2014-11-21 22:32:16 -05:00
{
2015-12-02 16:42:06 -05:00
SCOPE_CYCLE_COUNTER ( STAT_FDeferredShadingSceneRenderer_DistanceFieldAO_Init ) ;
2014-12-10 11:54:51 -05:00
GDistanceFieldVolumeTextureAtlas . UpdateAllocations ( ) ;
UpdateGlobalDistanceFieldObjectBuffers ( RHICmdList ) ;
2015-02-06 23:31:19 -05:00
for ( int32 ViewIndex = 0 ; ViewIndex < Views . Num ( ) ; ViewIndex + + )
{
Views [ ViewIndex ] . HeightfieldLightingViewInfo . SetupVisibleHeightfields ( Views [ ViewIndex ] , RHICmdList ) ;
2015-05-11 20:04:15 -04:00
if ( UseGlobalDistanceField ( ) )
{
// Use the skylight's max distance if there is one
2016-04-04 18:44:59 -04:00
const float OcclusionMaxDistance = Scene - > SkyLight & & ! Scene - > SkyLight - > bWantsStaticShadowing ? Scene - > SkyLight - > OcclusionMaxDistance : Scene - > DefaultMaxDistanceFieldOcclusionDistance ;
2015-05-11 20:04:15 -04:00
UpdateGlobalDistanceFieldVolume ( RHICmdList , Views [ ViewIndex ] , Scene , OcclusionMaxDistance , Views [ ViewIndex ] . GlobalDistanceFieldInfo ) ;
}
2015-02-06 23:31:19 -05:00
}
2014-11-21 22:32:16 -05:00
}
2014-09-03 10:52:00 -04:00
2015-05-29 10:47:57 -04:00
if ( GRHIThread )
{
// we will probably stall on occlusion queries, so might as well have the RHI thread and GPU work while we wait.
2015-12-02 16:42:06 -05:00
SCOPE_CYCLE_COUNTER ( STAT_PostInitViews_FlushDel ) ;
2015-05-29 10:47:57 -04:00
FRHICommandListExecutor : : GetImmediateCommandList ( ) . ImmediateFlush ( EImmediateFlushType : : FlushRHIThreadFlushResources ) ;
}
2014-03-14 14:13:41 -04:00
const bool bIsWireframe = ViewFamily . EngineShowFlags . Wireframe ;
static const auto ClearMethodCVar = IConsoleManager : : Get ( ) . FindTConsoleVariableDataInt ( TEXT ( " r.ClearSceneMethod " ) ) ;
bool bRequiresRHIClear = true ;
bool bRequiresFarZQuadClear = false ;
2016-07-11 18:51:20 -04:00
const bool bUseGBuffer = ! IsAnyForwardShadingEnabled ( GetFeatureLevelShaderPlatform ( FeatureLevel ) ) ;
2014-07-29 17:32:52 -04:00
2014-03-14 14:13:41 -04:00
if ( ClearMethodCVar )
{
2015-04-17 11:11:12 -04:00
int32 clearMethod = ClearMethodCVar - > GetValueOnRenderThread ( ) ;
if ( clearMethod = = 0 & & ! ViewFamily . EngineShowFlags . Game )
{
// Do not clear the scene only if the view family is in game mode.
clearMethod = 1 ;
}
switch ( clearMethod )
2014-03-14 14:13:41 -04:00
{
case 0 : // No clear
{
bRequiresRHIClear = false ;
bRequiresFarZQuadClear = false ;
break ;
}
2014-06-27 11:07:13 -04:00
case 1 : // RHICmdList.Clear
2014-03-14 14:13:41 -04:00
{
bRequiresRHIClear = true ;
bRequiresFarZQuadClear = false ;
break ;
}
case 2 : // Clear using far-z quad
{
bRequiresFarZQuadClear = true ;
bRequiresRHIClear = false ;
break ;
}
}
}
// Always perform a full buffer clear for wireframe, shader complexity view mode, and stationary light overlap viewmode.
if ( bIsWireframe | | ViewFamily . EngineShowFlags . ShaderComplexity | | ViewFamily . EngineShowFlags . StationaryLightOverlap )
{
bRequiresRHIClear = true ;
}
// force using occ queries for wireframe if rendering is parented or frozen in the first view
check ( Views . Num ( ) ) ;
# if (UE_BUILD_SHIPPING || UE_BUILD_TEST)
const bool bIsViewFrozen = false ;
const bool bHasViewParent = false ;
# else
const bool bIsViewFrozen = Views [ 0 ] . State & & ( ( FSceneViewState * ) Views [ 0 ] . State ) - > bIsFrozen ;
const bool bHasViewParent = Views [ 0 ] . State & & ( ( FSceneViewState * ) Views [ 0 ] . State ) - > HasViewParent ( ) ;
# endif
2014-06-05 16:38:54 -04:00
2014-06-27 11:07:13 -04:00
2014-08-19 10:41:34 -04:00
const bool bIsOcclusionTesting = DoOcclusionQueries ( FeatureLevel ) & & ( ! bIsWireframe | | bIsViewFrozen | | bHasViewParent ) ;
2014-03-14 14:13:41 -04:00
// Dynamic vertex and index buffers need to be committed before rendering.
2016-02-16 05:48:48 -05:00
if ( ! bDoInitViewAftersPrepass )
2015-03-04 08:31:40 -05:00
{
2016-02-16 05:48:48 -05:00
{
SCOPE_CYCLE_COUNTER ( STAT_FDeferredShadingSceneRenderer_FGlobalDynamicVertexBuffer_Commit ) ;
FGlobalDynamicVertexBuffer : : Get ( ) . Commit ( ) ;
FGlobalDynamicIndexBuffer : : Get ( ) . Commit ( ) ;
}
2015-03-04 08:31:40 -05:00
}
2015-04-27 14:32:32 -04:00
{
2015-12-02 16:42:06 -05:00
SCOPE_CYCLE_COUNTER ( STAT_FDeferredShadingSceneRenderer_MotionBlurStartFrame ) ;
2015-04-27 14:32:32 -04:00
Scene - > MotionBlurInfoData . StartFrame ( ViewFamily . bWorldIsPaused ) ;
}
2014-03-14 14:13:41 -04:00
// Notify the FX system that the scene is about to be rendered.
2016-01-27 07:18:43 -05:00
bool bLateFXPrerender = CVarFXSystemPreRenderAfterPrepass . GetValueOnRenderThread ( ) > 0 ;
bool bDoFXPrerender = Scene - > FXSystem & & Views . IsValidIndex ( 0 ) ;
if ( ! bLateFXPrerender & & bDoFXPrerender )
2014-03-14 14:13:41 -04:00
{
2015-12-02 16:42:06 -05:00
SCOPE_CYCLE_COUNTER ( STAT_FDeferredShadingSceneRenderer_FXSystem_PreRender ) ;
2016-02-16 05:48:48 -05:00
RHICmdList . SetCurrentStat ( GET_STATID ( STAT_CLM_FXPreRender ) ) ;
2015-05-18 13:21:23 -04:00
Scene - > FXSystem - > PreRender ( RHICmdList , & Views [ 0 ] . GlobalDistanceFieldInfo . ParameterData ) ;
2014-03-14 14:13:41 -04:00
}
2016-01-08 11:12:28 -05:00
if ( GEnableGPUSkinCache )
{
GGPUSkinCache . TransitionToReadable ( RHICmdList ) ;
}
2016-02-16 05:48:48 -05:00
bool bDidAfterTaskWork = false ;
auto AfterTasksAreStarted = [ & bDidAfterTaskWork , bDoInitViewAftersPrepass , this , & RHICmdList , & ILCTaskData , & SortEvents , bLateFXPrerender , bDoFXPrerender ] ( )
{
if ( ! bDidAfterTaskWork )
{
QUICK_SCOPE_CYCLE_COUNTER ( STAT_AfterPrepassTasksWork ) ;
bDidAfterTaskWork = true ; // only do this once
if ( bDoInitViewAftersPrepass )
{
InitViewsPossiblyAfterPrepass ( RHICmdList , ILCTaskData , SortEvents ) ;
{
SCOPE_CYCLE_COUNTER ( STAT_FDeferredShadingSceneRenderer_FGlobalDynamicVertexBuffer_Commit ) ;
FGlobalDynamicVertexBuffer : : Get ( ) . Commit ( ) ;
FGlobalDynamicIndexBuffer : : Get ( ) . Commit ( ) ;
}
ServiceLocalQueue ( ) ;
}
if ( bLateFXPrerender & & bDoFXPrerender )
{
SCOPE_CYCLE_COUNTER ( STAT_FDeferredShadingSceneRenderer_FXSystem_PreRender ) ;
RHICmdList . SetCurrentStat ( GET_STATID ( STAT_CLM_FXPreRender ) ) ;
Scene - > FXSystem - > PreRender ( RHICmdList , & Views [ 0 ] . GlobalDistanceFieldInfo . ParameterData ) ;
ServiceLocalQueue ( ) ;
}
}
} ;
2014-03-14 14:13:41 -04:00
// Draw the scene pre-pass / early z pass, populating the scene depth buffer and HiZ
2016-02-16 05:48:48 -05:00
GRenderTargetPool . AddPhaseEvent ( TEXT ( " EarlyZPass " ) ) ;
2015-03-26 18:31:22 -04:00
const bool bNeedsPrePass = NeedsPrePass ( this ) ;
2016-01-27 07:18:43 -05:00
bool bDepthWasCleared ;
2015-03-26 18:31:22 -04:00
if ( bNeedsPrePass )
2014-10-23 16:31:43 -04:00
{
2016-02-16 05:48:48 -05:00
bDepthWasCleared = RenderPrePass ( RHICmdList , AfterTasksAreStarted ) ;
2016-01-27 07:18:43 -05:00
}
else
{
// we didn't do the prepass, but we still want the HMD mask if there is one
2016-02-16 05:48:48 -05:00
AfterTasksAreStarted ( ) ;
RHICmdList . SetCurrentStat ( GET_STATID ( STAT_CLM_PrePass ) ) ;
2016-01-27 07:18:43 -05:00
bDepthWasCleared = RenderPrePassHMD ( RHICmdList ) ;
2014-10-23 16:31:43 -04:00
}
2016-02-16 05:48:48 -05:00
check ( bDidAfterTaskWork ) ;
2014-10-02 11:20:07 -04:00
RHICmdList . SetCurrentStat ( GET_STATID ( STAT_CLM_AfterPrePass ) ) ;
2015-05-29 10:47:57 -04:00
ServiceLocalQueue ( ) ;
2016-01-08 11:12:28 -05:00
2016-02-16 05:48:48 -05:00
2015-02-02 18:00:05 -05:00
const bool bShouldRenderVelocities = ShouldRenderVelocities ( ) ;
const bool bUseVelocityGBuffer = FVelocityRendering : : OutputsToGBuffer ( ) ;
2015-09-23 12:52:42 -04:00
const bool bUseSelectiveBasePassOutputs = UseSelectiveBasePassOutputs ( ) ;
2015-03-04 08:31:40 -05:00
{
2015-12-02 16:42:06 -05:00
SCOPE_CYCLE_COUNTER ( STAT_FDeferredShadingSceneRenderer_AllocGBufferTargets ) ;
2015-09-23 12:52:42 -04:00
SceneContext . PreallocGBufferTargets ( bUseVelocityGBuffer ) ; // Even if !bShouldRenderVelocities, the velocity buffer must be bound because it's a compile time option for the shader.
2015-09-21 20:07:00 -04:00
SceneContext . AllocGBufferTargets ( RHICmdList ) ;
2015-03-04 08:31:40 -05:00
}
2016-01-08 11:12:28 -05:00
//occlusion can't run before basepass if there's no prepass to fill in some depth to occlude against.
2016-07-11 18:51:20 -04:00
bool bOcclusionBeforeBasePass = ( ( CVarOcclusionQueryLocation . GetValueOnRenderThread ( ) = = 1 ) & & bNeedsPrePass ) | | IsForwardShadingEnabled ( FeatureLevel ) ;
2016-01-08 11:12:28 -05:00
bool bHZBBeforeBasePass = bOcclusionBeforeBasePass & & ( EarlyZPassMode = = EDepthDrawingMode : : DDM_AllOccluders ) ;
RenderOcclusion ( RHICmdList , bOcclusionBeforeBasePass , bHZBBeforeBasePass ) ;
ServiceLocalQueue ( ) ;
2016-01-14 08:11:47 -05:00
2016-06-27 13:42:20 -04:00
if ( bOcclusionBeforeBasePass )
{
RenderShadowDepthMaps ( RHICmdList ) ;
ServiceLocalQueue ( ) ;
}
2014-03-14 14:13:41 -04:00
// Clear LPVs for all views
2015-07-14 19:56:43 -04:00
if ( FeatureLevel > = ERHIFeatureLevel : : SM5 )
2014-03-14 14:13:41 -04:00
{
2015-12-02 16:42:06 -05:00
SCOPE_CYCLE_COUNTER ( STAT_FDeferredShadingSceneRenderer_ClearLPVs ) ;
2014-06-05 16:38:54 -04:00
ClearLPVs ( RHICmdList ) ;
2015-05-29 10:47:57 -04:00
ServiceLocalQueue ( ) ;
2014-03-14 14:13:41 -04:00
}
2016-01-14 08:11:47 -05:00
if ( GetCustomDepthPassLocation ( ) = = 0 )
{
QUICK_SCOPE_CYCLE_COUNTER ( STAT_FDeferredShadingSceneRenderer_CustomDepthPass0 ) ;
RenderCustomDepthPassAtLocation ( RHICmdList , 0 ) ;
}
2016-01-08 11:12:28 -05:00
2016-07-11 18:51:20 -04:00
ComputeLightGrid ( RHICmdList ) ;
if ( IsForwardShadingEnabled ( FeatureLevel ) )
{
RenderForwardShadingShadowProjections ( RHICmdList ) ;
RenderIndirectCapsuleShadows (
RHICmdList ,
NULL ,
NULL ) ;
}
2014-03-14 14:13:41 -04:00
// only temporarily available after early z pass and until base pass
2015-05-29 10:47:57 -04:00
check ( ! SceneContext . DBufferA ) ;
check ( ! SceneContext . DBufferB ) ;
check ( ! SceneContext . DBufferC ) ;
2014-03-14 14:13:41 -04:00
2015-07-14 19:56:43 -04:00
if ( bDBuffer )
2014-03-14 14:13:41 -04:00
{
2015-12-02 16:42:06 -05:00
SCOPE_CYCLE_COUNTER ( STAT_FDeferredShadingSceneRenderer_DBuffer ) ;
2015-05-29 10:47:57 -04:00
SceneContext . ResolveSceneDepthTexture ( RHICmdList ) ;
SceneContext . ResolveSceneDepthToAuxiliaryTexture ( RHICmdList ) ;
2014-03-14 14:13:41 -04:00
2015-04-23 13:22:07 -04:00
// e.g. DBuffer deferred decals
2014-03-14 14:13:41 -04:00
for ( int32 ViewIndex = 0 ; ViewIndex < Views . Num ( ) ; ViewIndex + + )
{
2014-10-20 10:43:43 -04:00
SCOPED_CONDITIONAL_DRAW_EVENTF ( RHICmdList , EventView , Views . Num ( ) > 1 , TEXT ( " View%d " ) , ViewIndex ) ;
2015-04-23 13:22:07 -04:00
2014-06-27 11:07:13 -04:00
GCompositionLighting . ProcessBeforeBasePass ( RHICmdList , Views [ ViewIndex ] ) ;
2014-03-14 14:13:41 -04:00
}
2015-10-10 17:47:14 -04:00
//GBuffer pass will want to write to SceneDepthZ
RHICmdList . TransitionResource ( EResourceTransitionAccess : : EWritable , SceneContext . GetSceneDepthTexture ( ) ) ;
2015-05-29 10:47:57 -04:00
ServiceLocalQueue ( ) ;
2014-03-14 14:13:41 -04:00
}
2014-10-27 20:23:51 -04:00
// Clear the G Buffer render targets
bool bIsGBufferCurrent = false ;
if ( bRequiresRHIClear )
{
2015-12-02 16:42:06 -05:00
SCOPE_CYCLE_COUNTER ( STAT_FDeferredShadingSceneRenderer_SetAndClearViewGBuffer ) ;
2014-10-27 20:23:51 -04:00
// set GBuffer to be current, and clear it
SetAndClearViewGBuffer ( RHICmdList , Views [ 0 ] , ! bDepthWasCleared ) ;
// depth was cleared now no matter what
bDepthWasCleared = true ;
bIsGBufferCurrent = true ;
2015-05-29 10:47:57 -04:00
ServiceLocalQueue ( ) ;
2014-10-27 20:23:51 -04:00
}
2015-07-14 19:56:43 -04:00
if ( bIsWireframe & & FSceneRenderer : : ShouldCompositeEditorPrimitives ( Views [ 0 ] ) )
2014-03-14 14:13:41 -04:00
{
// In Editor we want wire frame view modes to be MSAA for better quality. Resolve will be done with EditorPrimitives
2015-09-21 20:07:00 -04:00
SetRenderTarget ( RHICmdList , SceneContext . GetEditorPrimitivesColor ( RHICmdList ) , SceneContext . GetEditorPrimitivesDepth ( RHICmdList ) , ESimpleRenderTargetMode : : EClearColorAndDepth ) ;
2014-03-14 14:13:41 -04:00
}
2014-10-27 20:23:51 -04:00
else if ( ! bIsGBufferCurrent )
2014-03-14 14:13:41 -04:00
{
2014-10-27 20:23:51 -04:00
// make sure the GBuffer is set, in case we didn't need to clear above
2014-10-23 16:31:43 -04:00
ERenderTargetLoadAction DepthLoadAction = bDepthWasCleared ? ERenderTargetLoadAction : : ELoad : ERenderTargetLoadAction : : EClear ;
2015-11-10 17:11:09 -05:00
SceneContext . BeginRenderingGBuffer ( RHICmdList , ERenderTargetLoadAction : : ENoAction , DepthLoadAction , ViewFamily . EngineShowFlags . ShaderComplexity ) ;
2014-03-14 14:13:41 -04:00
}
2016-07-11 18:51:20 -04:00
if ( GbEnableAsyncComputeTranslucencyLightingVolumeClear & & GSupportsEfficientAsyncCompute )
{
ClearTranslucentVolumeLightingAsyncCompute ( RHICmdList ) ;
}
2014-04-23 19:52:11 -04:00
GRenderTargetPool . AddPhaseEvent ( TEXT ( " BasePass " ) ) ;
2014-10-02 11:20:07 -04:00
RHICmdList . SetCurrentStat ( GET_STATID ( STAT_CLM_BasePass ) ) ;
2014-06-27 11:07:13 -04:00
RenderBasePass ( RHICmdList ) ;
2014-10-02 11:20:07 -04:00
RHICmdList . SetCurrentStat ( GET_STATID ( STAT_CLM_AfterBasePass ) ) ;
2015-05-29 10:47:57 -04:00
ServiceLocalQueue ( ) ;
2014-03-14 14:13:41 -04:00
2015-07-14 19:56:43 -04:00
if ( ViewFamily . EngineShowFlags . VisualizeLightCulling )
2016-01-08 11:12:28 -05:00
{
// clear out emissive and baked lighting (not too efficient but simple and only needed for this debug view)
SceneContext . BeginRenderingSceneColor ( RHICmdList ) ;
RHICmdList . Clear ( true , FLinearColor ( 0 , 0 , 0 , 0 ) , false , ( float ) ERHIZBuffer : : FarPlane , false , 0 , FIntRect ( ) ) ;
}
2014-03-14 14:13:41 -04:00
2016-01-08 11:12:28 -05:00
SceneContext . DBufferA . SafeRelease ( ) ;
SceneContext . DBufferB . SafeRelease ( ) ;
SceneContext . DBufferC . SafeRelease ( ) ;
2014-03-14 14:13:41 -04:00
2016-01-08 11:12:28 -05:00
// only temporarily available after early z pass and until base pass
check ( ! SceneContext . DBufferA ) ;
check ( ! SceneContext . DBufferB ) ;
check ( ! SceneContext . DBufferC ) ;
2014-03-14 14:13:41 -04:00
if ( bRequiresFarZQuadClear )
{
2015-12-02 16:42:06 -05:00
SCOPE_CYCLE_COUNTER ( STAT_FDeferredShadingSceneRenderer_ClearGBufferAtMaxZ ) ;
2014-03-14 14:13:41 -04:00
// Clears view by drawing quad at maximum Z
2014-06-27 11:07:13 -04:00
// TODO: if all the platforms have fast color clears, we can replace this with an RHICmdList.Clear.
2014-06-12 07:13:34 -04:00
ClearGBufferAtMaxZ ( RHICmdList ) ;
2015-05-29 10:47:57 -04:00
ServiceLocalQueue ( ) ;
2014-03-14 14:13:41 -04:00
bRequiresFarZQuadClear = false ;
}
2015-10-30 17:41:13 -04:00
2015-09-21 20:07:00 -04:00
{
2015-12-02 16:42:06 -05:00
SCOPE_CYCLE_COUNTER ( STAT_FDeferredShadingSceneRenderer_ResolveDepth_After_Basepass ) ;
2015-05-29 10:47:57 -04:00
SceneContext . ResolveSceneDepthTexture ( RHICmdList ) ;
SceneContext . ResolveSceneDepthToAuxiliaryTexture ( RHICmdList ) ;
2015-09-21 20:07:00 -04:00
}
2014-03-14 14:13:41 -04:00
2015-09-21 20:07:00 -04:00
bool bOcclusionAfterBasePass = bIsOcclusionTesting & & ! bOcclusionBeforeBasePass ;
2016-01-08 11:12:28 -05:00
bool bHZBAfterBasePass = ! bHZBBeforeBasePass ;
2015-09-21 20:07:00 -04:00
RenderOcclusion ( RHICmdList , bOcclusionAfterBasePass , bHZBAfterBasePass ) ;
ServiceLocalQueue ( ) ;
2016-06-27 13:42:20 -04:00
if ( ! bOcclusionBeforeBasePass )
{
RenderShadowDepthMaps ( RHICmdList ) ;
ServiceLocalQueue ( ) ;
}
2015-09-21 20:07:00 -04:00
{
2015-12-02 16:42:06 -05:00
SCOPE_CYCLE_COUNTER ( STAT_FDeferredShadingSceneRenderer_Resolve_After_Basepass ) ;
2015-09-21 20:07:00 -04:00
SceneContext . ResolveSceneColor ( RHICmdList , FResolveRect ( 0 , 0 , ViewFamily . FamilySizeX , ViewFamily . FamilySizeY ) ) ;
2015-05-29 10:47:57 -04:00
SceneContext . FinishRenderingGBuffer ( RHICmdList ) ;
2015-03-04 08:31:40 -05:00
}
2015-09-21 20:07:00 -04:00
2016-01-14 08:11:47 -05:00
if ( GetCustomDepthPassLocation ( ) = = 1 )
{
QUICK_SCOPE_CYCLE_COUNTER ( STAT_FDeferredShadingSceneRenderer_CustomDepthPass1 ) ;
RenderCustomDepthPassAtLocation ( RHICmdList , 1 ) ;
}
ServiceLocalQueue ( ) ;
2016-01-08 11:12:28 -05:00
2014-03-14 14:13:41 -04:00
// Notify the FX system that opaque primitives have been rendered and we now have a valid depth buffer.
if ( Scene - > FXSystem & & Views . IsValidIndex ( 0 ) )
{
2015-12-02 16:42:06 -05:00
SCOPE_CYCLE_COUNTER ( STAT_FDeferredShadingSceneRenderer_FXSystem_PostRenderOpaque ) ;
2014-03-14 14:13:41 -04:00
Scene - > FXSystem - > PostRenderOpaque (
2014-06-27 11:07:13 -04:00
RHICmdList ,
2014-09-29 04:23:44 -04:00
Views . GetData ( ) ,
2015-05-29 10:47:57 -04:00
SceneContext . GetSceneDepthTexture ( ) ,
SceneContext . GetGBufferATexture ( )
2014-03-14 14:13:41 -04:00
) ;
2015-05-29 10:47:57 -04:00
ServiceLocalQueue ( ) ;
2014-03-14 14:13:41 -04:00
}
2015-02-19 16:09:15 -05:00
TRefCountPtr < IPooledRenderTarget > VelocityRT ;
if ( bUseVelocityGBuffer )
{
2015-05-29 10:47:57 -04:00
VelocityRT = SceneContext . GetGBufferVelocityRT ( ) ;
2015-02-19 16:09:15 -05:00
}
2015-09-23 12:52:42 -04:00
if ( bShouldRenderVelocities & & ( ! bUseVelocityGBuffer | | bUseSelectiveBasePassOutputs ) )
2015-02-19 16:09:15 -05:00
{
// Render the velocities of movable objects
RHICmdList . SetCurrentStat ( GET_STATID ( STAT_CLM_Velocity ) ) ;
RenderVelocities ( RHICmdList , VelocityRT ) ;
RHICmdList . SetCurrentStat ( GET_STATID ( STAT_CLM_AfterVelocity ) ) ;
2015-05-29 10:47:57 -04:00
ServiceLocalQueue ( ) ;
2015-02-19 16:09:15 -05:00
}
2015-11-10 17:11:09 -05:00
// Copy lighting channels out of stencil before deferred decals which overwrite those values
CopyStencilToLightingChannelTexture ( RHICmdList ) ;
2016-07-11 18:51:20 -04:00
{
GCompositionLighting . GfxWaitForAsyncSSAO ( RHICmdList ) ;
}
2015-04-13 15:39:50 -04:00
// Pre-lighting composition lighting stage
2015-11-10 17:11:09 -05:00
// e.g. deferred decals, SSAO
2016-06-02 13:13:43 -04:00
if ( FeatureLevel > = ERHIFeatureLevel : : SM4 )
2015-04-13 15:39:50 -04:00
{
2015-12-02 16:42:06 -05:00
SCOPE_CYCLE_COUNTER ( STAT_FDeferredShadingSceneRenderer_AfterBasePass ) ;
2015-04-13 15:39:50 -04:00
GRenderTargetPool . AddPhaseEvent ( TEXT ( " AfterBasePass " ) ) ;
for ( int32 ViewIndex = 0 ; ViewIndex < Views . Num ( ) ; ViewIndex + + )
{
SCOPED_CONDITIONAL_DRAW_EVENTF ( RHICmdList , EventView , Views . Num ( ) > 1 , TEXT ( " View%d " ) , ViewIndex ) ;
GCompositionLighting . ProcessAfterBasePass ( RHICmdList , Views [ ViewIndex ] ) ;
}
2015-05-29 10:47:57 -04:00
ServiceLocalQueue ( ) ;
2015-04-13 15:39:50 -04:00
}
2015-11-10 17:11:09 -05:00
{
SCOPED_DRAW_EVENT ( RHICmdList , ClearStencilFromBasePass ) ;
FRHISetRenderTargetsInfo Info ( 0 , NULL , FRHIDepthRenderTargetView (
2016-01-08 11:12:28 -05:00
SceneContext . GetSceneDepthSurface ( ) ,
ERenderTargetLoadAction : : ENoAction ,
ERenderTargetStoreAction : : ENoAction ,
ERenderTargetLoadAction : : EClear ,
ERenderTargetStoreAction : : EStore ,
FExclusiveDepthStencil : : DepthNop_StencilWrite ) ) ;
2015-11-10 17:11:09 -05:00
// Clear stencil to 0 now that deferred decals are done using what was setup in the base pass
// Shadow passes and other users of stencil assume it is cleared to 0 going in
RHICmdList . SetRenderTargetsAndClear ( Info ) ;
RHICmdList . TransitionResource ( EResourceTransitionAccess : : EReadable , SceneContext . GetSceneDepthSurface ( ) ) ;
}
2014-03-14 14:13:41 -04:00
// Render lighting.
if ( ViewFamily . EngineShowFlags . Lighting
2014-05-08 09:05:50 -04:00
& & FeatureLevel > = ERHIFeatureLevel : : SM4
2014-03-14 14:13:41 -04:00
& & ViewFamily . EngineShowFlags . DeferredLighting
2016-05-18 09:31:59 -04:00
& & bUseGBuffer )
2014-03-14 14:13:41 -04:00
{
2015-12-02 16:42:06 -05:00
SCOPE_CYCLE_COUNTER ( STAT_FDeferredShadingSceneRenderer_Lighting ) ;
2015-03-04 08:31:40 -05:00
2014-04-23 19:52:11 -04:00
GRenderTargetPool . AddPhaseEvent ( TEXT ( " Lighting " ) ) ;
2015-12-10 21:55:37 -05:00
// These modulate the scenecolor output from the basepass, which is assumed to be indirect lighting
2016-07-11 18:51:20 -04:00
RenderIndirectCapsuleShadows (
RHICmdList ,
SceneContext . GetSceneColorSurface ( ) ,
SceneContext . bScreenSpaceAOIsValid ? SceneContext . ScreenSpaceAO - > GetRenderTargetItem ( ) . TargetableTexture : NULL ) ;
2015-12-10 21:55:37 -05:00
2016-03-02 13:38:38 -05:00
TRefCountPtr < IPooledRenderTarget > DynamicBentNormalAO ;
// These modulate the scenecolor output from the basepass, which is assumed to be indirect lighting
RenderDFAOAsIndirectShadowing ( RHICmdList , VelocityRT , DynamicBentNormalAO ) ;
2014-03-14 14:13:41 -04:00
// Clear the translucent lighting volumes before we accumulate
2016-07-11 18:51:20 -04:00
if ( ( GbEnableAsyncComputeTranslucencyLightingVolumeClear & & GSupportsEfficientAsyncCompute ) = = false )
{
ClearTranslucentVolumeLighting ( RHICmdList ) ;
}
2014-03-14 14:13:41 -04:00
2014-10-02 11:20:07 -04:00
RHICmdList . SetCurrentStat ( GET_STATID ( STAT_CLM_Lighting ) ) ;
2014-06-05 16:38:54 -04:00
RenderLights ( RHICmdList ) ;
2014-10-02 11:20:07 -04:00
RHICmdList . SetCurrentStat ( GET_STATID ( STAT_CLM_AfterLighting ) ) ;
2015-05-29 10:47:57 -04:00
ServiceLocalQueue ( ) ;
2014-03-14 14:13:41 -04:00
2014-06-30 16:04:34 -04:00
GRenderTargetPool . AddPhaseEvent ( TEXT ( " AfterRenderLights " ) ) ;
2014-06-05 16:38:54 -04:00
InjectAmbientCubemapTranslucentVolumeLighting ( RHICmdList ) ;
2015-05-29 10:47:57 -04:00
ServiceLocalQueue ( ) ;
2014-03-14 14:13:41 -04:00
// Filter the translucency lighting volume now that it is complete
2014-06-12 07:13:34 -04:00
FilterTranslucentVolumeLighting ( RHICmdList ) ;
2015-05-29 10:47:57 -04:00
ServiceLocalQueue ( ) ;
2014-03-14 14:13:41 -04:00
2015-05-15 18:54:37 -04:00
// Pre-lighting composition lighting stage
// e.g. LPV indirect
2015-07-14 19:56:43 -04:00
for ( int32 ViewIndex = 0 ; ViewIndex < Views . Num ( ) ; + + ViewIndex )
2015-05-29 10:47:57 -04:00
{
2015-10-28 08:58:16 -04:00
FViewInfo & View = Views [ ViewIndex ] ;
if ( IsLpvIndirectPassRequired ( View ) )
{
SCOPED_CONDITIONAL_DRAW_EVENTF ( RHICmdList , EventView , Views . Num ( ) > 1 , TEXT ( " View%d " ) , ViewIndex ) ;
GCompositionLighting . ProcessLpvIndirect ( RHICmdList , View ) ;
ServiceLocalQueue ( ) ;
}
2014-03-14 14:13:41 -04:00
}
2015-02-19 16:09:15 -05:00
RenderDynamicSkyLighting ( RHICmdList , VelocityRT , DynamicBentNormalAO ) ;
2015-05-29 10:47:57 -04:00
ServiceLocalQueue ( ) ;
2014-08-28 13:54:31 -04:00
2015-05-15 18:54:37 -04:00
// SSS need the SceneColor finalized as an SRV.
2015-05-29 10:47:57 -04:00
SceneContext . FinishRenderingSceneColor ( RHICmdList , true ) ;
2015-01-27 16:14:50 -05:00
2014-03-14 14:13:41 -04:00
// Render reflections that only operate on opaque pixels
2014-08-28 13:54:31 -04:00
RenderDeferredReflections ( RHICmdList , DynamicBentNormalAO ) ;
2015-05-29 10:47:57 -04:00
ServiceLocalQueue ( ) ;
2014-03-14 14:13:41 -04:00
// Post-lighting composition lighting stage
2015-05-15 18:54:37 -04:00
// e.g. ScreenSpaceSubsurfaceScattering
2014-03-14 14:13:41 -04:00
for ( int32 ViewIndex = 0 ; ViewIndex < Views . Num ( ) ; + + ViewIndex )
{
2014-10-20 10:43:43 -04:00
SCOPED_CONDITIONAL_DRAW_EVENTF ( RHICmdList , EventView , Views . Num ( ) > 1 , TEXT ( " View%d " ) , ViewIndex ) ;
2015-05-15 18:54:37 -04:00
GCompositionLighting . ProcessAfterLighting ( RHICmdList , Views [ ViewIndex ] ) ;
2014-03-14 14:13:41 -04:00
}
2015-05-29 10:47:57 -04:00
ServiceLocalQueue ( ) ;
2014-03-14 14:13:41 -04:00
}
2015-07-14 19:56:43 -04:00
if ( ViewFamily . EngineShowFlags . StationaryLightOverlap & &
2014-05-08 09:05:50 -04:00
FeatureLevel > = ERHIFeatureLevel : : SM4 )
2014-03-14 14:13:41 -04:00
{
2014-06-12 07:13:34 -04:00
RenderStationaryLightOverlap ( RHICmdList ) ;
2015-05-29 10:47:57 -04:00
ServiceLocalQueue ( ) ;
2014-03-14 14:13:41 -04:00
}
FLightShaftsOutput LightShaftOutput ;
// Draw Lightshafts
if ( ViewFamily . EngineShowFlags . LightShafts )
{
2015-12-02 16:42:06 -05:00
SCOPE_CYCLE_COUNTER ( STAT_FDeferredShadingSceneRenderer_RenderLightShaftOcclusion ) ;
2015-10-28 08:58:16 -04:00
RenderLightShaftOcclusion ( RHICmdList , LightShaftOutput ) ;
2015-05-29 10:47:57 -04:00
ServiceLocalQueue ( ) ;
2014-03-14 14:13:41 -04:00
}
// Draw atmosphere
2015-07-14 19:56:43 -04:00
if ( ShouldRenderAtmosphere ( ViewFamily ) )
2014-03-14 14:13:41 -04:00
{
2015-12-02 16:42:06 -05:00
SCOPE_CYCLE_COUNTER ( STAT_FDeferredShadingSceneRenderer_RenderAtmosphere ) ;
2014-03-14 14:13:41 -04:00
if ( Scene - > AtmosphericFog )
{
// Update RenderFlag based on LightShaftTexture is valid or not
2015-10-28 08:58:16 -04:00
if ( LightShaftOutput . LightShaftOcclusion )
2014-03-14 14:13:41 -04:00
{
Scene - > AtmosphericFog - > RenderFlag & = EAtmosphereRenderFlag : : E_LightShaftMask ;
}
else
{
Scene - > AtmosphericFog - > RenderFlag | = EAtmosphereRenderFlag : : E_DisableLightShaft ;
}
# if WITH_EDITOR
if ( Scene - > bIsEditorScene )
{
// Precompute Atmospheric Textures
2014-09-29 04:23:44 -04:00
Scene - > AtmosphericFog - > PrecomputeTextures ( RHICmdList , Views . GetData ( ) , & ViewFamily ) ;
2014-03-14 14:13:41 -04:00
}
# endif
2014-06-27 11:07:13 -04:00
RenderAtmosphere ( RHICmdList , LightShaftOutput ) ;
2015-05-29 10:47:57 -04:00
ServiceLocalQueue ( ) ;
2014-03-14 14:13:41 -04:00
}
}
2014-04-23 19:52:11 -04:00
GRenderTargetPool . AddPhaseEvent ( TEXT ( " Fog " ) ) ;
2014-03-14 14:13:41 -04:00
// Draw fog.
2015-07-14 19:56:43 -04:00
if ( ShouldRenderFog ( ViewFamily ) )
2014-03-14 14:13:41 -04:00
{
2015-12-02 16:42:06 -05:00
SCOPE_CYCLE_COUNTER ( STAT_FDeferredShadingSceneRenderer_RenderFog ) ;
2014-06-12 07:13:34 -04:00
RenderFog ( RHICmdList , LightShaftOutput ) ;
2015-05-29 10:47:57 -04:00
ServiceLocalQueue ( ) ;
2014-03-14 14:13:41 -04:00
}
2015-07-14 19:56:43 -04:00
if ( GetRendererModule ( ) . HasPostOpaqueExtentions ( ) )
{
SceneContext . BeginRenderingSceneColor ( RHICmdList ) ;
for ( int32 ViewIndex = 0 ; ViewIndex < Views . Num ( ) ; + + ViewIndex )
{
const FViewInfo & View = Views [ ViewIndex ] ;
RHICmdList . SetViewport ( View . ViewRect . Min . X , View . ViewRect . Min . Y , 0.0f , View . ViewRect . Max . X , View . ViewRect . Max . Y , 1.0f ) ;
GetRendererModule ( ) . RenderPostOpaqueExtensions ( View , RHICmdList , SceneContext ) ;
}
2015-10-31 14:47:30 -04:00
SceneContext . FinishRenderingSceneColor ( RHICmdList , true ) ;
2015-07-14 19:56:43 -04:00
}
2014-03-14 14:13:41 -04:00
// No longer needed, release
LightShaftOutput . LightShaftOcclusion = NULL ;
2014-04-23 19:52:11 -04:00
GRenderTargetPool . AddPhaseEvent ( TEXT ( " Translucency " ) ) ;
2014-03-14 14:13:41 -04:00
// Draw translucency.
2015-07-14 19:56:43 -04:00
if ( ViewFamily . EngineShowFlags . Translucency )
2014-03-14 14:13:41 -04:00
{
SCOPE_CYCLE_COUNTER ( STAT_TranslucencyDrawTime ) ;
2014-10-02 11:20:07 -04:00
RHICmdList . SetCurrentStat ( GET_STATID ( STAT_CLM_Translucency ) ) ;
2014-06-27 11:07:13 -04:00
RenderTranslucency ( RHICmdList ) ;
2015-05-29 10:47:57 -04:00
ServiceLocalQueue ( ) ;
2014-06-24 20:14:10 -04:00
2015-08-28 17:18:26 -04:00
if ( GetRefractionQuality ( ViewFamily ) > 0 )
2014-03-14 14:13:41 -04:00
{
2014-06-24 20:14:10 -04:00
// To apply refraction effect by distorting the scene color.
// After non separate translucency as that is considered at scene depth anyway
// It allows skybox translucency (set to non separate translucency) to be refracted.
2015-06-08 09:38:50 -04:00
RHICmdList . SetCurrentStat ( GET_STATID ( STAT_CLM_RenderDistortion ) ) ;
2014-06-05 16:38:54 -04:00
RenderDistortion ( RHICmdList ) ;
2015-05-29 10:47:57 -04:00
ServiceLocalQueue ( ) ;
2014-03-14 14:13:41 -04:00
}
2015-06-08 09:38:50 -04:00
RHICmdList . SetCurrentStat ( GET_STATID ( STAT_CLM_AfterTranslucency ) ) ;
2014-03-14 14:13:41 -04:00
}
2015-05-29 10:47:57 -04:00
2014-03-14 14:13:41 -04:00
if ( ViewFamily . EngineShowFlags . LightShafts )
{
2015-12-02 16:42:06 -05:00
SCOPE_CYCLE_COUNTER ( STAT_FDeferredShadingSceneRenderer_RenderLightShaftBloom ) ;
2015-06-08 09:38:50 -04:00
RHICmdList . SetCurrentStat ( GET_STATID ( STAT_CLM_LightShaftBloom ) ) ;
2014-06-12 07:13:34 -04:00
RenderLightShaftBloom ( RHICmdList ) ;
2015-05-29 10:47:57 -04:00
ServiceLocalQueue ( ) ;
2014-03-14 14:13:41 -04:00
}
2015-07-14 19:56:43 -04:00
for ( int32 ViewIndex = 0 ; ViewIndex < Views . Num ( ) ; + + ViewIndex )
{
const FViewInfo & View = Views [ ViewIndex ] ;
RHICmdList . SetViewport ( View . ViewRect . Min . X , View . ViewRect . Min . Y , 0.0f , View . ViewRect . Max . X , View . ViewRect . Max . Y , 1.0f ) ;
GetRendererModule ( ) . RenderOverlayExtensions ( View , RHICmdList , SceneContext ) ;
}
2014-12-16 20:00:22 -05:00
if ( ViewFamily . EngineShowFlags . VisualizeDistanceFieldAO | | ViewFamily . EngineShowFlags . VisualizeDistanceFieldGI )
2014-06-03 15:53:13 -04:00
{
2014-12-16 20:00:22 -05:00
// Use the skylight's max distance if there is one, to be consistent with DFAO shadowing on the skylight
2016-04-04 18:44:59 -04:00
const float OcclusionMaxDistance = Scene - > SkyLight & & ! Scene - > SkyLight - > bWantsStaticShadowing ? Scene - > SkyLight - > OcclusionMaxDistance : Scene - > DefaultMaxDistanceFieldOcclusionDistance ;
2014-08-28 13:54:31 -04:00
TRefCountPtr < IPooledRenderTarget > DummyOutput ;
2015-06-08 09:38:50 -04:00
RHICmdList . SetCurrentStat ( GET_STATID ( STAT_CLM_RenderDistanceFieldLighting ) ) ;
2016-03-02 13:38:38 -05:00
RenderDistanceFieldLighting ( RHICmdList , FDistanceFieldAOParameters ( OcclusionMaxDistance ) , VelocityRT , DummyOutput , DummyOutput , false , ViewFamily . EngineShowFlags . VisualizeDistanceFieldAO , ViewFamily . EngineShowFlags . VisualizeDistanceFieldGI ) ;
2015-05-29 10:47:57 -04:00
ServiceLocalQueue ( ) ;
2014-08-28 13:54:31 -04:00
}
if ( ViewFamily . EngineShowFlags . VisualizeMeshDistanceFields )
{
2016-04-04 18:44:59 -04:00
RenderMeshDistanceFieldVisualization ( RHICmdList , FDistanceFieldAOParameters ( Scene - > DefaultMaxDistanceFieldOcclusionDistance ) ) ;
2015-05-29 10:47:57 -04:00
ServiceLocalQueue ( ) ;
2014-06-03 15:53:13 -04:00
}
2014-03-14 14:13:41 -04:00
// Resolve the scene color for post processing.
2015-05-29 10:47:57 -04:00
SceneContext . ResolveSceneColor ( RHICmdList , FResolveRect ( 0 , 0 , ViewFamily . FamilySizeX , ViewFamily . FamilySizeY ) ) ;
2016-06-02 13:13:43 -04:00
CopySceneCaptureComponentToTarget ( RHICmdList ) ;
2014-03-14 14:13:41 -04:00
// Finish rendering for each view.
2015-07-14 19:56:43 -04:00
if ( ViewFamily . bResolveScene )
2014-03-14 14:13:41 -04:00
{
2014-10-20 10:43:43 -04:00
SCOPED_DRAW_EVENT ( RHICmdList , PostProcessing ) ;
2016-07-18 17:17:08 -04:00
SCOPED_GPU_STAT ( RHICmdList , Stat_GPU_Postprocessing ) ;
2014-03-14 14:13:41 -04:00
SCOPE_CYCLE_COUNTER ( STAT_FinishRenderViewTargetTime ) ;
2014-09-02 16:37:25 -04:00
2015-06-08 09:38:50 -04:00
RHICmdList . SetCurrentStat ( GET_STATID ( STAT_CLM_PostProcessing ) ) ;
2016-06-27 13:42:20 -04:00
for ( int32 ViewIndex = 0 ; ViewIndex < Views . Num ( ) ; ViewIndex + + )
2014-09-02 16:37:25 -04:00
{
2014-10-20 10:43:43 -04:00
SCOPED_CONDITIONAL_DRAW_EVENTF ( RHICmdList , EventView , Views . Num ( ) > 1 , TEXT ( " View%d " ) , ViewIndex ) ;
2014-09-02 16:37:25 -04:00
GPostProcessing . Process ( RHICmdList , Views [ ViewIndex ] , VelocityRT ) ;
2014-03-14 14:13:41 -04:00
}
2016-06-27 13:42:20 -04:00
// End of frame, we don't need it anymore
FSceneRenderTargets : : Get ( RHICmdList ) . FreeSeparateTranslucencyDepth ( ) ;
2015-12-10 21:55:37 -05:00
// we rendered to it during the frame, seems we haven't made use of it, because it should be released
check ( ! FSceneRenderTargets : : Get ( RHICmdList ) . SeparateTranslucencyRT ) ;
2014-03-14 14:13:41 -04:00
}
2014-05-19 09:42:34 -04:00
else
{
// Release the original reference on the scene render targets
2015-09-21 20:07:00 -04:00
SceneContext . AdjustGBufferRefCount ( RHICmdList , - 1 ) ;
2014-05-19 09:42:34 -04:00
}
2014-03-14 14:13:41 -04:00
2014-12-18 17:17:28 -05:00
//grab the new transform out of the proxies for next frame
2015-01-20 20:14:07 -05:00
if ( VelocityRT )
2014-12-18 17:17:28 -05:00
{
2015-12-02 16:42:06 -05:00
SCOPE_CYCLE_COUNTER ( STAT_FDeferredShadingSceneRenderer_UpdateMotionBlurCache ) ;
2014-12-18 17:17:28 -05:00
Scene - > MotionBlurInfoData . UpdateMotionBlurCache ( Scene ) ;
}
2014-09-02 16:37:25 -04:00
VelocityRT . SafeRelease ( ) ;
2015-03-04 08:31:40 -05:00
{
2015-12-02 16:42:06 -05:00
SCOPE_CYCLE_COUNTER ( STAT_FDeferredShadingSceneRenderer_RenderFinish ) ;
2015-06-08 09:38:50 -04:00
RHICmdList . SetCurrentStat ( GET_STATID ( STAT_CLM_RenderFinish ) ) ;
2015-03-04 08:31:40 -05:00
RenderFinish ( RHICmdList ) ;
RHICmdList . SetCurrentStat ( GET_STATID ( STAT_CLM_AfterFrame ) ) ;
}
2015-05-29 10:47:57 -04:00
ServiceLocalQueue ( ) ;
2014-03-14 14:13:41 -04:00
}
/** A simple pixel shader used on PC to read scene depth from scene color alpha and write it to a downsized depth buffer. */
class FDownsampleSceneDepthPS : public FGlobalShader
{
DECLARE_SHADER_TYPE ( FDownsampleSceneDepthPS , Global ) ;
public :
static bool ShouldCache ( EShaderPlatform Platform )
{
2014-08-25 14:41:54 -04:00
return IsFeatureLevelSupported ( Platform , ERHIFeatureLevel : : SM4 ) ;
2014-03-14 14:13:41 -04:00
}
FDownsampleSceneDepthPS ( const ShaderMetaType : : CompiledShaderInitializerType & Initializer ) :
FGlobalShader ( Initializer )
{
SceneTextureParameters . Bind ( Initializer . ParameterMap ) ;
ProjectionScaleBias . Bind ( Initializer . ParameterMap , TEXT ( " ProjectionScaleBias " ) ) ;
SourceTexelOffsets01 . Bind ( Initializer . ParameterMap , TEXT ( " SourceTexelOffsets01 " ) ) ;
SourceTexelOffsets23 . Bind ( Initializer . ParameterMap , TEXT ( " SourceTexelOffsets23 " ) ) ;
2016-02-24 06:51:42 -05:00
UseMaxDepth . Bind ( Initializer . ParameterMap , TEXT ( " UseMaxDepth " ) ) ;
2014-03-14 14:13:41 -04:00
}
FDownsampleSceneDepthPS ( ) { }
2016-02-24 06:51:42 -05:00
void SetParameters ( FRHICommandList & RHICmdList , const FSceneView & View , bool bUseMaxDepth )
2014-03-14 14:13:41 -04:00
{
2014-06-05 16:38:54 -04:00
FGlobalShader : : SetParameters ( RHICmdList , GetPixelShader ( ) , View ) ;
2015-05-29 10:47:57 -04:00
FSceneRenderTargets & SceneContext = FSceneRenderTargets : : Get ( RHICmdList ) ;
2014-03-14 14:13:41 -04:00
// Used to remap view space Z (which is stored in scene color alpha) into post projection z and w so we can write z/w into the downsized depth buffer
const FVector2D ProjectionScaleBiasValue ( View . ViewMatrices . ProjMatrix . M [ 2 ] [ 2 ] , View . ViewMatrices . ProjMatrix . M [ 3 ] [ 2 ] ) ;
2014-06-05 16:38:54 -04:00
SetShaderValue ( RHICmdList , GetPixelShader ( ) , ProjectionScaleBias , ProjectionScaleBiasValue ) ;
2016-02-24 06:51:42 -05:00
SetShaderValue ( RHICmdList , GetPixelShader ( ) , UseMaxDepth , ( bUseMaxDepth ? 1.0f : 0.0f ) ) ;
2014-03-14 14:13:41 -04:00
2015-05-29 10:47:57 -04:00
FIntPoint BufferSize = SceneContext . GetBufferSizeXY ( ) ;
2014-03-14 14:13:41 -04:00
2015-05-29 10:47:57 -04:00
const uint32 DownsampledBufferSizeX = BufferSize . X / SceneContext . GetSmallColorDepthDownsampleFactor ( ) ;
const uint32 DownsampledBufferSizeY = BufferSize . Y / SceneContext . GetSmallColorDepthDownsampleFactor ( ) ;
2014-03-14 14:13:41 -04:00
// Offsets of the four full resolution pixels corresponding with a low resolution pixel
const FVector4 Offsets01 ( 0.0f , 0.0f , 1.0f / DownsampledBufferSizeX , 0.0f ) ;
2014-06-05 16:38:54 -04:00
SetShaderValue ( RHICmdList , GetPixelShader ( ) , SourceTexelOffsets01 , Offsets01 ) ;
2014-03-14 14:13:41 -04:00
const FVector4 Offsets23 ( 0.0f , 1.0f / DownsampledBufferSizeY , 1.0f / DownsampledBufferSizeX , 1.0f / DownsampledBufferSizeY ) ;
2014-06-05 16:38:54 -04:00
SetShaderValue ( RHICmdList , GetPixelShader ( ) , SourceTexelOffsets23 , Offsets23 ) ;
SceneTextureParameters . Set ( RHICmdList , GetPixelShader ( ) , View ) ;
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 < < ProjectionScaleBias ;
Ar < < SourceTexelOffsets01 ;
Ar < < SourceTexelOffsets23 ;
Ar < < SceneTextureParameters ;
2016-02-24 06:51:42 -05:00
Ar < < UseMaxDepth ;
2014-03-14 14:13:41 -04:00
return bShaderHasOutdatedParameters ;
}
FShaderParameter ProjectionScaleBias ;
FShaderParameter SourceTexelOffsets01 ;
FShaderParameter SourceTexelOffsets23 ;
FSceneTextureShaderParameters SceneTextureParameters ;
2016-02-24 06:51:42 -05:00
FShaderParameter UseMaxDepth ;
2014-03-14 14:13:41 -04:00
} ;
IMPLEMENT_SHADER_TYPE ( , FDownsampleSceneDepthPS , TEXT ( " DownsampleDepthPixelShader " ) , TEXT ( " Main " ) , SF_Pixel ) ;
FGlobalBoundShaderState DownsampleDepthBoundShaderState ;
/** Updates the downsized depth buffer with the current full resolution depth buffer. */
2014-07-08 10:43:52 -04:00
void FDeferredShadingSceneRenderer : : UpdateDownsampledDepthSurface ( FRHICommandList & RHICmdList )
2014-03-14 14:13:41 -04:00
{
2015-05-29 10:47:57 -04:00
FSceneRenderTargets & SceneContext = FSceneRenderTargets : : Get ( RHICmdList ) ;
if ( SceneContext . UseDownsizedOcclusionQueries ( ) & & ( FeatureLevel > = ERHIFeatureLevel : : SM4 ) )
2014-03-14 14:13:41 -04:00
{
2016-02-04 23:40:42 -05:00
RHICmdList . TransitionResource ( EResourceTransitionAccess : : EReadable , SceneContext . GetSceneDepthSurface ( ) ) ;
2014-03-14 14:13:41 -04:00
for ( int32 ViewIndex = 0 ; ViewIndex < Views . Num ( ) ; ViewIndex + + )
{
const FViewInfo & View = Views [ ViewIndex ] ;
2016-02-24 06:51:42 -05:00
DownsampleDepthSurface ( RHICmdList , SceneContext . GetSmallDepthSurface ( ) , View , 1.0f / SceneContext . GetSmallColorDepthDownsampleFactor ( ) , true ) ;
2014-03-14 14:13:41 -04:00
}
}
}
2015-10-06 15:59:09 -04:00
2015-10-28 08:58:16 -04:00
/** Downsample the scene depth with a specified scale factor to a specified render target
*/
2016-02-24 06:51:42 -05:00
void FDeferredShadingSceneRenderer : : DownsampleDepthSurface ( FRHICommandList & RHICmdList , const FTexture2DRHIRef & RenderTarget , const FViewInfo & View , float ScaleFactor , bool bUseMaxDepth )
2015-10-06 15:59:09 -04:00
{
FSceneRenderTargets & SceneContext = FSceneRenderTargets : : Get ( RHICmdList ) ;
SetRenderTarget ( RHICmdList , NULL , RenderTarget ) ;
SCOPED_DRAW_EVENT ( RHICmdList , DownsampleDepth ) ;
// Set shaders and texture
TShaderMapRef < FScreenVS > ScreenVertexShader ( View . ShaderMap ) ;
TShaderMapRef < FDownsampleSceneDepthPS > PixelShader ( View . ShaderMap ) ;
extern TGlobalResource < FFilterVertexDeclaration > GFilterVertexDeclaration ;
SetGlobalBoundShaderState ( RHICmdList , FeatureLevel , DownsampleDepthBoundShaderState , GFilterVertexDeclaration . VertexDeclarationRHI , * ScreenVertexShader , * PixelShader ) ;
RHICmdList . SetBlendState ( TStaticBlendState < CW_NONE > : : GetRHI ( ) ) ;
RHICmdList . SetRasterizerState ( TStaticRasterizerState < FM_Solid , CM_None > : : GetRHI ( ) ) ;
RHICmdList . SetDepthStencilState ( TStaticDepthStencilState < true , CF_Always > : : GetRHI ( ) ) ;
2016-02-24 06:51:42 -05:00
PixelShader - > SetParameters ( RHICmdList , View , bUseMaxDepth ) ;
2015-10-06 15:59:09 -04:00
const uint32 DownsampledX = FMath : : TruncToInt ( View . ViewRect . Min . X * ScaleFactor ) ;
const uint32 DownsampledY = FMath : : TruncToInt ( View . ViewRect . Min . Y * ScaleFactor ) ;
const uint32 DownsampledSizeX = FMath : : TruncToInt ( View . ViewRect . Width ( ) * ScaleFactor ) ;
const uint32 DownsampledSizeY = FMath : : TruncToInt ( View . ViewRect . Height ( ) * ScaleFactor ) ;
RHICmdList . SetViewport ( DownsampledX , DownsampledY , 0.0f , DownsampledX + DownsampledSizeX , DownsampledY + DownsampledSizeY , 1.0f ) ;
DrawRectangle (
RHICmdList ,
0 , 0 ,
DownsampledSizeX , DownsampledSizeY ,
View . ViewRect . Min . X , View . ViewRect . Min . Y ,
View . ViewRect . Width ( ) , View . ViewRect . Height ( ) ,
FIntPoint ( DownsampledSizeX , DownsampledSizeY ) ,
SceneContext . GetBufferSizeXY ( ) ,
* ScreenVertexShader ,
EDRF_UseTriangleOptimization ) ;
2015-10-31 14:47:30 -04:00
RHICmdList . TransitionResource ( EResourceTransitionAccess : : EReadable , RenderTarget ) ;
2015-10-06 15:59:09 -04:00
}
2015-11-10 17:11:09 -05:00
/** */
class FCopyStencilToLightingChannelsPS : public FGlobalShader
{
DECLARE_SHADER_TYPE ( FCopyStencilToLightingChannelsPS , 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 ( " STENCIL_LIGHTING_CHANNELS_SHIFT " ) , STENCIL_LIGHTING_CHANNELS_BIT_ID ) ;
2015-12-10 21:55:37 -05:00
OutEnvironment . SetRenderTargetOutputFormat ( 0 , PF_R16_UINT ) ;
2015-11-10 17:11:09 -05:00
}
FCopyStencilToLightingChannelsPS ( const ShaderMetaType : : CompiledShaderInitializerType & Initializer ) :
FGlobalShader ( Initializer )
{
SceneStencilTexture . Bind ( Initializer . ParameterMap , TEXT ( " SceneStencilTexture " ) ) ;
}
FCopyStencilToLightingChannelsPS ( ) { }
void SetParameters ( FRHICommandList & RHICmdList , const FSceneView & View )
{
FGlobalShader : : SetParameters ( RHICmdList , GetPixelShader ( ) , View ) ;
FSceneRenderTargets & SceneContext = FSceneRenderTargets : : Get ( RHICmdList ) ;
SetSRVParameter ( RHICmdList , GetPixelShader ( ) , SceneStencilTexture , SceneContext . SceneStencilSRV ) ;
}
virtual bool Serialize ( FArchive & Ar ) override
{
bool bShaderHasOutdatedParameters = FGlobalShader : : Serialize ( Ar ) ;
Ar < < SceneStencilTexture ;
return bShaderHasOutdatedParameters ;
}
FShaderResourceParameter SceneStencilTexture ;
} ;
IMPLEMENT_SHADER_TYPE ( , FCopyStencilToLightingChannelsPS , TEXT ( " DownsampleDepthPixelShader " ) , TEXT ( " CopyStencilToLightingChannelsPS " ) , SF_Pixel ) ;
FGlobalBoundShaderState CopyStencilBoundShaderState ;
void FDeferredShadingSceneRenderer : : CopyStencilToLightingChannelTexture ( FRHICommandList & RHICmdList )
{
bool bAnyViewUsesLightingChannels = false ;
for ( int32 ViewIndex = 0 ; ViewIndex < Views . Num ( ) ; ViewIndex + + )
{
const FViewInfo & View = Views [ ViewIndex ] ;
bAnyViewUsesLightingChannels = bAnyViewUsesLightingChannels | | View . bUsesLightingChannels ;
}
if ( bAnyViewUsesLightingChannels )
{
FSceneRenderTargets & SceneContext = FSceneRenderTargets : : Get ( RHICmdList ) ;
SCOPED_DRAW_EVENT ( RHICmdList , CopyStencilToLightingChannels ) ;
RHICmdList . TransitionResource ( EResourceTransitionAccess : : EReadable , SceneContext . GetSceneDepthTexture ( ) ) ;
SceneContext . AllocateLightingChannelTexture ( RHICmdList ) ;
// Set the light attenuation surface as the render target, and the scene depth buffer as the depth-stencil surface.
SetRenderTarget ( RHICmdList , SceneContext . LightingChannels - > GetRenderTargetItem ( ) . TargetableTexture , nullptr , ESimpleRenderTargetMode : : EExistingColorAndDepth , FExclusiveDepthStencil : : DepthNop_StencilNop , true ) ;
for ( int32 ViewIndex = 0 ; ViewIndex < Views . Num ( ) ; ViewIndex + + )
{
const FViewInfo & View = Views [ ViewIndex ] ;
// Set shaders and texture
TShaderMapRef < FScreenVS > ScreenVertexShader ( View . ShaderMap ) ;
TShaderMapRef < FCopyStencilToLightingChannelsPS > PixelShader ( View . ShaderMap ) ;
extern TGlobalResource < FFilterVertexDeclaration > GFilterVertexDeclaration ;
SetGlobalBoundShaderState ( RHICmdList , FeatureLevel , CopyStencilBoundShaderState , GFilterVertexDeclaration . VertexDeclarationRHI , * ScreenVertexShader , * PixelShader ) ;
RHICmdList . SetBlendState ( TStaticBlendState < CW_RGBA > : : GetRHI ( ) ) ;
RHICmdList . SetRasterizerState ( TStaticRasterizerState < FM_Solid , CM_None > : : GetRHI ( ) ) ;
RHICmdList . SetDepthStencilState ( TStaticDepthStencilState < false , CF_Always > : : GetRHI ( ) ) ;
PixelShader - > SetParameters ( RHICmdList , View ) ;
RHICmdList . SetViewport ( View . ViewRect . Min . X , View . ViewRect . Min . Y , 0.0f , View . ViewRect . Min . X + View . ViewRect . Width ( ) , View . ViewRect . Min . Y + View . ViewRect . Height ( ) , 1.0f ) ;
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 ( ) ) ,
SceneContext . GetBufferSizeXY ( ) ,
* ScreenVertexShader ,
EDRF_UseTriangleOptimization ) ;
}
FResolveParams ResolveParams ;
RHICmdList . CopyToResolveTarget (
SceneContext . LightingChannels - > GetRenderTargetItem ( ) . TargetableTexture ,
SceneContext . LightingChannels - > GetRenderTargetItem ( ) . TargetableTexture ,
true ,
ResolveParams ) ;
}
2016-07-18 17:17:08 -04:00
}