2020-06-23 18:40:00 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
/*=============================================================================
Functionality for capturing and pre - filtering a sky env map in real time .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
# include "ReflectionEnvironmentCapture.h"
# include "ClearQuad.h"
# include "MeshPassProcessor.h"
# include "PrimitiveSceneProxy.h"
# include "MeshPassProcessor.inl"
# include "ScenePrivate.h"
# include "SkyPassRendering.h"
# include "RenderGraphUtils.h"
# include "VolumetricCloudRendering.h"
# include "VolumetricCloudProxy.h"
2020-08-11 01:36:57 -04:00
# include "FogRendering.h"
2020-09-01 14:07:48 -04:00
# include "GPUScene.h"
2021-04-29 17:55:33 -04:00
# include "ScreenPass.h"
2020-06-23 18:40:00 -04:00
2020-09-01 14:07:48 -04:00
# if WITH_EDITOR
# include "CanvasTypes.h"
# include "RenderTargetTemp.h"
# endif
2020-06-23 18:40:00 -04:00
extern float GReflectionCaptureNearPlane ;
DECLARE_GPU_STAT ( CaptureConvolveSkyEnvMap ) ;
static TAutoConsoleVariable < int32 > CVarRealTimeReflectionCaptureTimeSlicing (
2020-09-01 14:07:48 -04:00
TEXT ( " r.SkyLight.RealTimeReflectionCapture.TimeSlice " ) , 1 ,
TEXT ( " When enabled, the real-time sky light capture and convolutions will by distributed over several frames to lower the per-frame cost. " ) ,
2020-06-23 18:40:00 -04:00
ECVF_RenderThreadSafe ) ;
2020-08-11 01:36:57 -04:00
static TAutoConsoleVariable < int32 > CVarRealTimeReflectionCaptureShadowFromOpaque (
2020-09-01 14:07:48 -04:00
TEXT ( " r.SkyLight.RealTimeReflectionCapture.ShadowFromOpaque " ) , 0 ,
2020-09-24 00:43:27 -04:00
TEXT ( " Opaque meshes cast shadow from directional lights onto sky and clouds when enabled. \n " ) ,
2020-09-01 14:07:48 -04:00
ECVF_RenderThreadSafe ) ;
static TAutoConsoleVariable < int32 > CVarRealTimeReflectionCaptureDepthBuffer (
TEXT ( " r.SkyLight.RealTimeReflectionCapture.DepthBuffer " ) , 1 ,
2021-02-24 20:13:15 -04:00
TEXT ( " When enabled, the real-time sky light capture will have a depth buffer, this is for multiple meshes to be cover each other correctly. The height fog will also be applied according to the depth buffer. " ) ,
2020-08-11 01:36:57 -04:00
ECVF_RenderThreadSafe ) ;
2020-06-23 18:40:00 -04:00
class FDownsampleCubeFaceCS : public FGlobalShader
{
DECLARE_GLOBAL_SHADER ( FDownsampleCubeFaceCS ) ;
SHADER_USE_PARAMETER_STRUCT ( FDownsampleCubeFaceCS , FGlobalShader ) ;
static const uint32 ThreadGroupSize = 8 ;
using FPermutationDomain = TShaderPermutationDomain < > ;
BEGIN_SHADER_PARAMETER_STRUCT ( FParameters , )
SHADER_PARAMETER ( uint32 , MipIndex )
SHADER_PARAMETER ( uint32 , NumMips )
SHADER_PARAMETER ( int32 , CubeFace )
SHADER_PARAMETER ( int32 , FaceThreadGroupSize )
SHADER_PARAMETER ( FIntPoint , ValidDispatchCoord )
SHADER_PARAMETER_RDG_TEXTURE_SRV ( TextureCube , SourceCubemapTexture )
SHADER_PARAMETER_SAMPLER ( SamplerState , SourceCubemapSampler )
SHADER_PARAMETER_RDG_TEXTURE_UAV ( RWTexture2D , OutTextureMipColor )
END_SHADER_PARAMETER_STRUCT ( )
public :
static bool ShouldCompilePermutation ( const FGlobalShaderPermutationParameters & Parameters ) { return GetMaxSupportedFeatureLevel ( Parameters . Platform ) > = ERHIFeatureLevel : : SM5 ; }
static void ModifyCompilationEnvironment ( const FGlobalShaderPermutationParameters & Parameters , FShaderCompilerEnvironment & OutEnvironment )
{
FGlobalShader : : ModifyCompilationEnvironment ( Parameters , OutEnvironment ) ;
OutEnvironment . SetDefine ( TEXT ( " THREADGROUP_SIZE " ) , ThreadGroupSize ) ;
OutEnvironment . SetDefine ( TEXT ( " USE_COMPUTE " ) , 1 ) ;
}
} ;
IMPLEMENT_GLOBAL_SHADER ( FDownsampleCubeFaceCS , " /Engine/Private/ReflectionEnvironmentShaders.usf " , " DownsampleCS " , SF_Compute ) ;
class FConvolveSpecularFaceCS : public FGlobalShader
{
DECLARE_GLOBAL_SHADER ( FConvolveSpecularFaceCS ) ;
SHADER_USE_PARAMETER_STRUCT ( FConvolveSpecularFaceCS , FGlobalShader ) ;
static const uint32 ThreadGroupSize = 8 ;
using FPermutationDomain = TShaderPermutationDomain < > ;
BEGIN_SHADER_PARAMETER_STRUCT ( FParameters , )
SHADER_PARAMETER ( uint32 , MipIndex )
SHADER_PARAMETER ( uint32 , NumMips )
2020-09-01 14:07:48 -04:00
SHADER_PARAMETER ( int32 , CubeFaceOffset )
2020-06-23 18:40:00 -04:00
SHADER_PARAMETER ( int32 , CubeFace )
SHADER_PARAMETER ( int32 , FaceThreadGroupSize )
SHADER_PARAMETER ( FIntPoint , ValidDispatchCoord )
SHADER_PARAMETER_RDG_TEXTURE_SRV ( TextureCube , SourceCubemapTexture )
SHADER_PARAMETER_SAMPLER ( SamplerState , SourceCubemapSampler )
SHADER_PARAMETER_RDG_TEXTURE_UAV ( RWTexture2D , OutTextureMipColor )
END_SHADER_PARAMETER_STRUCT ( )
public :
static bool ShouldCompilePermutation ( const FGlobalShaderPermutationParameters & Parameters ) { return GetMaxSupportedFeatureLevel ( Parameters . Platform ) > = ERHIFeatureLevel : : SM5 ; }
static void ModifyCompilationEnvironment ( const FGlobalShaderPermutationParameters & Parameters , FShaderCompilerEnvironment & OutEnvironment )
{
FGlobalShader : : ModifyCompilationEnvironment ( Parameters , OutEnvironment ) ;
OutEnvironment . SetDefine ( TEXT ( " THREADGROUP_SIZE " ) , ThreadGroupSize ) ;
OutEnvironment . SetDefine ( TEXT ( " USE_COMPUTE " ) , 1 ) ;
}
} ;
IMPLEMENT_GLOBAL_SHADER ( FConvolveSpecularFaceCS , " /Engine/Private/ReflectionEnvironmentShaders.usf " , " FilterCS " , SF_Compute ) ;
class FComputeSkyEnvMapDiffuseIrradianceCS : public FGlobalShader
{
DECLARE_GLOBAL_SHADER ( FComputeSkyEnvMapDiffuseIrradianceCS ) ;
SHADER_USE_PARAMETER_STRUCT ( FComputeSkyEnvMapDiffuseIrradianceCS , FGlobalShader ) ;
// 8*8=64 threads in a group.
// Each thread uses 4*7*RGB sh float => 84 bytes shared group memory.
// 64 * 84 = 5376 bytes which fits dx11 16KB shared memory limitation. 6144 with vector alignement in shared memory and it still fits
// Low occupancy on a single CU.
static const uint32 ThreadGroupSizeX = 8 ;
static const uint32 ThreadGroupSizeY = 8 ;
using FPermutationDomain = TShaderPermutationDomain < > ;
BEGIN_SHADER_PARAMETER_STRUCT ( FParameters , )
SHADER_PARAMETER_RDG_TEXTURE_SRV ( TextureCube , SourceCubemapTexture )
SHADER_PARAMETER_SAMPLER ( SamplerState , SourceCubemapSampler )
SHADER_PARAMETER_UAV ( RWStructuredBuffer , OutIrradianceEnvMapSH )
SHADER_PARAMETER ( float , UniformSampleSolidAngle )
SHADER_PARAMETER ( uint32 , MipIndex )
END_SHADER_PARAMETER_STRUCT ( )
public :
static bool ShouldCompilePermutation ( const FGlobalShaderPermutationParameters & Parameters ) { return GetMaxSupportedFeatureLevel ( Parameters . Platform ) > = ERHIFeatureLevel : : SM5 ; }
static void ModifyCompilationEnvironment ( const FGlobalShaderPermutationParameters & Parameters , FShaderCompilerEnvironment & OutEnvironment )
{
FGlobalShader : : ModifyCompilationEnvironment ( Parameters , OutEnvironment ) ;
OutEnvironment . SetDefine ( TEXT ( " THREADGROUP_SIZE_X " ) , ThreadGroupSizeX ) ;
OutEnvironment . SetDefine ( TEXT ( " THREADGROUP_SIZE_Y " ) , ThreadGroupSizeY ) ;
OutEnvironment . SetDefine ( TEXT ( " SHADER_DIFFUSE_TO_SH " ) , 1 ) ;
}
} ;
IMPLEMENT_GLOBAL_SHADER ( FComputeSkyEnvMapDiffuseIrradianceCS , " /Engine/Private/ReflectionEnvironmentShaders.usf " , " ComputeSkyEnvMapDiffuseIrradianceCS " , SF_Compute ) ;
2020-08-11 01:36:57 -04:00
class FApplyLowerHemisphereColor : public FGlobalShader
{
DECLARE_GLOBAL_SHADER ( FApplyLowerHemisphereColor ) ;
SHADER_USE_PARAMETER_STRUCT ( FApplyLowerHemisphereColor , FGlobalShader ) ;
static const uint32 ThreadGroupSize = 8 ;
using FPermutationDomain = TShaderPermutationDomain < > ;
BEGIN_SHADER_PARAMETER_STRUCT ( FParameters , )
SHADER_PARAMETER ( FLinearColor , LowerHemisphereSolidColor )
SHADER_PARAMETER ( FIntPoint , ValidDispatchCoord )
SHADER_PARAMETER ( int32 , FaceThreadGroupSize )
SHADER_PARAMETER_RDG_TEXTURE_UAV ( RWTexture2D , OutTextureMipColor )
END_SHADER_PARAMETER_STRUCT ( )
public :
static bool ShouldCompilePermutation ( const FGlobalShaderPermutationParameters & Parameters ) { return GetMaxSupportedFeatureLevel ( Parameters . Platform ) > = ERHIFeatureLevel : : SM5 ; }
static void ModifyCompilationEnvironment ( const FGlobalShaderPermutationParameters & Parameters , FShaderCompilerEnvironment & OutEnvironment )
{
FGlobalShader : : ModifyCompilationEnvironment ( Parameters , OutEnvironment ) ;
OutEnvironment . SetDefine ( TEXT ( " THREADGROUP_SIZE " ) , ThreadGroupSize ) ;
OutEnvironment . SetDefine ( TEXT ( " USE_COMPUTE " ) , 1 ) ;
}
} ;
IMPLEMENT_GLOBAL_SHADER ( FApplyLowerHemisphereColor , " /Engine/Private/ReflectionEnvironmentShaders.usf " , " ApplyLowerHemisphereColorCS " , SF_Compute ) ;
class FRenderRealTimeReflectionHeightFogVS : public FGlobalShader
{
DECLARE_GLOBAL_SHADER ( FRenderRealTimeReflectionHeightFogVS ) ;
SHADER_USE_PARAMETER_STRUCT ( FRenderRealTimeReflectionHeightFogVS , FGlobalShader ) ; ;
BEGIN_SHADER_PARAMETER_STRUCT ( FParameters , )
SHADER_PARAMETER_STRUCT_REF ( FViewUniformShaderParameters , ViewUniformBuffer )
END_SHADER_PARAMETER_STRUCT ( )
using FPermutationDomain = TShaderPermutationDomain < > ;
static FPermutationDomain RemapPermutation ( FPermutationDomain PermutationVector )
{
return PermutationVector ;
}
static bool ShouldCompilePermutation ( const FGlobalShaderPermutationParameters & Parameters )
{
return true ;
}
static void ModifyCompilationEnvironment ( const FGlobalShaderPermutationParameters & Parameters , FShaderCompilerEnvironment & OutEnvironment )
{
FGlobalShader : : ModifyCompilationEnvironment ( Parameters , OutEnvironment ) ;
OutEnvironment . SetDefine ( TEXT ( " REALTIME_REFLECTION_HEIGHT_FOG " ) , 1 ) ;
}
} ;
IMPLEMENT_GLOBAL_SHADER ( FRenderRealTimeReflectionHeightFogVS , " /Engine/Private/ReflectionEnvironmentShaders.usf " , " RenderRealTimeReflectionHeightFogVS " , SF_Vertex ) ;
class FRenderRealTimeReflectionHeightFogPS : public FGlobalShader
{
DECLARE_GLOBAL_SHADER ( FRenderRealTimeReflectionHeightFogPS ) ;
SHADER_USE_PARAMETER_STRUCT ( FRenderRealTimeReflectionHeightFogPS , FGlobalShader ) ;
2020-09-01 14:07:48 -04:00
class FDepthTexture : SHADER_PERMUTATION_BOOL ( " PERMUTATION_DEPTHTEXTURE " ) ;
using FPermutationDomain = TShaderPermutationDomain < FDepthTexture > ;
2020-08-11 01:36:57 -04:00
BEGIN_SHADER_PARAMETER_STRUCT ( FParameters , )
SHADER_PARAMETER_STRUCT_REF ( FViewUniformShaderParameters , ViewUniformBuffer )
2020-09-24 00:43:27 -04:00
SHADER_PARAMETER_RDG_UNIFORM_BUFFER ( FFogUniformParameters , FogStruct )
2020-09-01 14:07:48 -04:00
SHADER_PARAMETER_RDG_TEXTURE ( Texture2D , DepthTexture )
2020-08-11 01:36:57 -04:00
RENDER_TARGET_BINDING_SLOTS ( )
END_SHADER_PARAMETER_STRUCT ( )
static FPermutationDomain RemapPermutation ( FPermutationDomain PermutationVector )
{
return PermutationVector ;
}
static bool ShouldCompilePermutation ( const FGlobalShaderPermutationParameters & Parameters )
{
return true ;
}
static void ModifyCompilationEnvironment ( const FGlobalShaderPermutationParameters & Parameters , FShaderCompilerEnvironment & OutEnvironment )
{
FGlobalShader : : ModifyCompilationEnvironment ( Parameters , OutEnvironment ) ;
OutEnvironment . SetDefine ( TEXT ( " REALTIME_REFLECTION_HEIGHT_FOG " ) , 1 ) ;
}
} ;
IMPLEMENT_GLOBAL_SHADER ( FRenderRealTimeReflectionHeightFogPS , " /Engine/Private/ReflectionEnvironmentShaders.usf " , " RenderRealTimeReflectionHeightFogPS " , SF_Pixel ) ;
2020-09-24 00:43:27 -04:00
void FScene : : ValidateSkyLightRealTimeCapture (
FRDGBuilder & GraphBuilder ,
const FViewInfo & View ,
FRDGTextureRef SceneColorTexture )
2020-09-01 14:07:48 -04:00
{
# if WITH_EDITOR
bool bSkyMeshInMainPassExist = false ;
bool bSkyMeshInRealTimeSkyCaptureExtist = false ;
2020-09-24 00:43:27 -04:00
const int32 SkyRealTimeReflectionOnlyMeshBatcheCount = View . SkyMeshBatches . Num ( ) ;
2020-09-01 14:07:48 -04:00
for ( int32 MeshBatchIndex = 0 ; MeshBatchIndex < SkyRealTimeReflectionOnlyMeshBatcheCount ; + + MeshBatchIndex )
{
2020-09-24 00:43:27 -04:00
const FSkyMeshBatch & SkyMeshBatch = View . SkyMeshBatches [ MeshBatchIndex ] ;
2020-09-01 14:07:48 -04:00
bSkyMeshInMainPassExist | = SkyMeshBatch . bVisibleInMainPass ;
bSkyMeshInRealTimeSkyCaptureExtist | = SkyMeshBatch . bVisibleInRealTimeSkyCapture ;
}
if ( ! bSkyMeshInMainPassExist | | ! bSkyMeshInRealTimeSkyCaptureExtist )
{
2020-09-24 00:43:27 -04:00
AddDrawCanvasPass ( GraphBuilder , { } , View , FScreenPassRenderTarget ( SceneColorTexture , View . ViewRect , ERenderTargetLoadAction : : ELoad ) , [ this , & View , bSkyMeshInMainPassExist , bSkyMeshInRealTimeSkyCaptureExtist ] ( FCanvas & Canvas )
{
FLinearColor TextColor ( 1.0f , 0.5f , 0.0f ) ;
2020-09-01 14:07:48 -04:00
2020-09-24 00:43:27 -04:00
if ( View . bSceneHasSkyMaterial & & ! bSkyMeshInMainPassExist )
{
Canvas . DrawShadowedString ( 100.0f , 100.0f , TEXT ( " At least one mesh with a sky material is in the scene but none are rendered in main view. " ) , GetStatsFont ( ) , TextColor ) ;
}
if ( View . bSceneHasSkyMaterial & & ! bSkyMeshInRealTimeSkyCaptureExtist & & SkyLight & & SkyLight - > bRealTimeCaptureEnabled )
{
Canvas . DrawShadowedString ( 100.0f , 110.0f , TEXT ( " At least one mesh with a sky material is in the scene but none are rendered in the real-time sky light reflection. " ) , GetStatsFont ( ) , TextColor ) ;
}
} ) ;
2020-09-01 14:07:48 -04:00
}
# endif
}
2020-09-24 00:43:27 -04:00
BEGIN_SHADER_PARAMETER_STRUCT ( FCaptureSkyMeshReflectionPassParameters , )
2020-12-09 13:11:49 -04:00
SHADER_PARAMETER_STRUCT_INCLUDE ( FViewShaderParameters , View )
2021-01-14 05:23:34 -04:00
SHADER_PARAMETER_STRUCT_INCLUDE ( FInstanceCullingDrawParams , InstanceCullingDrawParams )
2020-09-24 00:43:27 -04:00
SHADER_PARAMETER_RDG_UNIFORM_BUFFER ( FOpaqueBasePassUniformParameters , BasePass )
RENDER_TARGET_BINDING_SLOTS ( )
END_SHADER_PARAMETER_STRUCT ( )
2020-09-01 14:07:48 -04:00
2020-06-23 18:40:00 -04:00
void FScene : : AllocateAndCaptureFrameSkyEnvMap (
2020-09-24 00:43:27 -04:00
FRDGBuilder & GraphBuilder , FSceneRenderer & SceneRenderer , FViewInfo & MainView ,
2021-01-14 05:23:34 -04:00
bool bShouldRenderSkyAtmosphere , bool bShouldRenderVolumetricCloud , FInstanceCullingManager & InstanceCullingManager )
2020-06-23 18:40:00 -04:00
{
check ( SkyLight & & SkyLight - > bRealTimeCaptureEnabled & & ! SkyLight - > bHasStaticLighting ) ;
2021-12-02 03:07:02 -05:00
// Ignore viewfamilies without the Atmosphere showflag enabled as the sky capture may fail otherwise
// as well as all views being "scene captures" which cannot be used to update the sky light data.
if ( MainView . bIsSceneCapture | | ! MainView . Family - > EngineShowFlags . Atmosphere )
2021-04-29 19:32:06 -04:00
{
return ;
}
const bool bIsNewFrame = GFrameNumberRenderThread ! = RealTimeSlicedReflectionCaptureFrameNumber ;
RealTimeSlicedReflectionCaptureFrameNumber = GFrameNumberRenderThread ;
2020-09-24 00:43:27 -04:00
RDG_EVENT_SCOPE ( GraphBuilder , " CaptureConvolveSkyEnvMap " ) ;
RDG_GPU_STAT_SCOPE ( GraphBuilder , CaptureConvolveSkyEnvMap ) ;
2020-06-23 18:40:00 -04:00
const uint32 CubeWidth = SkyLight - > CaptureCubeMapResolution ;
const uint32 CubeMipCount = FMath : : CeilLogTwo ( CubeWidth ) + 1 ;
// Make a snapshot we are going to use for the 6 cubemap faces and set it up.
2020-08-11 01:36:57 -04:00
// Note: cube view is not meant to be sent to lambdas because we only create a single one. You should only send the ViewUniformBuffer around.
2020-06-23 18:40:00 -04:00
FViewInfo & CubeView = * MainView . CreateSnapshot ( ) ;
CubeView . FOV = 90.0f ;
2020-09-01 14:07:48 -04:00
// Note: We cannot override exposure because sky input texture are using exposure
// Other view data clean up
2021-11-24 21:57:34 -05:00
CubeView . StereoPass = EStereoscopicPass : : eSSP_FULL ;
2020-09-01 14:07:48 -04:00
CubeView . DrawDynamicFlags = EDrawDynamicFlags : : ForceLowestLOD ;
CubeView . MaterialTextureMipBias = 0 ;
2020-06-23 18:40:00 -04:00
FViewMatrices : : FMinimalInitializer SceneCubeViewInitOptions ;
SceneCubeViewInitOptions . ConstrainedViewRect = FIntRect ( FIntPoint ( 0 , 0 ) , FIntPoint ( CubeWidth , CubeWidth ) ) ;
FBox VolumeBounds [ TVC_MAX ] ;
CubeView . CachedViewUniformShaderParameters = MakeUnique < FViewUniformShaderParameters > ( ) ;
CubeView . SetupUniformBufferParameters (
VolumeBounds ,
TVC_MAX ,
* CubeView . CachedViewUniformShaderParameters ) ;
const FMatrix CubeProjectionMatrix = GetCubeProjectionMatrix ( CubeView . FOV * 0.5f , ( float ) CubeWidth , GReflectionCaptureNearPlane ) ;
CubeView . UpdateProjectionMatrix ( CubeProjectionMatrix ) ;
FPooledRenderTargetDesc SkyCubeTexDesc = FPooledRenderTargetDesc : : CreateCubemapDesc ( CubeWidth ,
PF_FloatR11G11B10 , FClearValueBinding : : Black , TexCreate_TargetArraySlicesIndependently ,
2020-09-01 14:07:48 -04:00
TexCreate_ShaderResource | TexCreate_UAV | TexCreate_RenderTargetable , false , 1 , CubeMipCount , false ) ;
2020-06-23 18:40:00 -04:00
const bool bTimeSlicedRealTimeCapture = CVarRealTimeReflectionCaptureTimeSlicing . GetValueOnRenderThread ( ) > 0 ;
2020-09-01 14:07:48 -04:00
const bool CubeResolutionInvalidated = ConvolvedSkyRenderTargetReadyIndex < 0 | | ( ConvolvedSkyRenderTarget [ ConvolvedSkyRenderTargetReadyIndex ] . IsValid ( ) & & ConvolvedSkyRenderTarget [ ConvolvedSkyRenderTargetReadyIndex ] - > GetDesc ( ) . GetSize ( ) . X ! = CubeWidth ) ;
if ( ! ConvolvedSkyRenderTarget [ 0 ] . IsValid ( ) | | CubeResolutionInvalidated )
2020-06-23 18:40:00 -04:00
{
2020-09-01 14:07:48 -04:00
// Always allocated
2021-02-02 05:19:56 -04:00
GRenderTargetPool . FindFreeElement ( GraphBuilder . RHICmdList , SkyCubeTexDesc , ConvolvedSkyRenderTarget [ 0 ] , TEXT ( " SkyLight.ConvolvedSkyRenderTarget0 " ) , ERenderTargetTransience : : NonTransient ) ;
GRenderTargetPool . FindFreeElement ( GraphBuilder . RHICmdList , SkyCubeTexDesc , CapturedSkyRenderTarget , TEXT ( " SkyLight.CapturedSkyRenderTarget " ) , ERenderTargetTransience : : NonTransient ) ;
2020-06-23 18:40:00 -04:00
}
2020-09-01 14:07:48 -04:00
if ( bTimeSlicedRealTimeCapture & & ( CubeResolutionInvalidated | | ! ConvolvedSkyRenderTarget [ ConvolvedSkyRenderTargetReadyIndex ] . IsValid ( ) ) )
2020-06-23 18:40:00 -04:00
{
2020-09-01 14:07:48 -04:00
// Additional allocation for time slicing
2021-02-02 05:19:56 -04:00
GRenderTargetPool . FindFreeElement ( GraphBuilder . RHICmdList , SkyCubeTexDesc , ConvolvedSkyRenderTarget [ 1 ] , TEXT ( " SkyLight.ConvolvedSkyRenderTarget1 " ) , ERenderTargetTransience : : NonTransient ) ;
2020-06-23 18:40:00 -04:00
}
2020-12-09 11:13:00 -04:00
auto ClearCubeFace = [ & ] ( FRDGTextureRef SkyCubeTexture , int32 CubeFace )
{
FRenderTargetParameters * Parameters = GraphBuilder . AllocParameters < FRenderTargetParameters > ( ) ;
Parameters - > RenderTargets [ 0 ] = FRenderTargetBinding ( SkyCubeTexture , ERenderTargetLoadAction : : ENoAction , 0 , CubeFace ) ;
FLinearColor ClearColor = FLinearColor : : Black ;
GraphBuilder . AddPass (
RDG_EVENT_NAME ( " ClearSkyRenderTarget " ) ,
Parameters ,
ERDGPassFlags : : Raster ,
[ Parameters , ClearColor ] ( FRHICommandList & RHICmdList )
{
DrawClearQuad ( RHICmdList , ClearColor ) ;
} ) ;
} ;
2020-06-23 18:40:00 -04:00
2020-09-01 14:07:48 -04:00
auto RenderCubeFaces_SkyCloud = [ & ] ( bool bExecuteSky , bool bExecuteCloud , TRefCountPtr < IPooledRenderTarget > & SkyRenderTarget )
2020-06-23 18:40:00 -04:00
{
2020-08-11 01:36:57 -04:00
FScene * Scene = MainView . Family - > Scene - > GetRenderScene ( ) ;
2020-09-24 00:43:27 -04:00
FRDGTextureRef SkyCubeTexture = GraphBuilder . RegisterExternalTexture ( SkyRenderTarget , TEXT ( " SkyRenderTarget " ) ) ;
2020-12-09 11:13:00 -04:00
if ( bExecuteSky | | bExecuteCloud )
2020-06-23 18:40:00 -04:00
{
FRDGTextureRef BlackDummy2dTex = GraphBuilder . RegisterExternalTexture ( GSystemTextures . BlackDummy ) ;
FRDGTextureRef BlackDummy3dTex = GraphBuilder . RegisterExternalTexture ( GSystemTextures . VolumetricBlackDummy ) ;
2020-08-11 01:36:57 -04:00
const bool CaptureShadowFromOpaque = CVarRealTimeReflectionCaptureShadowFromOpaque . GetValueOnRenderThread ( ) > 0 ;
2020-12-09 11:13:00 -04:00
FSkyAtmosphereRenderContext SkyRC ;
const FAtmosphereSetup * AtmosphereSetup = nullptr ;
if ( bShouldRenderSkyAtmosphere )
2020-08-11 01:36:57 -04:00
{
2020-12-09 11:13:00 -04:00
FSkyAtmosphereRenderSceneInfo & SkyInfo = * GetSkyAtmosphereSceneInfo ( ) ;
const FSkyAtmosphereSceneProxy & SkyAtmosphereSceneProxy = SkyInfo . GetSkyAtmosphereSceneProxy ( ) ;
// Global data constant between faces
AtmosphereSetup = & SkyAtmosphereSceneProxy . GetAtmosphereSetup ( ) ;
SkyRC . bFastSky = false ;
SkyRC . bFastAerialPerspective = false ;
SkyRC . bFastAerialPerspectiveDepthTest = false ;
SkyRC . bSecondAtmosphereLightEnabled = IsSecondAtmosphereLightEnabled ( ) ;
// Enable opaque shadow on sky if needed
SkyRC . bShouldSampleOpaqueShadow = false ;
if ( CaptureShadowFromOpaque )
{
SkyAtmosphereLightShadowData LightShadowData ;
SkyRC . bShouldSampleOpaqueShadow = ShouldSkySampleAtmosphereLightsOpaqueShadow ( * Scene , SceneRenderer . VisibleLightInfos , LightShadowData ) ;
2021-04-02 20:11:25 -04:00
GetSkyAtmosphereLightsUniformBuffers ( GraphBuilder , SkyRC . LightShadowShaderParams0UniformBuffer , SkyRC . LightShadowShaderParams1UniformBuffer ,
2020-12-09 11:13:00 -04:00
LightShadowData , CubeView , SkyRC . bShouldSampleOpaqueShadow , UniformBuffer_SingleDraw ) ;
}
SkyRC . bUseDepthBoundTestIfPossible = false ;
SkyRC . bForceRayMarching = true ; // We do not have any valid view LUT
SkyRC . bDepthReadDisabled = true ;
SkyRC . bDisableBlending = true ;
SkyRC . TransmittanceLut = GraphBuilder . RegisterExternalTexture ( SkyInfo . GetTransmittanceLutTexture ( ) ) ;
SkyRC . MultiScatteredLuminanceLut = GraphBuilder . RegisterExternalTexture ( SkyInfo . GetMultiScatteredLuminanceLutTexture ( ) ) ;
2020-08-11 01:36:57 -04:00
}
FCloudRenderContext CloudRC ;
2020-06-23 18:40:00 -04:00
if ( bShouldRenderVolumetricCloud )
{
FVolumetricCloudRenderSceneInfo & CloudInfo = * GetVolumetricCloudSceneInfo ( ) ;
FVolumetricCloudSceneProxy & CloudSceneProxy = CloudInfo . GetVolumetricCloudSceneProxy ( ) ;
if ( CloudSceneProxy . GetCloudVolumeMaterial ( ) )
{
FMaterialRenderProxy * CloudVolumeMaterialProxy = CloudSceneProxy . GetCloudVolumeMaterial ( ) - > GetRenderProxy ( ) ;
CloudRC . CloudInfo = & CloudInfo ;
CloudRC . CloudVolumeMaterialProxy = CloudVolumeMaterialProxy ;
2020-11-06 11:50:06 -04:00
CloudRC . SceneDepthZ = GSystemTextures . GetMaxFP16Depth ( GraphBuilder ) ;
2020-06-23 18:40:00 -04:00
2021-04-29 19:32:06 -04:00
CloudRC . MainView = & CubeView ; /// This is only accessing data that is not changing between view orientation. Such data are accessed from the ViewUniformBuffer. See CubeView comment above.
2020-06-23 18:40:00 -04:00
CloudRC . bShouldViewRenderVolumetricRenderTarget = false ;
CloudRC . bIsReflectionRendering = true ;
2020-08-11 01:36:57 -04:00
CloudRC . bIsSkyRealTimeReflectionRendering = true ;
CloudRC . bSecondAtmosphereLightEnabled = IsSecondAtmosphereLightEnabled ( ) ;
CloudRC . bSkipAtmosphericLightShadowmap = ! CaptureShadowFromOpaque ;
if ( CaptureShadowFromOpaque )
{
FLightSceneInfo * AtmosphericLight0Info = Scene - > AtmosphereLights [ 0 ] ;
FLightSceneProxy * AtmosphericLight0 = AtmosphericLight0Info ? AtmosphericLight0Info - > Proxy : nullptr ;
const FProjectedShadowInfo * ProjectedShadowInfo0 = nullptr ;
if ( AtmosphericLight0Info )
{
2021-03-08 23:14:54 -04:00
ProjectedShadowInfo0 = GetFirstWholeSceneShadowMap ( SceneRenderer . VisibleLightInfos [ AtmosphericLight0Info - > Id ] ) ;
2020-08-11 01:36:57 -04:00
}
2020-09-24 00:43:27 -04:00
// Get the main view shadow info for the cloud shadows in reflection.
2020-08-11 01:36:57 -04:00
if ( ! CloudRC . bSkipAtmosphericLightShadowmap & & AtmosphericLight0 & & ProjectedShadowInfo0 )
{
2021-04-02 20:11:25 -04:00
SetVolumeShadowingShaderParameters ( GraphBuilder , CloudRC . LightShadowShaderParams0 , MainView , AtmosphericLight0Info , ProjectedShadowInfo0 , INDEX_NONE ) ;
2020-08-11 01:36:57 -04:00
}
else
{
2021-04-02 20:11:25 -04:00
SetVolumeShadowingDefaultShaderParameters ( GraphBuilder , CloudRC . LightShadowShaderParams0 ) ;
2020-08-11 01:36:57 -04:00
}
}
else
{
2021-04-02 20:11:25 -04:00
SetVolumeShadowingDefaultShaderParameters ( GraphBuilder , CloudRC . LightShadowShaderParams0 ) ;
2020-08-11 01:36:57 -04:00
}
2020-06-23 18:40:00 -04:00
}
else
{
bShouldRenderVolumetricCloud = false ; // Disable cloud rendering
}
}
for ( int32 CubeFace = 0 ; CubeFace < CubeFace_MAX ; CubeFace + + )
{
SkyRC . RenderTargets [ 0 ] = FRenderTargetBinding ( SkyCubeTexture , ERenderTargetLoadAction : : ENoAction , 0 , CubeFace ) ;
const FMatrix CubeViewRotationMatrix = CalcCubeFaceViewRotationMatrix ( ( ECubeFace ) CubeFace ) ;
SceneCubeViewInitOptions . ViewRotationMatrix = CubeViewRotationMatrix ;
SceneCubeViewInitOptions . ViewOrigin = SkyLight - > CapturePosition ;
SceneCubeViewInitOptions . ProjectionMatrix = CubeProjectionMatrix ;
FViewMatrices CubeViewMatrices = FViewMatrices ( SceneCubeViewInitOptions ) ;
CubeView . SetupCommonViewUniformBufferParameters (
* CubeView . CachedViewUniformShaderParameters ,
FIntPoint ( CubeWidth , CubeWidth ) ,
1 ,
FIntRect ( FIntPoint ( 0 , 0 ) , FIntPoint ( CubeWidth , CubeWidth ) ) ,
CubeViewMatrices ,
CubeViewMatrices ) ;
// Notify the fact that we render a reflection, e.g. remove sun disk.
CubeView . CachedViewUniformShaderParameters - > RenderingReflectionCaptureMask = 1.0f ;
// Notify the fact that we render a reflection, e.g. use special exposure.
CubeView . CachedViewUniformShaderParameters - > RealTimeReflectionCapture = 1.0f ;
// We have rendered a sky dome with identity rotation at the SkyLight position for the capture.
2020-12-09 11:13:00 -04:00
if ( AtmosphereSetup )
2020-06-23 18:40:00 -04:00
{
2021-11-07 23:43:01 -05:00
FVector3f SkyWorldCameraOrigin ;
FMatrix44f SkyViewLutReferential ;
FVector4f TempSkyPlanetData ;
2020-12-09 11:13:00 -04:00
if ( MainView . bSceneHasSkyMaterial )
{
// Setup a constant referential for each of the faces of the dynamic reflection capture.
// This is to have the FastSkyViewLUT match the one generated specifically for the capture point of view.
2021-11-07 23:43:01 -05:00
const FVector3f SkyViewLutReferentialForward = FVector3f ( 1.0f , 0.0f , 0.0f ) ;
const FVector3f SkyViewLutReferentialRight = FVector3f ( 0.0f , 0.0f , - 1.0f ) ;
2020-12-09 11:13:00 -04:00
AtmosphereSetup - > ComputeViewData ( SkyLight - > CapturePosition , SkyViewLutReferentialForward , SkyViewLutReferentialRight ,
2021-09-22 10:01:48 -04:00
SkyWorldCameraOrigin , TempSkyPlanetData , SkyViewLutReferential ) ;
2020-12-09 11:13:00 -04:00
CubeView . CachedViewUniformShaderParameters - > SkyViewLutTexture = RealTimeReflectionCaptureSkyAtmosphereViewLutTexture - > GetRenderTargetItem ( ) . ShaderResourceTexture ;
}
else
{
// Else if there is no sky material, we assume that no material is sampling the FastSkyViewLUT texture in the sky light reflection (bFastSky=bFastAerialPerspective=false).
// But, we still need to udpate the sky parameters on the view according to the sky light capture position
2021-11-07 23:43:01 -05:00
const FVector3f SkyViewLutReferentialForward = FVector3f ( 1.0f , 0.0f , 0.0f ) ;
const FVector3f SkyViewLutReferentialRight = FVector3f ( 0.0f , 0.0f , - 1.0f ) ;
2021-09-22 10:01:48 -04:00
// LWC_TODO: SkyPlanetCenterAndViewHeight is FVector4f because it's from a shader, and will have lost precision already.
2020-12-09 11:13:00 -04:00
AtmosphereSetup - > ComputeViewData ( SkyLight - > CapturePosition , SkyViewLutReferentialForward , SkyViewLutReferentialRight ,
2021-09-22 10:01:48 -04:00
SkyWorldCameraOrigin , TempSkyPlanetData , SkyViewLutReferential ) ;
2020-12-09 11:13:00 -04:00
}
2021-05-05 15:07:25 -04:00
2021-09-22 10:01:48 -04:00
// LWC_TODO: Precision loss
CubeView . CachedViewUniformShaderParameters - > SkyPlanetCenterAndViewHeight = TempSkyPlanetData ;
2021-05-05 15:07:25 -04:00
CubeView . CachedViewUniformShaderParameters - > SkyWorldCameraOrigin = SkyWorldCameraOrigin ;
CubeView . CachedViewUniformShaderParameters - > SkyViewLutReferential = SkyViewLutReferential ;
2020-08-11 01:36:57 -04:00
}
2020-06-23 18:40:00 -04:00
2021-01-28 05:47:18 -04:00
if ( HasSkyAtmosphere ( ) & & ( MainView . bSceneHasSkyMaterial | | HasVolumetricCloud ( ) )
& & RealTimeReflectionCaptureCamera360APLutTexture . IsValid ( ) ) // we also check that because it seems it can happen for some view setup UE-107270, TODO find a repro for a proper fix.
2020-06-23 18:40:00 -04:00
{
CubeView . CachedViewUniformShaderParameters - > CameraAerialPerspectiveVolume = RealTimeReflectionCaptureCamera360APLutTexture - > GetRenderTargetItem ( ) . ShaderResourceTexture ;
}
2021-01-28 05:47:18 -04:00
else
{
CubeView . CachedViewUniformShaderParameters - > CameraAerialPerspectiveVolume = GSystemTextures . VolumetricBlackDummy - > GetRenderTargetItem ( ) . ShaderResourceTexture ;
}
2020-06-23 18:40:00 -04:00
2020-08-11 01:36:57 -04:00
TUniformBufferRef < FViewUniformShaderParameters > CubeViewUniformBuffer = TUniformBufferRef < FViewUniformShaderParameters > : : CreateUniformBufferImmediate ( * CubeView . CachedViewUniformShaderParameters , UniformBuffer_SingleFrame ) ;
2020-09-01 14:07:48 -04:00
CubeView . ViewUniformBuffer = CubeViewUniformBuffer ;
if ( CubeView . bSceneHasSkyMaterial )
{
2021-04-06 13:59:36 -04:00
GPUScene . UploadDynamicPrimitiveShaderDataForView ( GraphBuilder , this , CubeView ) ;
2020-09-01 14:07:48 -04:00
}
2020-08-11 01:36:57 -04:00
SkyRC . ViewUniformBuffer = CubeViewUniformBuffer ;
2020-06-23 18:40:00 -04:00
SkyRC . ViewMatrices = & CubeViewMatrices ;
SkyRC . SkyAtmosphereViewLutTexture = BlackDummy2dTex ;
SkyRC . SkyAtmosphereCameraAerialPerspectiveVolume = BlackDummy3dTex ;
SkyRC . Viewport = FIntRect ( FIntPoint ( 0 , 0 ) , FIntPoint ( CubeWidth , CubeWidth ) ) ;
SkyRC . bLightDiskEnabled = false ;
SkyRC . bRenderSkyPixel = true ;
SkyRC . AerialPerspectiveStartDepthInCm = 0.01f ;
SkyRC . NearClippingDistance = 0.01f ;
SkyRC . FeatureLevel = FeatureLevel ;
2020-11-24 18:42:39 -04:00
FCloudShadowAOData CloudShadowAOData ;
GetCloudShadowAOData ( GetVolumetricCloudSceneInfo ( ) , CubeView , GraphBuilder , CloudShadowAOData ) ;
SkyRC . bShouldSampleCloudShadow = CloudShadowAOData . bShouldSampleCloudShadow ;
SkyRC . VolumetricCloudShadowMap [ 0 ] = CloudShadowAOData . VolumetricCloudShadowMap [ 0 ] ;
SkyRC . VolumetricCloudShadowMap [ 1 ] = CloudShadowAOData . VolumetricCloudShadowMap [ 1 ] ;
SkyRC . bShouldSampleCloudSkyAO = CloudShadowAOData . bShouldSampleCloudSkyAO ;
SkyRC . VolumetricCloudSkyAO = CloudShadowAOData . VolumetricCloudSkyAO ;
2020-06-23 18:40:00 -04:00
2020-09-01 14:07:48 -04:00
const bool bUseDepthBuffer = CVarRealTimeReflectionCaptureDepthBuffer . GetValueOnRenderThread ( ) > 0 ;
FRDGTextureRef CubeDepthTexture = nullptr ;
2020-06-23 18:40:00 -04:00
if ( bExecuteSky )
{
2020-12-09 11:13:00 -04:00
if ( MainView . bSceneHasSkyMaterial | | bShouldRenderSkyAtmosphere )
2020-06-23 18:40:00 -04:00
{
2020-12-09 11:13:00 -04:00
// If there are any mesh tagged as IsSky then we render them only, otherwise we simply render the sky atmosphere itself.
if ( MainView . bSceneHasSkyMaterial )
2020-09-01 14:07:48 -04:00
{
2020-12-09 11:13:00 -04:00
auto * PassParameters = GraphBuilder . AllocParameters < FCaptureSkyMeshReflectionPassParameters > ( ) ;
2020-12-09 13:11:49 -04:00
PassParameters - > View = CubeView . GetShaderParameters ( ) ;
2020-12-09 11:13:00 -04:00
PassParameters - > RenderTargets = SkyRC . RenderTargets ;
PassParameters - > BasePass = CreateOpaqueBasePassUniformBuffer ( GraphBuilder , MainView , 0 ) ;
// Setup the depth buffer
if ( bUseDepthBuffer )
{
2021-01-11 14:49:16 -04:00
FRDGTextureDesc CubeDepthTextureDesc = FRDGTextureDesc : : Create2D ( FIntPoint ( CubeWidth , CubeWidth ) , PF_DepthStencil , GetSceneDepthClearValue ( ) ,
2020-12-09 11:13:00 -04:00
TexCreate_DepthStencilTargetable | TexCreate_ShaderResource ) ;
2021-02-02 05:19:56 -04:00
CubeDepthTexture = GraphBuilder . CreateTexture ( CubeDepthTextureDesc , TEXT ( " SkyLight.CubeDepthTexture " ) ) ;
2020-12-09 11:13:00 -04:00
PassParameters - > RenderTargets . DepthStencil = FDepthStencilBinding ( CubeDepthTexture , ERenderTargetLoadAction : : EClear , FExclusiveDepthStencil : : DepthWrite_StencilNop ) ;
}
2021-08-03 10:31:27 -04:00
AddSimpleMeshPass ( GraphBuilder , PassParameters , Scene , MainView , & InstanceCullingManager , RDG_EVENT_NAME ( " CaptureSkyMeshReflection " ) , SkyRC . Viewport ,
2021-05-31 10:59:43 -04:00
[ & MainView , & CubeViewUniformBuffer , bUseDepthBuffer , Scene ] ( FDynamicPassMeshDrawListContext * DynamicMeshPassContext )
{
FMeshPassProcessorRenderState DrawRenderState ;
FExclusiveDepthStencil : : Type BasePassDepthStencilAccess_Sky = bUseDepthBuffer ? FExclusiveDepthStencil : : Type ( Scene - > DefaultBasePassDepthStencilAccess | FExclusiveDepthStencil : : DepthWrite )
: FExclusiveDepthStencil : : Type ( Scene - > DefaultBasePassDepthStencilAccess & ~ FExclusiveDepthStencil : : DepthWrite ) ;
SetupBasePassState ( BasePassDepthStencilAccess_Sky , false , DrawRenderState ) ;
FSkyPassMeshProcessor PassMeshProcessor ( Scene , nullptr , DrawRenderState , DynamicMeshPassContext ) ;
const int32 SkyRealTimeReflectionOnlyMeshBatcheCount = MainView . SkyMeshBatches . Num ( ) ;
for ( int32 MeshBatchIndex = 0 ; MeshBatchIndex < SkyRealTimeReflectionOnlyMeshBatcheCount ; + + MeshBatchIndex )
2020-12-09 11:13:00 -04:00
{
2021-05-31 10:59:43 -04:00
FSkyMeshBatch & SkyMeshBatch = MainView . SkyMeshBatches [ MeshBatchIndex ] ;
if ( ! SkyMeshBatch . bVisibleInRealTimeSkyCapture )
{
continue ;
}
2020-12-09 11:13:00 -04:00
2021-05-31 10:59:43 -04:00
const FMeshBatch * MeshBatch = SkyMeshBatch . Mesh ;
const FPrimitiveSceneProxy * PrimitiveSceneProxy = SkyMeshBatch . Proxy ;
const FPrimitiveSceneInfo * PrimitiveSceneInfo = PrimitiveSceneProxy - > GetPrimitiveSceneInfo ( ) ;
2020-12-09 11:13:00 -04:00
2021-05-31 10:59:43 -04:00
const uint64 DefaultBatchElementMask = ~ 0ull ;
PassMeshProcessor . AddMeshBatch ( * MeshBatch , DefaultBatchElementMask , PrimitiveSceneProxy ) ;
}
} ) ;
2020-12-09 11:13:00 -04:00
}
else
{
FSceneTextureShaderParameters SceneTextures = CreateSceneTextureShaderParameters ( GraphBuilder , SceneRenderer . FeatureLevel , ESceneTextureSetupMode : : SceneDepth ) ;
SceneRenderer . RenderSkyAtmosphereInternal ( GraphBuilder , SceneTextures , SkyRC ) ;
2020-09-01 14:07:48 -04:00
}
2020-12-09 11:13:00 -04:00
// Also render the height fog as part of the sky render pass when time slicing is enabled.
if ( Scene & & Scene - > ExponentialFogs . Num ( ) > 0 )
{
FRenderRealTimeReflectionHeightFogVS : : FPermutationDomain VsPermutationVector ;
TShaderMapRef < FRenderRealTimeReflectionHeightFogVS > VertexShader ( GetGlobalShaderMap ( SkyRC . FeatureLevel ) , VsPermutationVector ) ;
2020-06-23 18:40:00 -04:00
2020-12-09 11:13:00 -04:00
FRenderRealTimeReflectionHeightFogPS : : FPermutationDomain PsPermutationVector ;
PsPermutationVector . Set < FRenderRealTimeReflectionHeightFogPS : : FDepthTexture > ( CubeDepthTexture ! = nullptr ) ;
TShaderMapRef < FRenderRealTimeReflectionHeightFogPS > PixelShader ( GetGlobalShaderMap ( SkyRC . FeatureLevel ) , PsPermutationVector ) ;
2020-06-23 18:40:00 -04:00
2020-12-09 11:13:00 -04:00
FRenderRealTimeReflectionHeightFogPS : : FParameters * PsPassParameters = GraphBuilder . AllocParameters < FRenderRealTimeReflectionHeightFogPS : : FParameters > ( ) ;
PsPassParameters - > ViewUniformBuffer = CubeViewUniformBuffer ;
PsPassParameters - > RenderTargets = SkyRC . RenderTargets ;
PsPassParameters - > DepthTexture = CubeDepthTexture ! = nullptr ? CubeDepthTexture : BlackDummy2dTex ;
PsPassParameters - > FogStruct = CreateFogUniformBuffer ( GraphBuilder , CubeView ) ;
2020-06-23 18:40:00 -04:00
2020-12-09 11:13:00 -04:00
ClearUnusedGraphResources ( PixelShader , PsPassParameters ) ;
2020-09-01 14:07:48 -04:00
2020-12-09 11:13:00 -04:00
// Render height fog at an infinite distance since real time reflections does not have a depth buffer for now.
// Volumetric fog is not supported in such reflections.
GraphBuilder . AddPass (
RDG_EVENT_NAME ( " DistantHeightFog " ) ,
PsPassParameters ,
ERDGPassFlags : : Raster ,
[ PsPassParameters , VertexShader , PixelShader , CubeWidth ] ( FRHICommandList & RHICmdListLambda )
{
RHICmdListLambda . SetViewport ( 0.0f , 0.0f , 0.0f , CubeWidth , CubeWidth , 1.0f ) ;
2020-06-23 18:40:00 -04:00
2020-12-09 11:13:00 -04:00
FGraphicsPipelineStateInitializer GraphicsPSOInit ;
RHICmdListLambda . ApplyCachedRenderTargets ( GraphicsPSOInit ) ;
GraphicsPSOInit . BlendState = TStaticBlendState < CW_RGB , BO_Add , BF_One , BF_SourceAlpha , BO_Add , BF_Zero , BF_One > : : GetRHI ( ) ;
GraphicsPSOInit . DepthStencilState = TStaticDepthStencilState < false , CF_Always > : : GetRHI ( ) ;
GraphicsPSOInit . RasterizerState = TStaticRasterizerState < FM_Solid , CM_None > : : GetRHI ( ) ;
GraphicsPSOInit . BoundShaderState . VertexDeclarationRHI = GEmptyVertexDeclaration . VertexDeclarationRHI ;
GraphicsPSOInit . BoundShaderState . VertexShaderRHI = VertexShader . GetVertexShader ( ) ;
GraphicsPSOInit . BoundShaderState . PixelShaderRHI = PixelShader . GetPixelShader ( ) ;
GraphicsPSOInit . PrimitiveType = PT_TriangleList ;
2021-09-03 12:04:52 -04:00
SetGraphicsPipelineState ( RHICmdListLambda , GraphicsPSOInit , 0 ) ;
2020-12-09 11:13:00 -04:00
FRenderRealTimeReflectionHeightFogVS : : FParameters VsPassParameters ;
VsPassParameters . ViewUniformBuffer = PsPassParameters - > ViewUniformBuffer ;
SetShaderParameters ( RHICmdListLambda , VertexShader , VertexShader . GetVertexShader ( ) , VsPassParameters ) ;
SetShaderParameters ( RHICmdListLambda , PixelShader , PixelShader . GetPixelShader ( ) , * PsPassParameters ) ;
RHICmdListLambda . DrawPrimitive ( 0 , 1 , 1 ) ;
} ) ;
}
2020-06-23 18:40:00 -04:00
}
else
{
2020-12-09 11:13:00 -04:00
ClearCubeFace ( SkyCubeTexture , CubeFace ) ;
2020-09-01 14:07:48 -04:00
}
2020-08-11 01:36:57 -04:00
}
if ( bShouldRenderVolumetricCloud & & bExecuteCloud )
{
CloudRC . ViewUniformBuffer = CubeViewUniformBuffer ;
2020-06-23 18:40:00 -04:00
CloudRC . RenderTargets [ 0 ] = SkyRC . RenderTargets [ 0 ] ;
// CloudRC.RenderTargets[1] = Null target will skip export
2020-08-11 01:36:57 -04:00
CloudRC . VolumetricCloudShadowTexture [ 0 ] = CloudShadowAOData . VolumetricCloudShadowMap [ 0 ] ;
CloudRC . VolumetricCloudShadowTexture [ 1 ] = CloudShadowAOData . VolumetricCloudShadowMap [ 1 ] ;
2020-06-23 18:40:00 -04:00
2021-01-14 05:23:34 -04:00
SceneRenderer . RenderVolumetricCloudsInternal ( GraphBuilder , CloudRC , InstanceCullingManager ) ;
2020-06-23 18:40:00 -04:00
}
2020-08-11 01:36:57 -04:00
}
2020-06-23 18:40:00 -04:00
2020-08-11 01:36:57 -04:00
// Render lower hemisphere color
if ( SkyLight - > bLowerHemisphereIsSolidColor )
{
FApplyLowerHemisphereColor : : FPermutationDomain PermutationVector ;
TShaderMapRef < FApplyLowerHemisphereColor > ComputeShader ( GetGlobalShaderMap ( FeatureLevel ) , PermutationVector ) ;
const uint32 MipIndex = 0 ;
const uint32 Mip0Resolution = SkyCubeTexture - > Desc . GetSize ( ) . X ;
FApplyLowerHemisphereColor : : FParameters * PassParameters = GraphBuilder . AllocParameters < FApplyLowerHemisphereColor : : FParameters > ( ) ;
PassParameters - > ValidDispatchCoord = FIntPoint ( Mip0Resolution , Mip0Resolution ) ;
PassParameters - > LowerHemisphereSolidColor = SkyLight - > LowerHemisphereColor ;
PassParameters - > OutTextureMipColor = GraphBuilder . CreateUAV ( FRDGTextureUAVDesc ( SkyCubeTexture , MipIndex ) ) ;
FIntVector NumGroups = FIntVector : : DivideAndRoundUp ( FIntVector ( Mip0Resolution , Mip0Resolution , 1 ) , FIntVector ( FApplyLowerHemisphereColor : : ThreadGroupSize , FApplyLowerHemisphereColor : : ThreadGroupSize , 1 ) ) ;
// The groupd size per face with padding
PassParameters - > FaceThreadGroupSize = NumGroups . X * FConvolveSpecularFaceCS : : ThreadGroupSize ;
// We are going to dispatch once for all faces
NumGroups . X * = 6 ;
FComputeShaderUtils : : AddPass ( GraphBuilder , RDG_EVENT_NAME ( " ApplyLowerHemisphereColor " ) , ComputeShader , PassParameters , NumGroups ) ;
2020-06-23 18:40:00 -04:00
}
}
else
{
for ( int32 CubeFace = 0 ; CubeFace < CubeFace_MAX ; CubeFace + + )
{
2020-12-09 11:13:00 -04:00
ClearCubeFace ( SkyCubeTexture , CubeFace ) ;
2020-06-23 18:40:00 -04:00
}
}
} ;
2020-09-01 14:07:48 -04:00
auto RenderCubeFaces_GenCubeMips = [ & ] ( uint32 CubeMipStart , uint32 CubeMipEnd , TRefCountPtr < IPooledRenderTarget > & SkyRenderTarget )
2020-06-23 18:40:00 -04:00
{
check ( CubeMipStart > 0 ) ; // Never write to mip0 as it has just been redered into
FRDGTextureRef SkyCubeTexture = GraphBuilder . RegisterExternalTexture ( SkyRenderTarget , TEXT ( " SkyRenderTarget " ) ) ;
FDownsampleCubeFaceCS : : FPermutationDomain PermutationVector ;
TShaderMapRef < FDownsampleCubeFaceCS > ComputeShader ( GetGlobalShaderMap ( FeatureLevel ) , PermutationVector ) ;
for ( uint32 MipIndex = CubeMipStart ; MipIndex < = CubeMipEnd ; MipIndex + + )
{
const uint32 MipResolution = 1 < < ( CubeMipCount - MipIndex - 1 ) ;
FRDGTextureSRVRef SkyCubeTextureSRV = GraphBuilder . CreateSRV ( FRDGTextureSRVDesc : : CreateForMipLevel ( SkyCubeTexture , MipIndex - 1 ) ) ; // slice/face selection is useless so remove from CreateForMipLevel
FDownsampleCubeFaceCS : : FParameters * PassParameters = GraphBuilder . AllocParameters < FDownsampleCubeFaceCS : : FParameters > ( ) ;
PassParameters - > MipIndex = MipIndex ;
PassParameters - > NumMips = CubeMipCount ;
PassParameters - > CubeFace = 0 ; // unused
PassParameters - > ValidDispatchCoord = FIntPoint ( MipResolution , MipResolution ) ;
PassParameters - > SourceCubemapSampler = TStaticSamplerState < SF_Point > : : GetRHI ( ) ;
PassParameters - > SourceCubemapTexture = SkyCubeTextureSRV ;
PassParameters - > OutTextureMipColor = GraphBuilder . CreateUAV ( FRDGTextureUAVDesc ( SkyCubeTexture , MipIndex ) ) ;
FIntVector NumGroups = FIntVector : : DivideAndRoundUp ( FIntVector ( MipResolution , MipResolution , 1 ) , FIntVector ( FDownsampleCubeFaceCS : : ThreadGroupSize , FDownsampleCubeFaceCS : : ThreadGroupSize , 1 ) ) ;
// The groupd size per face with padding
PassParameters - > FaceThreadGroupSize = NumGroups . X * FDownsampleCubeFaceCS : : ThreadGroupSize ;
// We are going to dispatch once for all faces
NumGroups . X * = 6 ;
// Dispatch with GenerateMips: reading from a slice through SRV and writing into lower mip through UAV.
ClearUnusedGraphResources ( ComputeShader , PassParameters ) ;
GraphBuilder . AddPass (
Forward < FRDGEventName > ( RDG_EVENT_NAME ( " MipGen " ) ) ,
PassParameters ,
2020-07-06 18:58:26 -04:00
ERDGPassFlags : : Compute ,
2020-06-23 18:40:00 -04:00
[ PassParameters , ComputeShader , NumGroups ] ( FRHICommandList & RHICmdList )
{
FComputeShaderUtils : : Dispatch ( RHICmdList , ComputeShader , * PassParameters , NumGroups ) ;
} ) ;
}
} ;
2020-09-01 14:07:48 -04:00
auto RenderCubeFaces_SpecularConvolution = [ & ] ( uint32 CubeMipStart , uint32 CubeMipEnd , uint32 FaceStart , uint32 FaceCount , TRefCountPtr < IPooledRenderTarget > & DstRenderTarget , TRefCountPtr < IPooledRenderTarget > & SrcRenderTarget )
2020-06-23 18:40:00 -04:00
{
2020-09-01 14:07:48 -04:00
check ( ( FaceStart + FaceCount ) < = 6 ) ;
2021-01-21 12:46:39 -04:00
FRDGTextureRef RDGSrcRenderTarget = GraphBuilder . RegisterExternalTexture ( SrcRenderTarget ) ;
FRDGTextureRef RDGDstRenderTarget = GraphBuilder . RegisterExternalTexture ( DstRenderTarget ) ;
2020-06-23 18:40:00 -04:00
FRDGTextureSRVRef RDGSrcRenderTargetSRV = GraphBuilder . CreateSRV ( FRDGTextureSRVDesc : : Create ( RDGSrcRenderTarget ) ) ;
FDownsampleCubeFaceCS : : FPermutationDomain PermutationVector ;
TShaderMapRef < FConvolveSpecularFaceCS > ComputeShader ( GetGlobalShaderMap ( FeatureLevel ) , PermutationVector ) ;
for ( uint32 MipIndex = CubeMipStart ; MipIndex < = CubeMipEnd ; MipIndex + + )
{
const uint32 MipResolution = 1 < < ( CubeMipCount - MipIndex - 1 ) ;
FConvolveSpecularFaceCS : : FParameters * PassParameters = GraphBuilder . AllocParameters < FConvolveSpecularFaceCS : : FParameters > ( ) ;
PassParameters - > MipIndex = MipIndex ;
PassParameters - > NumMips = CubeMipCount ;
PassParameters - > CubeFace = 0 ; // unused
2020-09-01 14:07:48 -04:00
PassParameters - > CubeFaceOffset = int ( FaceStart ) ;
2020-06-23 18:40:00 -04:00
PassParameters - > ValidDispatchCoord = FIntPoint ( MipResolution , MipResolution ) ;
PassParameters - > SourceCubemapSampler = TStaticSamplerState < SF_Point > : : GetRHI ( ) ;
PassParameters - > SourceCubemapTexture = RDGSrcRenderTargetSRV ;
PassParameters - > OutTextureMipColor = GraphBuilder . CreateUAV ( FRDGTextureUAVDesc ( RDGDstRenderTarget , MipIndex ) ) ;
FIntVector NumGroups = FIntVector : : DivideAndRoundUp ( FIntVector ( MipResolution , MipResolution , 1 ) , FIntVector ( FConvolveSpecularFaceCS : : ThreadGroupSize , FConvolveSpecularFaceCS : : ThreadGroupSize , 1 ) ) ;
// The groupd size per face with padding
PassParameters - > FaceThreadGroupSize = NumGroups . X * FConvolveSpecularFaceCS : : ThreadGroupSize ;
// We are going to dispatch once for all faces
2020-09-01 14:07:48 -04:00
NumGroups . X * = FaceCount ;
2020-06-23 18:40:00 -04:00
FComputeShaderUtils : : AddPass ( GraphBuilder , RDG_EVENT_NAME ( " Convolve " ) , ComputeShader , PassParameters , NumGroups ) ;
}
} ;
2020-09-01 14:07:48 -04:00
auto RenderCubeFaces_DiffuseIrradiance = [ & ] ( TRefCountPtr < IPooledRenderTarget > & SourceCubemap )
2020-06-23 18:40:00 -04:00
{
// ComputeDiffuseIrradiance using N uniform samples
2021-07-22 11:00:18 -04:00
AddPass ( GraphBuilder , RDG_EVENT_NAME ( " TransitionToUAV " ) , [ SkyIrradianceEnvironmentMap = SkyIrradianceEnvironmentMap . Buffer ] ( FRHIComputeCommandList & RHICmdList )
2020-06-23 18:40:00 -04:00
{
2021-01-21 12:46:39 -04:00
RHICmdList . Transition ( { SkyIrradianceEnvironmentMap , ERHIAccess : : Unknown , ERHIAccess : : UAVCompute } ) ;
} ) ;
2020-06-23 18:40:00 -04:00
2021-01-21 12:46:39 -04:00
FRDGTextureRef SourceCubemapTexture = GraphBuilder . RegisterExternalTexture ( SourceCubemap ) ;
FRDGTextureSRVRef SourceCubemapTextureSRV = GraphBuilder . CreateSRV ( FRDGTextureSRVDesc : : Create ( SourceCubemapTexture ) ) ;
2020-06-23 18:40:00 -04:00
2021-01-21 12:46:39 -04:00
TShaderMapRef < FComputeSkyEnvMapDiffuseIrradianceCS > ComputeShader ( GetGlobalShaderMap ( FeatureLevel ) ) ;
2020-06-23 18:40:00 -04:00
2021-01-21 12:46:39 -04:00
const float SampleCount = FComputeSkyEnvMapDiffuseIrradianceCS : : ThreadGroupSizeX * FComputeSkyEnvMapDiffuseIrradianceCS : : ThreadGroupSizeY ;
const float UniformSampleSolidAngle = 4.0f * PI / SampleCount ; // uniform distribution
2020-06-23 18:40:00 -04:00
2021-01-21 12:46:39 -04:00
FComputeSkyEnvMapDiffuseIrradianceCS : : FParameters * PassParameters = GraphBuilder . AllocParameters < FComputeSkyEnvMapDiffuseIrradianceCS : : FParameters > ( ) ;
PassParameters - > SourceCubemapSampler = TStaticSamplerState < SF_Point > : : GetRHI ( ) ;
PassParameters - > SourceCubemapTexture = SourceCubemapTextureSRV ;
PassParameters - > OutIrradianceEnvMapSH = SkyIrradianceEnvironmentMap . UAV ;
PassParameters - > UniformSampleSolidAngle = UniformSampleSolidAngle ;
2020-06-23 18:40:00 -04:00
2021-01-21 12:46:39 -04:00
// For 64 uniform samples on the unit sphere, we roughly have 10 samples per face.
// Considering mip generation and bilinear sampling, we can assume 10 samples is enough to integrate 10*4=40 texels.
// With that, we target integration of 16*16 face.
const uint32 Log2_16 = 4 ; // FMath::Log2(16.0f)
PassParameters - > MipIndex = uint32 ( FMath : : Log2 ( float ( CapturedSkyRenderTarget - > GetDesc ( ) . GetSize ( ) . X ) ) ) - Log2_16 ;
const FIntVector NumGroups = FIntVector ( 1 , 1 , 1 ) ;
FComputeShaderUtils : : AddPass ( GraphBuilder , RDG_EVENT_NAME ( " ComputeSkyEnvMapDiffuseIrradianceCS " ) , ComputeShader , PassParameters , NumGroups ) ;
2021-07-22 11:00:18 -04:00
AddPass ( GraphBuilder , RDG_EVENT_NAME ( " TransitionToSRV " ) , [ SkyIrradianceEnvironmentMap = SkyIrradianceEnvironmentMap . Buffer ] ( FRHICommandList & RHICmdList )
2021-01-21 12:46:39 -04:00
{
RHICmdList . Transition ( { SkyIrradianceEnvironmentMap , ERHIAccess : : UAVCompute , ERHIAccess : : SRVMask } ) ;
} ) ;
2020-06-23 18:40:00 -04:00
} ;
const uint32 LastMipLevel = CubeMipCount - 1 ;
2021-04-29 19:32:06 -04:00
// Ensure the main view got the full cubemap by running all the capture operations for the first frame.
2021-01-21 16:22:06 -04:00
// This ensures a proper initial state when time-slicing the steps.
// Update the firt frame detection state variable
if ( bTimeSlicedRealTimeCapture )
{
2021-09-06 12:23:53 -04:00
// Go to next state iff this is a new frame
if ( bIsNewFrame )
{
2021-04-29 19:32:06 -04:00
switch ( RealTimeSlicedReflectionCaptureFirstFrameState )
2021-01-21 16:22:06 -04:00
{
2021-04-29 19:32:06 -04:00
case ERealTimeSlicedReflectionCaptureFirstFrameState : : INIT :
RealTimeSlicedReflectionCaptureFirstFrameState = ERealTimeSlicedReflectionCaptureFirstFrameState : : FIRST_FRAME ;
break ;
2021-01-21 16:22:06 -04:00
2021-04-29 19:32:06 -04:00
case ERealTimeSlicedReflectionCaptureFirstFrameState : : FIRST_FRAME :
RealTimeSlicedReflectionCaptureFirstFrameState = ERealTimeSlicedReflectionCaptureFirstFrameState : : BEYOND_FIRST_FRAME ;
break ;
2021-01-21 16:22:06 -04:00
2021-04-29 19:32:06 -04:00
default :
break ;
2021-01-21 16:22:06 -04:00
}
}
2021-09-06 12:23:53 -04:00
}
2021-01-21 16:22:06 -04:00
else
{
// Reset the time-slicing first frame detection state when not time-slicing.
RealTimeSlicedReflectionCaptureFirstFrameState = ERealTimeSlicedReflectionCaptureFirstFrameState : : INIT ;
}
if ( ! bTimeSlicedRealTimeCapture
| | ( RealTimeSlicedReflectionCaptureFirstFrameState < ERealTimeSlicedReflectionCaptureFirstFrameState : : BEYOND_FIRST_FRAME ) )
2020-06-23 18:40:00 -04:00
{
2020-08-11 01:36:57 -04:00
// Generate a full cube map in a single frame for the first frame.
// Perf number are for a 128x128x6 a cubemap on PS4 with sky and cloud and default settings
2020-06-23 18:40:00 -04:00
2020-09-01 14:07:48 -04:00
// Since it is entirely generated each frame when time slicing is not enabled, we always use cubemap index 0 always allocated above
ConvolvedSkyRenderTargetReadyIndex = 0 ;
2020-06-23 18:40:00 -04:00
// 0.60ms (0.12ms for faces with the most clouds)
RenderCubeFaces_SkyCloud ( true , true , CapturedSkyRenderTarget ) ;
// 0.05ms
RenderCubeFaces_GenCubeMips ( 1 , LastMipLevel , CapturedSkyRenderTarget ) ;
// 0.80ms total (0.30ms for mip0, 0.20ms for mip1+2, 0.30ms for remaining mips)
2020-09-01 14:07:48 -04:00
RenderCubeFaces_SpecularConvolution ( 0 , LastMipLevel , 0 , 6 , ConvolvedSkyRenderTarget [ ConvolvedSkyRenderTargetReadyIndex ] , CapturedSkyRenderTarget ) ;
2020-06-23 18:40:00 -04:00
// 0.015ms
2020-09-01 14:07:48 -04:00
RenderCubeFaces_DiffuseIrradiance ( ConvolvedSkyRenderTarget [ ConvolvedSkyRenderTargetReadyIndex ] ) ;
2020-06-23 18:40:00 -04:00
2021-01-21 16:22:06 -04:00
// Reset Scene time slicing state so that it starts from the beginning if/when we get out of non-time-sliced.
RealTimeSlicedReflectionCaptureState = - 1 ; // Value of -1 indicates this is the first time-sliced iteration.
2021-03-01 18:28:37 -04:00
// The sky just changed, so invalidate these textures, so that the path tracer can rebuild them
PathTracingSkylightTexture . SafeRelease ( ) ;
PathTracingSkylightPdf . SafeRelease ( ) ;
2020-06-23 18:40:00 -04:00
}
else
{
// Each frame we capture the sky and work in ProcessedSkyRenderTarget to generate the specular convolution.
// Once done, we copy the result into ConvolvedSkyRenderTarget and generate the sky irradiance SH from there.
2021-01-21 16:22:06 -04:00
// On the first frame, we always fully initialise the convolution so ConvolvedSkyRenderTargetReadyIndex should already be valid.
2020-09-01 14:07:48 -04:00
check ( ConvolvedSkyRenderTargetReadyIndex > = 0 & & ConvolvedSkyRenderTargetReadyIndex < = 1 ) ;
const int32 ConvolvedSkyRenderTargetWorkIndex = 1 - ConvolvedSkyRenderTargetReadyIndex ;
const int32 TimeSliceCount = 12 ;
2021-09-06 12:23:53 -04:00
// Update the current time-slicing state if this is a new frame
// Note: RealTimeSlicedReflectionCaptureState will initially be -1.
if ( bIsNewFrame )
2021-01-21 16:22:06 -04:00
{
2021-09-06 12:23:53 -04:00
if ( + + RealTimeSlicedReflectionCaptureState > = TimeSliceCount )
2021-01-21 16:22:06 -04:00
{
RealTimeSlicedReflectionCaptureState = 0 ;
}
}
2020-09-01 14:07:48 -04:00
# define DEBUG_TIME_SLICE 0
# if DEBUG_TIME_SLICE
RealTimeSlicedReflectionCaptureState = 0 ;
for ( int i = 0 ; i < TimeSliceCount ; + + i )
{
# endif
2021-09-06 12:23:53 -04:00
if ( RealTimeSlicedReflectionCaptureState < = 0 )
2020-06-23 18:40:00 -04:00
{
2020-09-24 00:43:27 -04:00
RDG_EVENT_SCOPE ( GraphBuilder , " RenderSky " ) ;
2020-06-23 18:40:00 -04:00
RenderCubeFaces_SkyCloud ( true , false , CapturedSkyRenderTarget ) ;
}
else if ( RealTimeSlicedReflectionCaptureState = = 1 )
{
2020-09-24 00:43:27 -04:00
RDG_EVENT_SCOPE ( GraphBuilder , " RenderCloud " ) ;
2020-06-23 18:40:00 -04:00
RenderCubeFaces_SkyCloud ( false , true , CapturedSkyRenderTarget ) ;
}
else if ( RealTimeSlicedReflectionCaptureState = = 2 )
{
2020-09-24 00:43:27 -04:00
RDG_EVENT_SCOPE ( GraphBuilder , " GenCubeMips " ) ;
2020-06-23 18:40:00 -04:00
RenderCubeFaces_GenCubeMips ( 1 , LastMipLevel , CapturedSkyRenderTarget ) ;
}
else if ( RealTimeSlicedReflectionCaptureState = = 3 )
{
2020-09-24 00:43:27 -04:00
RDG_EVENT_SCOPE ( GraphBuilder , " ConvolutionMip0Face01 " ) ;
2020-09-01 14:07:48 -04:00
RenderCubeFaces_SpecularConvolution ( 0 , 0 , 0 , 2 , ConvolvedSkyRenderTarget [ ConvolvedSkyRenderTargetWorkIndex ] , CapturedSkyRenderTarget ) ; // convolution of mip0, face 0, 1
2020-06-23 18:40:00 -04:00
}
else if ( RealTimeSlicedReflectionCaptureState = = 4 )
{
2020-09-24 00:43:27 -04:00
RDG_EVENT_SCOPE ( GraphBuilder , " ConvolutionMip0Face23 " ) ;
2020-09-01 14:07:48 -04:00
RenderCubeFaces_SpecularConvolution ( 0 , 0 , 2 , 2 , ConvolvedSkyRenderTarget [ ConvolvedSkyRenderTargetWorkIndex ] , CapturedSkyRenderTarget ) ; // convolution of mip0, face 2, 3
2020-06-23 18:40:00 -04:00
}
else if ( RealTimeSlicedReflectionCaptureState = = 5 )
{
2020-09-24 00:43:27 -04:00
RDG_EVENT_SCOPE ( GraphBuilder , " ConvolutionMip0Face45 " ) ;
2020-09-01 14:07:48 -04:00
RenderCubeFaces_SpecularConvolution ( 0 , 0 , 4 , 2 , ConvolvedSkyRenderTarget [ ConvolvedSkyRenderTargetWorkIndex ] , CapturedSkyRenderTarget ) ; // convolution of mip0, face 4, 5
2020-06-23 18:40:00 -04:00
}
else if ( RealTimeSlicedReflectionCaptureState = = 6 )
{
2020-09-01 14:07:48 -04:00
if ( LastMipLevel > = 1 )
{
2020-09-24 00:43:27 -04:00
RDG_EVENT_SCOPE ( GraphBuilder , " ConvolutionMip1 " ) ;
2020-09-01 14:07:48 -04:00
RenderCubeFaces_SpecularConvolution ( 1 , 1 , 0 , 6 , ConvolvedSkyRenderTarget [ ConvolvedSkyRenderTargetWorkIndex ] , CapturedSkyRenderTarget ) ;
}
}
else if ( RealTimeSlicedReflectionCaptureState = = 7 )
{
if ( LastMipLevel > = 2 )
{
2020-09-24 00:43:27 -04:00
RDG_EVENT_SCOPE ( GraphBuilder , " ConvolutionMip2 " ) ;
2020-09-01 14:07:48 -04:00
RenderCubeFaces_SpecularConvolution ( 2 , 2 , 0 , 6 , ConvolvedSkyRenderTarget [ ConvolvedSkyRenderTargetWorkIndex ] , CapturedSkyRenderTarget ) ;
}
}
else if ( RealTimeSlicedReflectionCaptureState = = 8 )
{
if ( LastMipLevel > = 3 )
{
2020-09-24 00:43:27 -04:00
RDG_EVENT_SCOPE ( GraphBuilder , " ConvolutionMip3 " ) ;
2020-09-01 14:07:48 -04:00
RenderCubeFaces_SpecularConvolution ( 3 , 3 , 0 , 6 , ConvolvedSkyRenderTarget [ ConvolvedSkyRenderTargetWorkIndex ] , CapturedSkyRenderTarget ) ;
}
}
else if ( RealTimeSlicedReflectionCaptureState = = 9 )
{
if ( LastMipLevel > = 5 )
{
2020-09-24 00:43:27 -04:00
RDG_EVENT_SCOPE ( GraphBuilder , " ConvolutionMip45 " ) ;
2020-09-01 14:07:48 -04:00
RenderCubeFaces_SpecularConvolution ( 4 , 5 , 0 , 6 , ConvolvedSkyRenderTarget [ ConvolvedSkyRenderTargetWorkIndex ] , CapturedSkyRenderTarget ) ;
}
else if ( LastMipLevel > = 4 )
{
2020-09-24 00:43:27 -04:00
RDG_EVENT_SCOPE ( GraphBuilder , " ConvolutionMip4 " ) ;
2020-09-01 14:07:48 -04:00
RenderCubeFaces_SpecularConvolution ( 4 , 4 , 0 , 6 , ConvolvedSkyRenderTarget [ ConvolvedSkyRenderTargetWorkIndex ] , CapturedSkyRenderTarget ) ;
}
}
else if ( RealTimeSlicedReflectionCaptureState = = 10 )
{
if ( LastMipLevel > = 6 )
{
2020-09-24 00:43:27 -04:00
RDG_EVENT_SCOPE ( GraphBuilder , " ConvolutionMip6Etc " ) ;
2020-09-01 14:07:48 -04:00
RenderCubeFaces_SpecularConvolution ( 6 , LastMipLevel , 0 , 6 , ConvolvedSkyRenderTarget [ ConvolvedSkyRenderTargetWorkIndex ] , CapturedSkyRenderTarget ) ;
}
}
else if ( RealTimeSlicedReflectionCaptureState = = 11 )
{
2020-09-24 00:43:27 -04:00
RDG_EVENT_SCOPE ( GraphBuilder , " DiffuseIrradiance " ) ;
2020-06-23 18:40:00 -04:00
// Update the sky irradiance SH buffer.
2020-09-01 14:07:48 -04:00
RenderCubeFaces_DiffuseIrradiance ( ConvolvedSkyRenderTarget [ ConvolvedSkyRenderTargetWorkIndex ] ) ;
// Now use the new cubemap
ConvolvedSkyRenderTargetReadyIndex = ConvolvedSkyRenderTargetWorkIndex ;
2021-03-01 18:28:37 -04:00
// The sky just changed, so invalidate these textures, so that the path tracer can rebuild them
PathTracingSkylightTexture . SafeRelease ( ) ;
PathTracingSkylightPdf . SafeRelease ( ) ;
2020-06-23 18:40:00 -04:00
}
2020-09-01 14:07:48 -04:00
# if DEBUG_TIME_SLICE
}
# endif
2020-06-23 18:40:00 -04:00
}
2021-01-21 12:46:39 -04:00
if ( ConvolvedSkyRenderTarget [ ConvolvedSkyRenderTargetReadyIndex ] )
{
2021-04-06 11:45:09 -04:00
GraphBuilder . FinalizeTextureAccess ( GraphBuilder . RegisterExternalTexture ( ConvolvedSkyRenderTarget [ ConvolvedSkyRenderTargetReadyIndex ] ) , ERHIAccess : : SRVMask ) ;
2021-01-21 12:46:39 -04:00
}
2020-06-23 18:40:00 -04:00
}