2014-12-07 19:09:38 -05:00
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
2014-09-03 18:17:19 -04:00
/*=============================================================================
DistanceFieldShadowing . cpp
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
# include "RendererPrivate.h"
# include "ScenePrivate.h"
# include "UniformBuffer.h"
# include "ShaderParameters.h"
# include "PostProcessing.h"
# include "SceneFilterRendering.h"
# include "DistanceFieldLightingShared.h"
2014-09-18 15:13:07 -04:00
# include "DistanceFieldSurfaceCacheLighting.h"
2014-09-03 18:17:19 -04:00
# include "RHICommandList.h"
# include "SceneUtils.h"
# include "DistanceFieldAtlas.h"
int32 GDistanceFieldShadowing = 1 ;
FAutoConsoleVariableRef CVarDistanceFieldShadowing (
TEXT ( " r.DistanceFieldShadowing " ) ,
GDistanceFieldShadowing ,
TEXT ( " Whether the distance field shadowing feature is allowed. " ) ,
2014-12-15 15:29:48 -05:00
ECVF_Scalability | ECVF_RenderThreadSafe
2014-09-03 18:17:19 -04:00
) ;
2015-01-29 18:21:57 -05:00
int32 GFullResolutionDFShadowing = 0 ;
FAutoConsoleVariableRef CVarFullResolutionDFShadowing (
TEXT ( " r.DFFullResolution " ) ,
GFullResolutionDFShadowing ,
TEXT ( " 1 = full resolution distance field shadowing, 0 = half resolution with bilateral upsample. " ) ,
ECVF_Scalability | ECVF_RenderThreadSafe
) ;
2014-09-18 15:13:07 -04:00
int32 GShadowScatterTileCulling = 1 ;
FAutoConsoleVariableRef CVarShadowScatterTileCulling (
TEXT ( " r.DFShadowScatterTileCulling " ) ,
GShadowScatterTileCulling ,
TEXT ( " Whether to use the rasterizer to scatter objects onto the tile grid for culling. " ) ,
ECVF_Cheat | ECVF_RenderThreadSafe
) ;
2014-09-03 18:17:19 -04:00
2014-09-18 15:13:07 -04:00
float GShadowWorldTileSize = 200.0f ;
FAutoConsoleVariableRef CVarShadowWorldTileSize (
TEXT ( " r.DFShadowWorldTileSize " ) ,
GShadowWorldTileSize ,
TEXT ( " World space size of a tile used for culling for directional lights. " ) ,
ECVF_Cheat | ECVF_RenderThreadSafe
) ;
2015-01-29 18:21:57 -05:00
float GTwoSidedMeshDistanceBias = 4 ;
FAutoConsoleVariableRef CVarTwoSidedMeshDistanceBias (
TEXT ( " r.DFTwoSidedMeshDistanceBias " ) ,
GTwoSidedMeshDistanceBias ,
TEXT ( " World space amount to expand distance field representations of two sided meshes. This is useful to get tree shadows to match up with standard shadow mapping. " ) ,
ECVF_Cheat | ECVF_RenderThreadSafe
) ;
int32 GetDFShadowDownsampleFactor ( )
{
return GFullResolutionDFShadowing ? 1 : GAODownsampleFactor ;
}
FIntPoint GetBufferSizeForDFShadows ( )
{
return FIntPoint : : DivideAndRoundDown ( GSceneRenderTargets . GetBufferSizeXY ( ) , GetDFShadowDownsampleFactor ( ) ) ;
}
2014-11-21 22:32:16 -05:00
TGlobalResource < FDistanceFieldObjectBufferResource > GShadowCulledObjectBuffers ;
class FCullObjectsForShadowCS : public FGlobalShader
{
DECLARE_SHADER_TYPE ( FCullObjectsForShadowCS , Global )
public :
static bool ShouldCache ( EShaderPlatform Platform )
{
return IsFeatureLevelSupported ( Platform , ERHIFeatureLevel : : SM5 ) & & DoesPlatformSupportDistanceFieldShadowing ( Platform ) ;
}
static void ModifyCompilationEnvironment ( EShaderPlatform Platform , FShaderCompilerEnvironment & OutEnvironment )
{
FGlobalShader : : ModifyCompilationEnvironment ( Platform , OutEnvironment ) ;
OutEnvironment . SetDefine ( TEXT ( " UPDATEOBJECTS_THREADGROUP_SIZE " ) , UpdateObjectsGroupSize ) ;
}
FCullObjectsForShadowCS ( const ShaderMetaType : : CompiledShaderInitializerType & Initializer )
: FGlobalShader ( Initializer )
{
ObjectBufferParameters . Bind ( Initializer . ParameterMap ) ;
ObjectIndirectArguments . Bind ( Initializer . ParameterMap , TEXT ( " ObjectIndirectArguments " ) ) ;
CulledObjectBounds . Bind ( Initializer . ParameterMap , TEXT ( " CulledObjectBounds " ) ) ;
CulledObjectData . Bind ( Initializer . ParameterMap , TEXT ( " CulledObjectData " ) ) ;
CulledObjectBoxBounds . Bind ( Initializer . ParameterMap , TEXT ( " CulledObjectBoxBounds " ) ) ;
ObjectBoundingGeometryIndexCount . Bind ( Initializer . ParameterMap , TEXT ( " ObjectBoundingGeometryIndexCount " ) ) ;
WorldToShadow . Bind ( Initializer . ParameterMap , TEXT ( " WorldToShadow " ) ) ;
NumShadowHullPlanes . Bind ( Initializer . ParameterMap , TEXT ( " NumShadowHullPlanes " ) ) ;
ShadowBoundingSphere . Bind ( Initializer . ParameterMap , TEXT ( " ShadowBoundingSphere " ) ) ;
ShadowConvexHull . Bind ( Initializer . ParameterMap , TEXT ( " ShadowConvexHull " ) ) ;
}
FCullObjectsForShadowCS ( )
{
}
2014-12-16 20:00:22 -05:00
void SetParameters ( FRHICommandList & RHICmdList , const FScene * Scene , const FSceneView & View , const FMatrix & WorldToShadowValue , int32 NumPlanes , const FPlane * PlaneData , const FVector4 & ShadowBoundingSphereValue )
2014-11-21 22:32:16 -05:00
{
FComputeShaderRHIParamRef ShaderRHI = GetComputeShader ( ) ;
FGlobalShader : : SetParameters ( RHICmdList , ShaderRHI , View ) ;
ObjectBufferParameters . Set ( RHICmdList , ShaderRHI , * ( Scene - > DistanceFieldSceneData . ObjectBuffers ) , Scene - > DistanceFieldSceneData . NumObjectsInBuffer ) ;
ObjectIndirectArguments . SetBuffer ( RHICmdList , ShaderRHI , GShadowCulledObjectBuffers . Buffers . ObjectIndirectArguments ) ;
CulledObjectBounds . SetBuffer ( RHICmdList , ShaderRHI , GShadowCulledObjectBuffers . Buffers . Bounds ) ;
CulledObjectData . SetBuffer ( RHICmdList , ShaderRHI , GShadowCulledObjectBuffers . Buffers . Data ) ;
CulledObjectBoxBounds . SetBuffer ( RHICmdList , ShaderRHI , GShadowCulledObjectBuffers . Buffers . BoxBounds ) ;
SetShaderValue ( RHICmdList , ShaderRHI , ObjectBoundingGeometryIndexCount , StencilingGeometry : : GLowPolyStencilSphereIndexBuffer . GetIndexCount ( ) ) ;
SetShaderValue ( RHICmdList , ShaderRHI , WorldToShadow , WorldToShadowValue ) ;
SetShaderValue ( RHICmdList , ShaderRHI , ShadowBoundingSphere , ShadowBoundingSphereValue ) ;
2015-01-29 14:46:20 -05:00
2015-03-23 17:03:36 -04:00
if ( NumPlanes < = 12 )
2015-01-29 14:46:20 -05:00
{
SetShaderValue ( RHICmdList , ShaderRHI , NumShadowHullPlanes , NumPlanes ) ;
SetShaderValueArray ( RHICmdList , ShaderRHI , ShadowConvexHull , PlaneData , NumPlanes ) ;
}
else
{
SetShaderValue ( RHICmdList , ShaderRHI , NumShadowHullPlanes , 0 ) ;
}
2014-11-21 22:32:16 -05:00
}
void UnsetParameters ( FRHICommandList & RHICmdList )
{
ObjectBufferParameters . UnsetParameters ( RHICmdList , GetComputeShader ( ) ) ;
ObjectIndirectArguments . UnsetUAV ( RHICmdList , GetComputeShader ( ) ) ;
CulledObjectBounds . UnsetUAV ( RHICmdList , GetComputeShader ( ) ) ;
CulledObjectData . UnsetUAV ( RHICmdList , GetComputeShader ( ) ) ;
CulledObjectBoxBounds . UnsetUAV ( RHICmdList , GetComputeShader ( ) ) ;
}
2015-04-01 07:20:55 -04:00
virtual bool Serialize ( FArchive & Ar ) override
2014-11-21 22:32:16 -05:00
{
bool bShaderHasOutdatedParameters = FGlobalShader : : Serialize ( Ar ) ;
Ar < < ObjectBufferParameters ;
Ar < < ObjectIndirectArguments ;
Ar < < CulledObjectBounds ;
Ar < < CulledObjectData ;
Ar < < CulledObjectBoxBounds ;
Ar < < ObjectBoundingGeometryIndexCount ;
Ar < < WorldToShadow ;
Ar < < NumShadowHullPlanes ;
Ar < < ShadowBoundingSphere ;
Ar < < ShadowConvexHull ;
return bShaderHasOutdatedParameters ;
}
private :
FDistanceFieldObjectBufferParameters ObjectBufferParameters ;
FRWShaderParameter ObjectIndirectArguments ;
FRWShaderParameter CulledObjectBounds ;
FRWShaderParameter CulledObjectData ;
FRWShaderParameter CulledObjectBoxBounds ;
FShaderParameter ObjectBoundingGeometryIndexCount ;
FShaderParameter WorldToShadow ;
FShaderParameter NumShadowHullPlanes ;
FShaderParameter ShadowBoundingSphere ;
FShaderParameter ShadowConvexHull ;
} ;
IMPLEMENT_SHADER_TYPE ( , FCullObjectsForShadowCS , TEXT ( " DistanceFieldShadowing " ) , TEXT ( " CullObjectsForShadowCS " ) , SF_Compute ) ;
2014-09-18 15:13:07 -04:00
/** */
class FClearTilesCS : public FGlobalShader
2014-09-03 18:17:19 -04:00
{
2014-09-18 15:13:07 -04:00
DECLARE_SHADER_TYPE ( FClearTilesCS , Global )
public :
static bool ShouldCache ( EShaderPlatform Platform )
{
return IsFeatureLevelSupported ( Platform , ERHIFeatureLevel : : SM5 ) & & DoesPlatformSupportDistanceFieldShadowing ( Platform ) ;
}
static void ModifyCompilationEnvironment ( EShaderPlatform Platform , FShaderCompilerEnvironment & OutEnvironment )
{
FGlobalShader : : ModifyCompilationEnvironment ( Platform , OutEnvironment ) ;
OutEnvironment . SetDefine ( TEXT ( " THREADGROUP_SIZEX " ) , GDistanceFieldAOTileSizeX ) ;
OutEnvironment . SetDefine ( TEXT ( " THREADGROUP_SIZEY " ) , GDistanceFieldAOTileSizeY ) ;
}
FClearTilesCS ( const ShaderMetaType : : CompiledShaderInitializerType & Initializer )
: FGlobalShader ( Initializer )
{
2014-12-16 20:00:22 -05:00
ShadowTileHeadDataUnpacked . Bind ( Initializer . ParameterMap , TEXT ( " ShadowTileHeadDataUnpacked " ) ) ;
2014-09-18 15:13:07 -04:00
NumGroups . Bind ( Initializer . ParameterMap , TEXT ( " NumGroups " ) ) ;
}
FClearTilesCS ( )
{
}
void SetParameters ( FRHICommandList & RHICmdList , const FSceneView & View , FVector2D NumGroupsValue , FLightTileIntersectionResources * TileIntersectionResources )
{
FComputeShaderRHIParamRef ShaderRHI = GetComputeShader ( ) ;
FGlobalShader : : SetParameters ( RHICmdList , ShaderRHI , View ) ;
2014-12-16 20:00:22 -05:00
ShadowTileHeadDataUnpacked . SetBuffer ( RHICmdList , ShaderRHI , TileIntersectionResources - > TileHeadDataUnpacked ) ;
2014-09-18 15:13:07 -04:00
SetShaderValue ( RHICmdList , ShaderRHI , NumGroups , NumGroupsValue ) ;
}
void UnsetParameters ( FRHICommandList & RHICmdList )
{
2014-12-16 20:00:22 -05:00
ShadowTileHeadDataUnpacked . UnsetUAV ( RHICmdList , GetComputeShader ( ) ) ;
2014-09-18 15:13:07 -04:00
}
2015-04-01 07:20:55 -04:00
virtual bool Serialize ( FArchive & Ar ) override
2014-09-18 15:13:07 -04:00
{
bool bShaderHasOutdatedParameters = FGlobalShader : : Serialize ( Ar ) ;
2014-12-16 20:00:22 -05:00
Ar < < ShadowTileHeadDataUnpacked ;
2014-09-18 15:13:07 -04:00
Ar < < NumGroups ;
return bShaderHasOutdatedParameters ;
}
private :
2014-12-16 20:00:22 -05:00
FRWShaderParameter ShadowTileHeadDataUnpacked ;
2014-09-18 15:13:07 -04:00
FShaderParameter NumGroups ;
} ;
IMPLEMENT_SHADER_TYPE ( , FClearTilesCS , TEXT ( " DistanceFieldShadowing " ) , TEXT ( " ClearTilesCS " ) , SF_Compute ) ;
/** */
class FShadowObjectCullVS : public FGlobalShader
{
DECLARE_SHADER_TYPE ( FShadowObjectCullVS , Global ) ;
public :
static bool ShouldCache ( EShaderPlatform Platform )
{
return IsFeatureLevelSupported ( Platform , ERHIFeatureLevel : : SM5 ) & & DoesPlatformSupportDistanceFieldShadowing ( Platform ) ;
}
static void ModifyCompilationEnvironment ( EShaderPlatform Platform , FShaderCompilerEnvironment & OutEnvironment )
{
FGlobalShader : : ModifyCompilationEnvironment ( Platform , OutEnvironment ) ;
}
FShadowObjectCullVS ( const ShaderMetaType : : CompiledShaderInitializerType & Initializer ) :
FGlobalShader ( Initializer )
{
ObjectParameters . Bind ( Initializer . ParameterMap ) ;
ConservativeRadiusScale . Bind ( Initializer . ParameterMap , TEXT ( " ConservativeRadiusScale " ) ) ;
WorldToShadow . Bind ( Initializer . ParameterMap , TEXT ( " WorldToShadow " ) ) ;
MinRadius . Bind ( Initializer . ParameterMap , TEXT ( " MinRadius " ) ) ;
}
FShadowObjectCullVS ( ) { }
2014-12-16 20:00:22 -05:00
void SetParameters ( FRHICommandList & RHICmdList , const FSceneView & View , FVector2D NumGroupsValue , const FMatrix & WorldToShadowMatrixValue , float ShadowRadius )
2014-09-18 15:13:07 -04:00
{
const FVertexShaderRHIParamRef ShaderRHI = GetVertexShader ( ) ;
FGlobalShader : : SetParameters ( RHICmdList , ShaderRHI , View ) ;
2014-11-21 22:32:16 -05:00
ObjectParameters . Set ( RHICmdList , ShaderRHI , GShadowCulledObjectBuffers . Buffers ) ;
2014-09-18 15:13:07 -04:00
const int32 NumRings = StencilingGeometry : : GLowPolyStencilSphereVertexBuffer . GetNumRings ( ) ;
const float RadiansPerRingSegment = PI / ( float ) NumRings ;
// Boost the effective radius so that the edges of the sphere approximation lie on the sphere, instead of the vertices
const float ConservativeRadiusScaleValue = 1.0f / FMath : : Cos ( RadiansPerRingSegment ) ;
SetShaderValue ( RHICmdList , ShaderRHI , ConservativeRadiusScale , ConservativeRadiusScaleValue ) ;
SetShaderValue ( RHICmdList , ShaderRHI , WorldToShadow , WorldToShadowMatrixValue ) ;
2014-12-16 20:00:22 -05:00
float MinRadiusValue = 2 * ShadowRadius / FMath : : Min ( NumGroupsValue . X , NumGroupsValue . Y ) ;
2014-09-18 15:13:07 -04:00
SetShaderValue ( RHICmdList , ShaderRHI , MinRadius , MinRadiusValue ) ;
}
2015-04-01 07:20:55 -04:00
virtual bool Serialize ( FArchive & Ar ) override
2014-09-18 15:13:07 -04:00
{
bool bShaderHasOutdatedParameters = FGlobalShader : : Serialize ( Ar ) ;
Ar < < ObjectParameters ;
Ar < < ConservativeRadiusScale ;
Ar < < WorldToShadow ;
Ar < < MinRadius ;
return bShaderHasOutdatedParameters ;
}
private :
2014-11-21 22:32:16 -05:00
FDistanceFieldCulledObjectBufferParameters ObjectParameters ;
2014-09-18 15:13:07 -04:00
FShaderParameter ConservativeRadiusScale ;
FShaderParameter WorldToShadow ;
FShaderParameter MinRadius ;
} ;
IMPLEMENT_SHADER_TYPE ( , FShadowObjectCullVS , TEXT ( " DistanceFieldShadowing " ) , TEXT ( " ShadowObjectCullVS " ) , SF_Vertex ) ;
class FShadowObjectCullPS : public FGlobalShader
{
DECLARE_SHADER_TYPE ( FShadowObjectCullPS , Global ) ;
public :
static bool ShouldCache ( EShaderPlatform Platform )
{
return IsFeatureLevelSupported ( Platform , ERHIFeatureLevel : : SM5 ) & & DoesPlatformSupportDistanceFieldShadowing ( Platform ) ;
}
/** Default constructor. */
FShadowObjectCullPS ( ) { }
/** Initialization constructor. */
FShadowObjectCullPS ( const ShaderMetaType : : CompiledShaderInitializerType & Initializer )
: FGlobalShader ( Initializer )
{
ObjectParameters . Bind ( Initializer . ParameterMap ) ;
2014-12-16 20:00:22 -05:00
ShadowTileHeadDataUnpacked . Bind ( Initializer . ParameterMap , TEXT ( " ShadowTileHeadDataUnpacked " ) ) ;
ShadowTileArrayData . Bind ( Initializer . ParameterMap , TEXT ( " ShadowTileArrayData " ) ) ;
2014-09-18 15:13:07 -04:00
NumGroups . Bind ( Initializer . ParameterMap , TEXT ( " NumGroups " ) ) ;
}
void SetParameters (
FRHICommandList & RHICmdList ,
const FSceneView & View ,
2014-12-16 20:00:22 -05:00
FVector2D NumGroupsValue )
2014-09-18 15:13:07 -04:00
{
const FPixelShaderRHIParamRef ShaderRHI = GetPixelShader ( ) ;
FGlobalShader : : SetParameters ( RHICmdList , ShaderRHI , View ) ;
2014-11-21 22:32:16 -05:00
ObjectParameters . Set ( RHICmdList , ShaderRHI , GShadowCulledObjectBuffers . Buffers ) ;
2014-09-18 15:13:07 -04:00
SetShaderValue ( RHICmdList , ShaderRHI , NumGroups , NumGroupsValue ) ;
}
void GetUAVs ( const FSceneView & View , FLightTileIntersectionResources * TileIntersectionResources , TArray < FUnorderedAccessViewRHIParamRef > & UAVs )
{
2014-12-16 20:00:22 -05:00
int32 MaxIndex = FMath : : Max ( ShadowTileHeadDataUnpacked . GetUAVIndex ( ) , ShadowTileArrayData . GetUAVIndex ( ) ) ;
2014-09-18 15:13:07 -04:00
UAVs . AddZeroed ( MaxIndex + 1 ) ;
2014-12-16 20:00:22 -05:00
if ( ShadowTileHeadDataUnpacked . IsBound ( ) )
2014-09-18 15:13:07 -04:00
{
2014-12-16 20:00:22 -05:00
UAVs [ ShadowTileHeadDataUnpacked . GetUAVIndex ( ) ] = TileIntersectionResources - > TileHeadDataUnpacked . UAV ;
2014-09-18 15:13:07 -04:00
}
2014-12-16 20:00:22 -05:00
if ( ShadowTileArrayData . IsBound ( ) )
2014-09-18 15:13:07 -04:00
{
2014-12-16 20:00:22 -05:00
UAVs [ ShadowTileArrayData . GetUAVIndex ( ) ] = TileIntersectionResources - > TileArrayData . UAV ;
2014-09-18 15:13:07 -04:00
}
check ( UAVs . Num ( ) > 0 ) ;
}
// FShader interface.
2015-04-01 07:20:55 -04:00
virtual bool Serialize ( FArchive & Ar ) override
2014-09-18 15:13:07 -04:00
{
bool bShaderHasOutdatedParameters = FGlobalShader : : Serialize ( Ar ) ;
Ar < < ObjectParameters ;
2014-12-16 20:00:22 -05:00
Ar < < ShadowTileHeadDataUnpacked ;
Ar < < ShadowTileArrayData ;
2014-09-18 15:13:07 -04:00
Ar < < NumGroups ;
return bShaderHasOutdatedParameters ;
}
private :
2014-11-21 22:32:16 -05:00
FDistanceFieldCulledObjectBufferParameters ObjectParameters ;
2014-12-16 20:00:22 -05:00
FRWShaderParameter ShadowTileHeadDataUnpacked ;
FRWShaderParameter ShadowTileArrayData ;
2014-09-18 15:13:07 -04:00
FShaderParameter NumGroups ;
} ;
IMPLEMENT_SHADER_TYPE ( , FShadowObjectCullPS , TEXT ( " DistanceFieldShadowing " ) , TEXT ( " ShadowObjectCullPS " ) , SF_Pixel ) ;
enum EDistanceFieldShadowingType
{
DFS_DirectionalLightScatterTileCulling ,
DFS_DirectionalLightTiledCulling ,
DFS_PointLightTiledCulling
} ;
template < EDistanceFieldShadowingType ShadowingType >
class TDistanceFieldShadowingCS : public FGlobalShader
{
DECLARE_SHADER_TYPE ( TDistanceFieldShadowingCS , Global ) ;
2014-09-03 18:17:19 -04:00
public :
static bool ShouldCache ( EShaderPlatform Platform )
{
return IsFeatureLevelSupported ( Platform , ERHIFeatureLevel : : SM5 ) & & DoesPlatformSupportDistanceFieldShadowing ( Platform ) ;
}
static void ModifyCompilationEnvironment ( EShaderPlatform Platform , FShaderCompilerEnvironment & OutEnvironment )
{
OutEnvironment . SetDefine ( TEXT ( " THREADGROUP_SIZEX " ) , GDistanceFieldAOTileSizeX ) ;
OutEnvironment . SetDefine ( TEXT ( " THREADGROUP_SIZEY " ) , GDistanceFieldAOTileSizeY ) ;
2014-09-18 15:13:07 -04:00
OutEnvironment . SetDefine ( TEXT ( " SCATTER_TILE_CULLING " ) , ShadowingType = = DFS_DirectionalLightScatterTileCulling ? TEXT ( " 1 " ) : TEXT ( " 0 " ) ) ;
OutEnvironment . SetDefine ( TEXT ( " POINT_LIGHT " ) , ShadowingType = = DFS_PointLightTiledCulling ? TEXT ( " 1 " ) : TEXT ( " 0 " ) ) ;
2014-09-03 18:17:19 -04:00
}
/** Default constructor. */
2014-09-18 15:13:07 -04:00
TDistanceFieldShadowingCS ( ) { }
2014-09-03 18:17:19 -04:00
/** Initialization constructor. */
2014-09-18 15:13:07 -04:00
TDistanceFieldShadowingCS ( const ShaderMetaType : : CompiledShaderInitializerType & Initializer )
2014-09-03 18:17:19 -04:00
: FGlobalShader ( Initializer )
{
ShadowFactors . Bind ( Initializer . ParameterMap , TEXT ( " ShadowFactors " ) ) ;
NumGroups . Bind ( Initializer . ParameterMap , TEXT ( " NumGroups " ) ) ;
LightDirection . Bind ( Initializer . ParameterMap , TEXT ( " LightDirection " ) ) ;
2014-09-18 15:13:07 -04:00
LightSourceRadius . Bind ( Initializer . ParameterMap , TEXT ( " LightSourceRadius " ) ) ;
2015-01-23 21:17:37 -05:00
RayStartOffsetDepthScale . Bind ( Initializer . ParameterMap , TEXT ( " RayStartOffsetDepthScale " ) ) ;
2014-09-18 15:13:07 -04:00
LightPositionAndInvRadius . Bind ( Initializer . ParameterMap , TEXT ( " LightPositionAndInvRadius " ) ) ;
TanLightAngleAndNormalThreshold . Bind ( Initializer . ParameterMap , TEXT ( " TanLightAngleAndNormalThreshold " ) ) ;
ScissorRectMinAndSize . Bind ( Initializer . ParameterMap , TEXT ( " ScissorRectMinAndSize " ) ) ;
2014-09-03 18:17:19 -04:00
ObjectParameters . Bind ( Initializer . ParameterMap ) ;
DeferredParameters . Bind ( Initializer . ParameterMap ) ;
2014-12-16 20:00:22 -05:00
ShadowTileHeadDataUnpacked . Bind ( Initializer . ParameterMap , TEXT ( " ShadowTileHeadDataUnpacked " ) ) ;
ShadowTileArrayData . Bind ( Initializer . ParameterMap , TEXT ( " ShadowTileArrayData " ) ) ;
ShadowTileListGroupSize . Bind ( Initializer . ParameterMap , TEXT ( " ShadowTileListGroupSize " ) ) ;
2014-09-18 15:13:07 -04:00
WorldToShadow . Bind ( Initializer . ParameterMap , TEXT ( " WorldToShadow " ) ) ;
2015-01-29 18:21:57 -05:00
TwoSidedMeshDistanceBias . Bind ( Initializer . ParameterMap , TEXT ( " TwoSidedMeshDistanceBias " ) ) ;
DownsampleFactor . Bind ( Initializer . ParameterMap , TEXT ( " DownsampleFactor " ) ) ;
2014-09-03 18:17:19 -04:00
}
void SetParameters (
FRHICommandList & RHICmdList ,
const FSceneView & View ,
const FProjectedShadowInfo * ProjectedShadowInfo ,
FSceneRenderTargetItem & ShadowFactorsValue ,
2014-09-18 15:13:07 -04:00
FVector2D NumGroupsValue ,
const FIntRect & ScissorRect ,
FLightTileIntersectionResources * TileIntersectionResources )
2014-09-03 18:17:19 -04:00
{
const FComputeShaderRHIParamRef ShaderRHI = GetComputeShader ( ) ;
FGlobalShader : : SetParameters ( RHICmdList , ShaderRHI , View ) ;
ShadowFactors . SetTexture ( RHICmdList , ShaderRHI , ShadowFactorsValue . ShaderResourceTexture , ShadowFactorsValue . UAV ) ;
2014-11-21 22:32:16 -05:00
ObjectParameters . Set ( RHICmdList , ShaderRHI , GShadowCulledObjectBuffers . Buffers ) ;
2014-09-03 18:17:19 -04:00
DeferredParameters . Set ( RHICmdList , ShaderRHI , View ) ;
SetShaderValue ( RHICmdList , ShaderRHI , NumGroups , NumGroupsValue ) ;
2014-09-18 15:13:07 -04:00
FVector4 LightPositionAndInvRadiusValue ;
FVector4 LightColorAndFalloffExponent ;
FVector NormalizedLightDirection ;
FVector2D SpotAngles ;
float LightSourceRadiusValue ;
float LightSourceLength ;
float LightMinRoughness ;
2015-01-25 13:58:27 -05:00
const FLightSceneProxy & LightProxy = * ( ProjectedShadowInfo - > GetLightSceneInfo ( ) . Proxy ) ;
LightProxy . GetParameters ( LightPositionAndInvRadiusValue , LightColorAndFalloffExponent , NormalizedLightDirection , SpotAngles , LightSourceRadiusValue , LightSourceLength , LightMinRoughness ) ;
2014-09-18 15:13:07 -04:00
SetShaderValue ( RHICmdList , ShaderRHI , LightDirection , NormalizedLightDirection ) ;
SetShaderValue ( RHICmdList , ShaderRHI , LightPositionAndInvRadius , LightPositionAndInvRadiusValue ) ;
// Default light source radius of 0 gives poor results
SetShaderValue ( RHICmdList , ShaderRHI , LightSourceRadius , LightSourceRadiusValue = = 0 ? 20 : FMath : : Clamp ( LightSourceRadiusValue , .001f , 1.0f / ( 4 * LightPositionAndInvRadiusValue . W ) ) ) ;
2015-01-25 13:58:27 -05:00
SetShaderValue ( RHICmdList , ShaderRHI , RayStartOffsetDepthScale , LightProxy . GetRayStartOffsetDepthScale ( ) ) ;
2015-01-23 21:17:37 -05:00
2015-01-25 13:58:27 -05:00
const float LightSourceAngle = FMath : : Clamp ( LightProxy . GetLightSourceAngle ( ) , 0.001f , 5.0f ) * PI / 180.0f ;
2014-09-18 15:13:07 -04:00
const FVector2D TanLightAngleAndNormalThresholdValue ( FMath : : Tan ( LightSourceAngle ) , FMath : : Cos ( PI / 2 + LightSourceAngle ) ) ;
SetShaderValue ( RHICmdList , ShaderRHI , TanLightAngleAndNormalThreshold , TanLightAngleAndNormalThresholdValue ) ;
SetShaderValue ( RHICmdList , ShaderRHI , ScissorRectMinAndSize , FIntRect ( ScissorRect . Min , ScissorRect . Size ( ) ) ) ;
2014-12-16 20:00:22 -05:00
check ( TileIntersectionResources | | ! ShadowTileHeadDataUnpacked . IsBound ( ) ) ;
2014-09-18 15:13:07 -04:00
if ( TileIntersectionResources )
{
2014-12-16 20:00:22 -05:00
SetSRVParameter ( RHICmdList , ShaderRHI , ShadowTileHeadDataUnpacked , TileIntersectionResources - > TileHeadDataUnpacked . SRV ) ;
SetSRVParameter ( RHICmdList , ShaderRHI , ShadowTileArrayData , TileIntersectionResources - > TileArrayData . SRV ) ;
SetShaderValue ( RHICmdList , ShaderRHI , ShadowTileListGroupSize , TileIntersectionResources - > TileDimensions ) ;
2014-09-18 15:13:07 -04:00
}
FMatrix WorldToShadowMatrixValue = FTranslationMatrix ( ProjectedShadowInfo - > PreShadowTranslation ) * ProjectedShadowInfo - > SubjectAndReceiverMatrix ;
SetShaderValue ( RHICmdList , ShaderRHI , WorldToShadow , WorldToShadowMatrixValue ) ;
2015-01-29 18:21:57 -05:00
SetShaderValue ( RHICmdList , ShaderRHI , TwoSidedMeshDistanceBias , GTwoSidedMeshDistanceBias ) ;
SetShaderValue ( RHICmdList , ShaderRHI , DownsampleFactor , GetDFShadowDownsampleFactor ( ) ) ;
2014-09-03 18:17:19 -04:00
}
void UnsetParameters ( FRHICommandList & RHICmdList )
{
ShadowFactors . UnsetUAV ( RHICmdList , GetComputeShader ( ) ) ;
}
// FShader interface.
2015-04-01 07:20:55 -04:00
virtual bool Serialize ( FArchive & Ar ) override
2014-09-03 18:17:19 -04:00
{
bool bShaderHasOutdatedParameters = FGlobalShader : : Serialize ( Ar ) ;
Ar < < ShadowFactors ;
Ar < < NumGroups ;
Ar < < LightDirection ;
2014-09-18 15:13:07 -04:00
Ar < < LightPositionAndInvRadius ;
Ar < < LightSourceRadius ;
2015-01-23 21:17:37 -05:00
Ar < < RayStartOffsetDepthScale ;
2014-09-18 15:13:07 -04:00
Ar < < TanLightAngleAndNormalThreshold ;
Ar < < ScissorRectMinAndSize ;
2014-09-03 18:17:19 -04:00
Ar < < ObjectParameters ;
Ar < < DeferredParameters ;
2014-12-16 20:00:22 -05:00
Ar < < ShadowTileHeadDataUnpacked ;
Ar < < ShadowTileArrayData ;
Ar < < ShadowTileListGroupSize ;
2014-09-18 15:13:07 -04:00
Ar < < WorldToShadow ;
2015-01-29 18:21:57 -05:00
Ar < < TwoSidedMeshDistanceBias ;
Ar < < DownsampleFactor ;
2014-09-03 18:17:19 -04:00
return bShaderHasOutdatedParameters ;
}
private :
FRWShaderParameter ShadowFactors ;
FShaderParameter NumGroups ;
FShaderParameter LightDirection ;
2014-09-18 15:13:07 -04:00
FShaderParameter LightPositionAndInvRadius ;
FShaderParameter LightSourceRadius ;
2015-01-23 21:17:37 -05:00
FShaderParameter RayStartOffsetDepthScale ;
2014-09-18 15:13:07 -04:00
FShaderParameter TanLightAngleAndNormalThreshold ;
FShaderParameter ScissorRectMinAndSize ;
2014-11-21 22:32:16 -05:00
FDistanceFieldCulledObjectBufferParameters ObjectParameters ;
2014-09-03 18:17:19 -04:00
FDeferredPixelShaderParameters DeferredParameters ;
2014-12-16 20:00:22 -05:00
FShaderResourceParameter ShadowTileHeadDataUnpacked ;
FShaderResourceParameter ShadowTileArrayData ;
FShaderParameter ShadowTileListGroupSize ;
2014-09-18 15:13:07 -04:00
FShaderParameter WorldToShadow ;
2015-01-29 18:21:57 -05:00
FShaderParameter TwoSidedMeshDistanceBias ;
FShaderParameter DownsampleFactor ;
2014-09-03 18:17:19 -04:00
} ;
2014-09-18 15:13:07 -04:00
IMPLEMENT_SHADER_TYPE ( template < > , TDistanceFieldShadowingCS < DFS_DirectionalLightScatterTileCulling > , TEXT ( " DistanceFieldShadowing " ) , TEXT ( " DistanceFieldShadowingCS " ) , SF_Compute ) ;
IMPLEMENT_SHADER_TYPE ( template < > , TDistanceFieldShadowingCS < DFS_DirectionalLightTiledCulling > , TEXT ( " DistanceFieldShadowing " ) , TEXT ( " DistanceFieldShadowingCS " ) , SF_Compute ) ;
IMPLEMENT_SHADER_TYPE ( template < > , TDistanceFieldShadowingCS < DFS_PointLightTiledCulling > , TEXT ( " DistanceFieldShadowing " ) , TEXT ( " DistanceFieldShadowingCS " ) , SF_Compute ) ;
2014-09-03 18:17:19 -04:00
2015-01-29 18:21:57 -05:00
template < bool bUpsampleRequired >
class TDistanceFieldShadowingUpsamplePS : public FGlobalShader
2014-09-03 18:17:19 -04:00
{
2015-01-29 18:21:57 -05:00
DECLARE_SHADER_TYPE ( TDistanceFieldShadowingUpsamplePS , Global ) ;
2014-09-03 18:17:19 -04:00
public :
static bool ShouldCache ( EShaderPlatform Platform )
{
return IsFeatureLevelSupported ( Platform , ERHIFeatureLevel : : SM5 ) & & DoesPlatformSupportDistanceFieldShadowing ( Platform ) ;
}
static void ModifyCompilationEnvironment ( EShaderPlatform Platform , FShaderCompilerEnvironment & OutEnvironment )
{
OutEnvironment . SetDefine ( TEXT ( " DOWNSAMPLE_FACTOR " ) , GAODownsampleFactor ) ;
2015-01-29 18:21:57 -05:00
OutEnvironment . SetDefine ( TEXT ( " UPSAMPLE_REQUIRED " ) , bUpsampleRequired ? TEXT ( " 1 " ) : TEXT ( " 0 " ) ) ;
2014-09-03 18:17:19 -04:00
}
/** Default constructor. */
2015-01-29 18:21:57 -05:00
TDistanceFieldShadowingUpsamplePS ( ) { }
2014-09-03 18:17:19 -04:00
/** Initialization constructor. */
2015-01-29 18:21:57 -05:00
TDistanceFieldShadowingUpsamplePS ( const ShaderMetaType : : CompiledShaderInitializerType & Initializer )
2014-09-03 18:17:19 -04:00
: FGlobalShader ( Initializer )
{
DeferredParameters . Bind ( Initializer . ParameterMap ) ;
ShadowFactorsTexture . Bind ( Initializer . ParameterMap , TEXT ( " ShadowFactorsTexture " ) ) ;
ShadowFactorsSampler . Bind ( Initializer . ParameterMap , TEXT ( " ShadowFactorsSampler " ) ) ;
2014-09-18 15:13:07 -04:00
ScissorRectMinAndSize . Bind ( Initializer . ParameterMap , TEXT ( " ScissorRectMinAndSize " ) ) ;
2015-03-02 14:11:33 -05:00
FadePlaneOffset . Bind ( Initializer . ParameterMap , TEXT ( " FadePlaneOffset " ) ) ;
InvFadePlaneLength . Bind ( Initializer . ParameterMap , TEXT ( " InvFadePlaneLength " ) ) ;
2014-09-03 18:17:19 -04:00
}
2014-09-18 15:13:07 -04:00
void SetParameters ( FRHICommandList & RHICmdList , const FSceneView & View , const FProjectedShadowInfo * ShadowInfo , const FIntRect & ScissorRect , TRefCountPtr < IPooledRenderTarget > & ShadowFactorsTextureValue )
2014-09-03 18:17:19 -04:00
{
const FPixelShaderRHIParamRef ShaderRHI = GetPixelShader ( ) ;
FGlobalShader : : SetParameters ( RHICmdList , ShaderRHI , View ) ;
DeferredParameters . Set ( RHICmdList , ShaderRHI , View ) ;
SetTextureParameter ( RHICmdList , ShaderRHI , ShadowFactorsTexture , ShadowFactorsSampler , TStaticSamplerState < SF_Bilinear > : : GetRHI ( ) , ShadowFactorsTextureValue - > GetRenderTargetItem ( ) . ShaderResourceTexture ) ;
2014-09-18 15:13:07 -04:00
SetShaderValue ( RHICmdList , ShaderRHI , ScissorRectMinAndSize , FIntRect ( ScissorRect . Min , ScissorRect . Size ( ) ) ) ;
2015-03-02 14:11:33 -05:00
if ( ShadowInfo - > bDirectionalLight & & ShadowInfo - > CascadeSettings . FadePlaneLength > 0 )
{
SetShaderValue ( RHICmdList , ShaderRHI , FadePlaneOffset , ShadowInfo - > CascadeSettings . FadePlaneOffset ) ;
SetShaderValue ( RHICmdList , ShaderRHI , InvFadePlaneLength , 1.0f / FMath : : Max ( ShadowInfo - > CascadeSettings . FadePlaneLength , .00001f ) ) ;
}
else
{
SetShaderValue ( RHICmdList , ShaderRHI , FadePlaneOffset , 0.0f ) ;
SetShaderValue ( RHICmdList , ShaderRHI , InvFadePlaneLength , 0.0f ) ;
}
2014-09-03 18:17:19 -04:00
}
2014-09-18 15:13:07 -04:00
2014-09-03 18:17:19 -04:00
// FShader interface.
2015-04-01 07:20:55 -04:00
virtual bool Serialize ( FArchive & Ar ) override
2014-09-03 18:17:19 -04:00
{
bool bShaderHasOutdatedParameters = FGlobalShader : : Serialize ( Ar ) ;
Ar < < DeferredParameters ;
Ar < < ShadowFactorsTexture ;
Ar < < ShadowFactorsSampler ;
2014-09-18 15:13:07 -04:00
Ar < < ScissorRectMinAndSize ;
2015-03-02 14:11:33 -05:00
Ar < < FadePlaneOffset ;
Ar < < InvFadePlaneLength ;
2014-09-03 18:17:19 -04:00
return bShaderHasOutdatedParameters ;
}
private :
FDeferredPixelShaderParameters DeferredParameters ;
FShaderResourceParameter ShadowFactorsTexture ;
FShaderResourceParameter ShadowFactorsSampler ;
2014-09-18 15:13:07 -04:00
FShaderParameter ScissorRectMinAndSize ;
2015-03-02 14:11:33 -05:00
FShaderParameter FadePlaneOffset ;
FShaderParameter InvFadePlaneLength ;
2014-09-03 18:17:19 -04:00
} ;
2015-01-29 18:21:57 -05:00
IMPLEMENT_SHADER_TYPE ( template < > , TDistanceFieldShadowingUpsamplePS < true > , TEXT ( " DistanceFieldShadowing " ) , TEXT ( " DistanceFieldShadowingUpsamplePS " ) , SF_Pixel ) ;
IMPLEMENT_SHADER_TYPE ( template < > , TDistanceFieldShadowingUpsamplePS < false > , TEXT ( " DistanceFieldShadowing " ) , TEXT ( " DistanceFieldShadowingUpsamplePS " ) , SF_Pixel ) ;
2014-09-03 18:17:19 -04:00
2014-12-16 20:00:22 -05:00
void CullDistanceFieldObjectsForLight (
FRHICommandListImmediate & RHICmdList ,
const FViewInfo & View ,
const FLightSceneProxy * LightSceneProxy ,
const FMatrix & WorldToShadowValue ,
int32 NumPlanes ,
const FPlane * PlaneData ,
const FVector4 & ShadowBoundingSphereValue ,
float ShadowBoundingRadius ,
TScopedPointer < FLightTileIntersectionResources > & TileIntersectionResources )
{
const FScene * Scene = ( const FScene * ) ( View . Family - > Scene ) ;
2015-01-29 14:46:20 -05:00
SCOPED_DRAW_EVENT ( RHICmdList , CullObjectsForLight ) ;
2014-12-16 20:00:22 -05:00
2015-01-29 14:46:20 -05:00
{
2014-12-16 20:00:22 -05:00
if ( GShadowCulledObjectBuffers . Buffers . MaxObjects < Scene - > DistanceFieldSceneData . NumObjectsInBuffer
| | GShadowCulledObjectBuffers . Buffers . MaxObjects > 3 * Scene - > DistanceFieldSceneData . NumObjectsInBuffer )
{
GShadowCulledObjectBuffers . Buffers . bWantBoxBounds = true ;
GShadowCulledObjectBuffers . Buffers . MaxObjects = Scene - > DistanceFieldSceneData . NumObjectsInBuffer * 5 / 4 ;
GShadowCulledObjectBuffers . Buffers . Release ( ) ;
GShadowCulledObjectBuffers . Buffers . Initialize ( ) ;
}
{
uint32 ClearValues [ 4 ] = { 0 } ;
RHICmdList . ClearUAV ( GShadowCulledObjectBuffers . Buffers . ObjectIndirectArguments . UAV , ClearValues ) ;
TShaderMapRef < FCullObjectsForShadowCS > ComputeShader ( GetGlobalShaderMap ( Scene - > GetFeatureLevel ( ) ) ) ;
RHICmdList . SetComputeShader ( ComputeShader - > GetComputeShader ( ) ) ;
ComputeShader - > SetParameters ( RHICmdList , Scene , View , WorldToShadowValue , NumPlanes , PlaneData , ShadowBoundingSphereValue ) ;
DispatchComputeShader ( RHICmdList , * ComputeShader , FMath : : DivideAndRoundUp < uint32 > ( Scene - > DistanceFieldSceneData . NumObjectsInBuffer , UpdateObjectsGroupSize ) , 1 , 1 ) ;
ComputeShader - > UnsetParameters ( RHICmdList ) ;
}
}
// Allocate tile resolution based on world space size
//@todo - light space perspective shadow maps would make much better use of the resolution
const float LightTiles = FMath : : Min ( ShadowBoundingRadius / GShadowWorldTileSize + 1 , 256.0f ) ;
FIntPoint LightTileDimensions ( LightTiles , LightTiles ) ;
if ( LightSceneProxy - > GetLightType ( ) = = LightType_Directional & & GShadowScatterTileCulling )
{
if ( ! TileIntersectionResources | | TileIntersectionResources - > TileDimensions ! = LightTileDimensions )
{
if ( TileIntersectionResources )
{
TileIntersectionResources - > Release ( ) ;
}
else
{
TileIntersectionResources = new FLightTileIntersectionResources ( ) ;
}
TileIntersectionResources - > TileDimensions = LightTileDimensions ;
TileIntersectionResources - > Initialize ( ) ;
}
{
TShaderMapRef < FClearTilesCS > ComputeShader ( View . ShaderMap ) ;
uint32 GroupSizeX = FMath : : DivideAndRoundUp ( LightTileDimensions . X , GDistanceFieldAOTileSizeX ) ;
uint32 GroupSizeY = FMath : : DivideAndRoundUp ( LightTileDimensions . Y , GDistanceFieldAOTileSizeY ) ;
RHICmdList . SetComputeShader ( ComputeShader - > GetComputeShader ( ) ) ;
ComputeShader - > SetParameters ( RHICmdList , View , FVector2D ( LightTileDimensions . X , LightTileDimensions . Y ) , TileIntersectionResources ) ;
DispatchComputeShader ( RHICmdList , * ComputeShader , GroupSizeX , GroupSizeY , 1 ) ;
ComputeShader - > UnsetParameters ( RHICmdList ) ;
}
{
TShaderMapRef < FShadowObjectCullVS > VertexShader ( View . ShaderMap ) ;
TShaderMapRef < FShadowObjectCullPS > PixelShader ( View . ShaderMap ) ;
TArray < FUnorderedAccessViewRHIParamRef > UAVs ;
PixelShader - > GetUAVs ( View , TileIntersectionResources , UAVs ) ;
RHICmdList . SetRenderTargets ( 0 , ( const FRHIRenderTargetView * ) NULL , NULL , UAVs . Num ( ) , UAVs . GetData ( ) ) ;
RHICmdList . SetViewport ( 0 , 0 , 0.0f , LightTileDimensions . X , LightTileDimensions . Y , 1.0f ) ;
// Render backfaces since camera may intersect
RHICmdList . SetRasterizerState ( View . bReverseCulling ? TStaticRasterizerState < FM_Solid , CM_CW > : : GetRHI ( ) : TStaticRasterizerState < FM_Solid , CM_CCW > : : GetRHI ( ) ) ;
RHICmdList . SetDepthStencilState ( TStaticDepthStencilState < false , CF_Always > : : GetRHI ( ) ) ;
RHICmdList . SetBlendState ( TStaticBlendState < > : : GetRHI ( ) ) ;
static FGlobalBoundShaderState BoundShaderState ;
SetGlobalBoundShaderState ( RHICmdList , View . GetFeatureLevel ( ) , BoundShaderState , GetVertexDeclarationFVector4 ( ) , * VertexShader , * PixelShader ) ;
VertexShader - > SetParameters ( RHICmdList , View , FVector2D ( LightTileDimensions . X , LightTileDimensions . Y ) , WorldToShadowValue , ShadowBoundingRadius ) ;
PixelShader - > SetParameters ( RHICmdList , View , FVector2D ( LightTileDimensions . X , LightTileDimensions . Y ) ) ;
RHICmdList . SetStreamSource ( 0 , StencilingGeometry : : GLowPolyStencilSphereVertexBuffer . VertexBufferRHI , sizeof ( FVector4 ) , 0 ) ;
RHICmdList . DrawIndexedPrimitiveIndirect (
PT_TriangleList ,
StencilingGeometry : : GLowPolyStencilSphereIndexBuffer . IndexBufferRHI ,
GShadowCulledObjectBuffers . Buffers . ObjectIndirectArguments . Buffer ,
0 ) ;
SetRenderTarget ( RHICmdList , NULL , NULL ) ;
}
}
}
2014-11-21 22:32:16 -05:00
bool SupportsDistanceFieldShadows ( ERHIFeatureLevel : : Type FeatureLevel , EShaderPlatform ShaderPlatform )
2014-09-03 18:17:19 -04:00
{
2014-11-21 22:32:16 -05:00
return GDistanceFieldShadowing
& & FeatureLevel > = ERHIFeatureLevel : : SM5
& & DoesPlatformSupportDistanceFieldShadowing ( ShaderPlatform ) ;
}
2014-09-03 18:17:19 -04:00
2014-11-21 22:32:16 -05:00
bool FDeferredShadingSceneRenderer : : ShouldPrepareForDistanceFieldShadows ( ) const
{
bool bSceneHasRayTracedDFShadows = false ;
2014-09-03 18:17:19 -04:00
2014-11-21 22:32:16 -05:00
for ( TSparseArray < FLightSceneInfoCompact > : : TConstIterator LightIt ( Scene - > Lights ) ; LightIt ; + + LightIt )
2014-09-03 18:17:19 -04:00
{
2014-11-21 22:32:16 -05:00
const FLightSceneInfoCompact & LightSceneInfoCompact = * LightIt ;
const FLightSceneInfo * const LightSceneInfo = LightSceneInfoCompact . LightSceneInfo ;
2014-09-03 18:17:19 -04:00
2014-11-21 22:32:16 -05:00
if ( LightSceneInfo - > ShouldRenderLightViewIndependent ( ) )
2014-09-03 18:17:19 -04:00
{
2014-11-21 22:32:16 -05:00
const FVisibleLightInfo & VisibleLightInfo = VisibleLightInfos [ LightSceneInfo - > Id ] ;
2014-09-03 18:17:19 -04:00
2014-11-21 22:32:16 -05:00
for ( int32 ShadowIndex = 0 ; ShadowIndex < VisibleLightInfo . AllProjectedShadows . Num ( ) ; ShadowIndex + + )
2014-09-03 18:17:19 -04:00
{
2014-11-21 22:32:16 -05:00
const FProjectedShadowInfo * ProjectedShadowInfo = VisibleLightInfo . AllProjectedShadows [ ShadowIndex ] ;
2014-09-03 18:17:19 -04:00
2015-01-23 17:48:57 -05:00
if ( ProjectedShadowInfo - > CascadeSettings . bRayTracedDistanceField )
2014-09-18 15:13:07 -04:00
{
2014-11-21 22:32:16 -05:00
bSceneHasRayTracedDFShadows = true ;
break ;
2014-09-18 15:13:07 -04:00
}
2014-09-03 18:17:19 -04:00
}
}
}
2014-11-21 22:32:16 -05:00
return ViewFamily . EngineShowFlags . DynamicShadows
& & bSceneHasRayTracedDFShadows
& & SupportsDistanceFieldShadows ( Scene - > GetFeatureLevel ( ) , Scene - > GetShaderPlatform ( ) ) ;
2014-09-03 18:17:19 -04:00
}
2014-09-18 15:13:07 -04:00
void FProjectedShadowInfo : : RenderRayTracedDistanceFieldProjection ( FRHICommandListImmediate & RHICmdList , const FViewInfo & View ) const
2014-09-03 18:17:19 -04:00
{
2014-11-21 22:32:16 -05:00
if ( SupportsDistanceFieldShadows ( View . GetFeatureLevel ( ) , View . GetShaderPlatform ( ) ) )
2014-09-03 18:17:19 -04:00
{
QUICK_SCOPE_CYCLE_COUNTER ( STAT_RenderRayTracedDistanceFieldShadows ) ;
2014-10-20 10:43:43 -04:00
SCOPED_DRAW_EVENT ( RHICmdList , RayTracedDistanceFieldShadow ) ;
2014-09-03 18:17:19 -04:00
2014-11-21 22:32:16 -05:00
const FScene * Scene = ( const FScene * ) ( View . Family - > Scene ) ;
2014-09-03 18:17:19 -04:00
2014-11-21 22:32:16 -05:00
if ( GDistanceFieldVolumeTextureAtlas . VolumeTextureRHI & & Scene - > DistanceFieldSceneData . NumObjectsInBuffer > 0 )
2014-09-03 18:17:19 -04:00
{
2014-11-21 22:32:16 -05:00
check ( ! Scene - > DistanceFieldSceneData . HasPendingOperations ( ) ) ;
2014-09-03 18:17:19 -04:00
2014-11-21 22:32:16 -05:00
GSceneRenderTargets . FinishRenderingLightAttenuation ( RHICmdList ) ;
SetRenderTarget ( RHICmdList , NULL , NULL ) ;
2014-12-16 20:00:22 -05:00
int32 NumPlanes = 0 ;
const FPlane * PlaneData = NULL ;
FVector4 ShadowBoundingSphereValue ( 0 , 0 , 0 , 0 ) ;
if ( bDirectionalLight )
2014-11-21 22:32:16 -05:00
{
2014-12-16 20:00:22 -05:00
NumPlanes = CascadeSettings . ShadowBoundsAccurate . Planes . Num ( ) ;
PlaneData = CascadeSettings . ShadowBoundsAccurate . Planes . GetData ( ) ;
2014-09-03 18:17:19 -04:00
}
2015-01-23 17:48:57 -05:00
else if ( CascadeSettings . bOnePassPointLightShadow )
2014-12-16 20:00:22 -05:00
{
ShadowBoundingSphereValue = FVector4 ( ShadowBounds . Center . X , ShadowBounds . Center . Y , ShadowBounds . Center . Z , ShadowBounds . W ) ;
}
else
{
NumPlanes = CasterFrustum . Planes . Num ( ) ;
PlaneData = CasterFrustum . Planes . GetData ( ) ;
ShadowBoundingSphereValue = FVector4 ( PreShadowTranslation , 0 ) ;
}
const FMatrix WorldToShadowValue = FTranslationMatrix ( PreShadowTranslation ) * SubjectAndReceiverMatrix ;
CullDistanceFieldObjectsForLight (
RHICmdList ,
View ,
LightSceneInfo - > Proxy ,
WorldToShadowValue ,
NumPlanes ,
PlaneData ,
ShadowBoundingSphereValue ,
ShadowBounds . W ,
LightSceneInfo - > TileIntersectionResources
) ;
FLightTileIntersectionResources * TileIntersectionResources = LightSceneInfo - > TileIntersectionResources ;
2014-11-21 22:32:16 -05:00
2015-02-06 23:31:19 -05:00
View . HeightfieldLightingViewInfo . ComputeRayTracedShadowing ( View , RHICmdList , this , TileIntersectionResources , GShadowCulledObjectBuffers ) ;
2014-11-21 22:32:16 -05:00
TRefCountPtr < IPooledRenderTarget > RayTracedShadowsRT ;
{
2015-01-29 18:21:57 -05:00
const FIntPoint BufferSize = GetBufferSizeForDFShadows ( ) ;
2014-11-21 22:32:16 -05:00
FPooledRenderTargetDesc Desc ( FPooledRenderTargetDesc : : Create2DDesc ( BufferSize , PF_G16R16F , TexCreate_None , TexCreate_RenderTargetable | TexCreate_UAV , false ) ) ;
GRenderTargetPool . FindFreeElement ( Desc , RayTracedShadowsRT , TEXT ( " RayTracedShadows " ) ) ;
}
FIntRect ScissorRect ;
{
if ( ! LightSceneInfo - > Proxy - > GetScissorRect ( ScissorRect , View ) )
{
ScissorRect = View . ViewRect ;
}
2015-01-29 18:21:57 -05:00
uint32 GroupSizeX = FMath : : DivideAndRoundUp ( ScissorRect . Size ( ) . X / GetDFShadowDownsampleFactor ( ) , GDistanceFieldAOTileSizeX ) ;
uint32 GroupSizeY = FMath : : DivideAndRoundUp ( ScissorRect . Size ( ) . Y / GetDFShadowDownsampleFactor ( ) , GDistanceFieldAOTileSizeY ) ;
2014-11-21 22:32:16 -05:00
{
SCOPED_DRAW_EVENT ( RHICmdList , RayTraceShadows ) ;
2015-02-06 23:31:19 -05:00
SetRenderTarget ( RHICmdList , NULL , NULL ) ;
2014-11-21 22:32:16 -05:00
if ( bDirectionalLight & & GShadowScatterTileCulling )
{
TShaderMapRef < TDistanceFieldShadowingCS < DFS_DirectionalLightScatterTileCulling > > ComputeShader ( View . ShaderMap ) ;
RHICmdList . SetComputeShader ( ComputeShader - > GetComputeShader ( ) ) ;
ComputeShader - > SetParameters ( RHICmdList , View , this , RayTracedShadowsRT - > GetRenderTargetItem ( ) , FVector2D ( GroupSizeX , GroupSizeY ) , ScissorRect , TileIntersectionResources ) ;
DispatchComputeShader ( RHICmdList , * ComputeShader , GroupSizeX , GroupSizeY , 1 ) ;
ComputeShader - > UnsetParameters ( RHICmdList ) ;
}
else if ( bDirectionalLight )
{
TShaderMapRef < TDistanceFieldShadowingCS < DFS_DirectionalLightTiledCulling > > ComputeShader ( View . ShaderMap ) ;
RHICmdList . SetComputeShader ( ComputeShader - > GetComputeShader ( ) ) ;
ComputeShader - > SetParameters ( RHICmdList , View , this , RayTracedShadowsRT - > GetRenderTargetItem ( ) , FVector2D ( GroupSizeX , GroupSizeY ) , ScissorRect , TileIntersectionResources ) ;
DispatchComputeShader ( RHICmdList , * ComputeShader , GroupSizeX , GroupSizeY , 1 ) ;
ComputeShader - > UnsetParameters ( RHICmdList ) ;
}
else
{
TShaderMapRef < TDistanceFieldShadowingCS < DFS_PointLightTiledCulling > > ComputeShader ( View . ShaderMap ) ;
RHICmdList . SetComputeShader ( ComputeShader - > GetComputeShader ( ) ) ;
ComputeShader - > SetParameters ( RHICmdList , View , this , RayTracedShadowsRT - > GetRenderTargetItem ( ) , FVector2D ( GroupSizeX , GroupSizeY ) , ScissorRect , TileIntersectionResources ) ;
DispatchComputeShader ( RHICmdList , * ComputeShader , GroupSizeX , GroupSizeY , 1 ) ;
ComputeShader - > UnsetParameters ( RHICmdList ) ;
}
}
}
{
GSceneRenderTargets . BeginRenderingLightAttenuation ( RHICmdList ) ;
SCOPED_DRAW_EVENT ( RHICmdList , Upsample ) ;
RHICmdList . SetViewport ( ScissorRect . Min . X , ScissorRect . Min . Y , 0.0f , ScissorRect . Max . X , ScissorRect . Max . Y , 1.0f ) ;
RHICmdList . SetRasterizerState ( TStaticRasterizerState < FM_Solid , CM_None > : : GetRHI ( ) ) ;
RHICmdList . SetDepthStencilState ( TStaticDepthStencilState < false , CF_Always > : : GetRHI ( ) ) ;
2015-03-02 14:11:33 -05:00
2014-11-21 22:32:16 -05:00
if ( bDirectionalLight )
{
2015-03-02 14:11:33 -05:00
// use R and G in Light Attenuation for directional lights
// CO_Min is needed to combine with far shadows which overlap the same depth range
2014-11-21 22:32:16 -05:00
RHICmdList . SetBlendState ( TStaticBlendState < CW_RG , BO_Min , BF_One , BF_One > : : GetRHI ( ) ) ;
}
else
{
// use B and A in Light Attenuation
2015-03-02 14:11:33 -05:00
// CO_Min is needed to combine multiple shadow passes
2014-11-21 22:32:16 -05:00
RHICmdList . SetBlendState ( TStaticBlendState < CW_BA , BO_Min , BF_One , BF_One , BO_Min , BF_One , BF_One > : : GetRHI ( ) ) ;
}
TShaderMapRef < FPostProcessVS > VertexShader ( View . ShaderMap ) ;
2015-01-29 18:21:57 -05:00
if ( GFullResolutionDFShadowing )
{
TShaderMapRef < TDistanceFieldShadowingUpsamplePS < false > > PixelShader ( View . ShaderMap ) ;
2014-11-21 22:32:16 -05:00
2015-01-29 18:21:57 -05:00
static FGlobalBoundShaderState BoundShaderState ;
SetGlobalBoundShaderState ( RHICmdList , View . GetFeatureLevel ( ) , BoundShaderState , GFilterVertexDeclaration . VertexDeclarationRHI , * VertexShader , * PixelShader ) ;
2014-11-21 22:32:16 -05:00
2015-01-29 18:21:57 -05:00
VertexShader - > SetParameters ( RHICmdList , View ) ;
PixelShader - > SetParameters ( RHICmdList , View , this , ScissorRect , RayTracedShadowsRT ) ;
}
else
{
TShaderMapRef < TDistanceFieldShadowingUpsamplePS < true > > PixelShader ( View . ShaderMap ) ;
static FGlobalBoundShaderState BoundShaderState ;
SetGlobalBoundShaderState ( RHICmdList , View . GetFeatureLevel ( ) , BoundShaderState , GFilterVertexDeclaration . VertexDeclarationRHI , * VertexShader , * PixelShader ) ;
VertexShader - > SetParameters ( RHICmdList , View ) ;
PixelShader - > SetParameters ( RHICmdList , View , this , ScissorRect , RayTracedShadowsRT ) ;
}
2014-11-21 22:32:16 -05:00
DrawRectangle (
RHICmdList ,
0 , 0 ,
ScissorRect . Width ( ) , ScissorRect . Height ( ) ,
2015-01-29 18:21:57 -05:00
ScissorRect . Min . X / GetDFShadowDownsampleFactor ( ) , ScissorRect . Min . Y / GetDFShadowDownsampleFactor ( ) ,
ScissorRect . Width ( ) / GetDFShadowDownsampleFactor ( ) , ScissorRect . Height ( ) / GetDFShadowDownsampleFactor ( ) ,
2014-11-21 22:32:16 -05:00
FIntPoint ( ScissorRect . Width ( ) , ScissorRect . Height ( ) ) ,
2015-01-29 18:21:57 -05:00
GetBufferSizeForDFShadows ( ) ,
2014-11-21 22:32:16 -05:00
* VertexShader ) ;
}
2014-09-03 18:17:19 -04:00
}
}
}