Files
UnrealEngineUWP/Engine/Source/Runtime/Renderer/Private/MobileBasePassRendering.cpp
jason hoerner af48ea5a98 UE5_MAIN: Multi-view-family scene renderer refactor, part 2. Move FSceneTextures singleton out of RDG blackboard and FSceneTexturesConfig global variable singleton, into FViewFamilyInfo. This is necessary to allow multiple view families to render in a single render graph and a single scene renderer call.
* Existing calls to CreateSceneTextureShaderParameters and similar functions use "GetSceneTexturesChecked", which allows for the possibility that they are reached in a code path where scene textures haven't been initialized, and nullptr is returned instead of asserting.  The shader parameter setup functions then fill in dummy defaults for that case.  The goal was to precisely match the original behavior, which queried the RDG blackboard, and gracefully handled null if scene textures weren't there.  This definitely appears to occur in FNiagaraGpuComputeDispatch::ProcessPendingTicksFlush, which can be called with a dummy scene with no scene textures.  In the future, I may change this so dummy defaults are filled in for FSceneTextures at construction time, so the structure is never in an uninitialized state, but I would like to set up a test case for the Niagara code path before doing that, and the checks aren't harmful in the meantime.
* I marked as deprecated global functions which query values from FSceneTexturesConfig, but they'll still work with the caveat that if you use multi-view-family rendering, the results will be indeterminate (whatever view family rendered last).  There was only one case outside the scene renderer that accessed the globals (depth clear value), which I removed, noting that there is nowhere in the code where we modify the depth clear value from its global default.  I would like to permanently deprecate or remove these at some point.  Display Cluster is the only code that's currently using the multi-view-family code path, and as a new (still incomplete) feature, third party code can't be using it, and won't be affected.

#jira NONE
#rb chris.kulla zach.bethel mihnea.balta
#preflight 6261aca76119a1a496bd2644

[CL 19873983 by jason hoerner in ue5-main branch]
2022-04-22 17:33:02 -04:00

377 lines
22 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
/*=============================================================================
MobileBasePassRendering.cpp: Base pass rendering implementation.
=============================================================================*/
#include "MobileBasePassRendering.h"
#include "DynamicPrimitiveDrawing.h"
#include "ScenePrivate.h"
#include "SceneTextureParameters.h"
#include "ShaderPlatformQualitySettings.h"
#include "MaterialShaderQualitySettings.h"
#include "PrimitiveSceneInfo.h"
#include "MeshPassProcessor.h"
#include "MeshPassProcessor.inl"
#include "EditorPrimitivesRendering.h"
#include "FramePro/FrameProProfiler.h"
#include "PostProcess/PostProcessPixelProjectedReflectionMobile.h"
#include "Engine/SubsurfaceProfile.h"
#include "LocalLightSceneProxy.h"
#include "ReflectionEnvironment.h"
// Changing this causes a full shader recompile
static TAutoConsoleVariable<int32> CVarMobileDisableVertexFog(
TEXT("r.Mobile.DisableVertexFog"),
0,
TEXT("Set to 1 to disable vertex fogging in all mobile shaders."),
ECVF_ReadOnly | ECVF_RenderThreadSafe);
static TAutoConsoleVariable<int32> CVarMobileEnableMovableSpotLightShadows(
TEXT("r.Mobile.EnableMovableSpotlightsShadow"),
0,
TEXT("If 1 then enable movable spotlight shadow support"),
ECVF_ReadOnly | ECVF_RenderThreadSafe);
static TAutoConsoleVariable<int32> CVarMobileMaxVisibleMovableSpotLightShadows(
TEXT("r.Mobile.MaxVisibleMovableSpotLightShadows"),
8,
TEXT("The max number of visible spotlighs can cast shadow sorted by screen size, should be as less as possible for performance reason"),
ECVF_RenderThreadSafe);
static TAutoConsoleVariable<int32> CVarMobileSceneDepthAux(
TEXT("r.Mobile.SceneDepthAux"),
1,
TEXT("1: 16F SceneDepthAux Format")
TEXT("2: 32F SceneDepthAux Format"),
ECVF_Scalability | ECVF_RenderThreadSafe);
static TAutoConsoleVariable<int32> CVarMobilePropagateAlpha(
TEXT("r.Mobile.PropagateAlpha"),
0,
TEXT("0: Disabled")
TEXT("1: Propagate Full Alpha Propagate"),
ECVF_ReadOnly | ECVF_RenderThreadSafe);
IMPLEMENT_STATIC_UNIFORM_BUFFER_STRUCT(FMobileBasePassUniformParameters, "MobileBasePass", SceneTextures);
static TAutoConsoleVariable<int32> CVarMobileUseHWsRGBEncoding(
TEXT("r.Mobile.UseHWsRGBEncoding"),
0,
TEXT("0: Write sRGB encoding in the shader\n")
TEXT("1: Use GPU HW to convert linear to sRGB automatically (device must support sRGB write control)\n"),
ECVF_RenderThreadSafe);
bool ShouldCacheShaderByPlatformAndOutputFormat(EShaderPlatform Platform, EOutputFormat OutputFormat)
{
bool bSupportsMobileHDR = IsMobileHDR();
bool bShaderUsesLDR = (OutputFormat == LDR_GAMMA_32);
// only cache this shader if the LDR/HDR output matches what we currently support. IsMobileHDR can't change, so we don't need
// the LDR shaders if we are doing HDR, and vice-versa.
return (bShaderUsesLDR && !bSupportsMobileHDR) || (!bShaderUsesLDR && bSupportsMobileHDR);
}
#define IMPLEMENT_MOBILE_SHADING_BASEPASS_LIGHTMAPPED_VERTEX_SHADER_TYPE(LightMapPolicyType,LightMapPolicyName) \
typedef TMobileBasePassVS< LightMapPolicyType, LDR_GAMMA_32 > TMobileBasePassVS##LightMapPolicyName##LDRGamma32; \
typedef TMobileBasePassVS< LightMapPolicyType, HDR_LINEAR_64 > TMobileBasePassVS##LightMapPolicyName##HDRLinear64; \
IMPLEMENT_MATERIAL_SHADER_TYPE(template<>, TMobileBasePassVS##LightMapPolicyName##LDRGamma32, TEXT("/Engine/Private/MobileBasePassVertexShader.usf"), TEXT("Main"), SF_Vertex); \
IMPLEMENT_MATERIAL_SHADER_TYPE(template<>, TMobileBasePassVS##LightMapPolicyName##HDRLinear64, TEXT("/Engine/Private/MobileBasePassVertexShader.usf"), TEXT("Main"), SF_Vertex);
#define IMPLEMENT_MOBILE_SHADING_BASEPASS_LIGHTMAPPED_PIXEL_SHADER_TYPE(LightMapPolicyType,LightMapPolicyName) \
typedef TMobileBasePassPS< LightMapPolicyType, LDR_GAMMA_32, false, false > TMobileBasePassPS##LightMapPolicyName##LDRGamma32; \
typedef TMobileBasePassPS< LightMapPolicyType, HDR_LINEAR_64, false, false > TMobileBasePassPS##LightMapPolicyName##HDRLinear64; \
typedef TMobileBasePassPS< LightMapPolicyType, LDR_GAMMA_32, true, false > TMobileBasePassPS##LightMapPolicyName##LDRGamma32##Skylight; \
typedef TMobileBasePassPS< LightMapPolicyType, HDR_LINEAR_64, true, false > TMobileBasePassPS##LightMapPolicyName##HDRLinear64##Skylight; \
typedef TMobileBasePassPS< LightMapPolicyType, LDR_GAMMA_32, false, true > TMobileBasePassPS##LightMapPolicyName##LDRGamma32##EnableLocalLights; \
typedef TMobileBasePassPS< LightMapPolicyType, HDR_LINEAR_64, false, true > TMobileBasePassPS##LightMapPolicyName##HDRLinear64##EnableLocalLights; \
typedef TMobileBasePassPS< LightMapPolicyType, LDR_GAMMA_32, true, true > TMobileBasePassPS##LightMapPolicyName##LDRGamma32##Skylight##EnableLocalLights; \
typedef TMobileBasePassPS< LightMapPolicyType, HDR_LINEAR_64, true, true > TMobileBasePassPS##LightMapPolicyName##HDRLinear64##Skylight##EnableLocalLights; \
IMPLEMENT_MATERIAL_SHADER_TYPE(template<>, TMobileBasePassPS##LightMapPolicyName##LDRGamma32, TEXT("/Engine/Private/MobileBasePassPixelShader.usf"), TEXT("Main"), SF_Pixel); \
IMPLEMENT_MATERIAL_SHADER_TYPE(template<>, TMobileBasePassPS##LightMapPolicyName##HDRLinear64, TEXT("/Engine/Private/MobileBasePassPixelShader.usf"), TEXT("Main"), SF_Pixel); \
IMPLEMENT_MATERIAL_SHADER_TYPE(template<>, TMobileBasePassPS##LightMapPolicyName##LDRGamma32##Skylight, TEXT("/Engine/Private/MobileBasePassPixelShader.usf"), TEXT("Main"), SF_Pixel); \
IMPLEMENT_MATERIAL_SHADER_TYPE(template<>, TMobileBasePassPS##LightMapPolicyName##HDRLinear64##Skylight, TEXT("/Engine/Private/MobileBasePassPixelShader.usf"), TEXT("Main"), SF_Pixel) \
IMPLEMENT_MATERIAL_SHADER_TYPE(template<>, TMobileBasePassPS##LightMapPolicyName##LDRGamma32##EnableLocalLights, TEXT("/Engine/Private/MobileBasePassPixelShader.usf"), TEXT("Main"), SF_Pixel); \
IMPLEMENT_MATERIAL_SHADER_TYPE(template<>, TMobileBasePassPS##LightMapPolicyName##HDRLinear64##EnableLocalLights, TEXT("/Engine/Private/MobileBasePassPixelShader.usf"), TEXT("Main"), SF_Pixel); \
IMPLEMENT_MATERIAL_SHADER_TYPE(template<>, TMobileBasePassPS##LightMapPolicyName##LDRGamma32##Skylight##EnableLocalLights, TEXT("/Engine/Private/MobileBasePassPixelShader.usf"), TEXT("Main"), SF_Pixel); \
IMPLEMENT_MATERIAL_SHADER_TYPE(template<>, TMobileBasePassPS##LightMapPolicyName##HDRLinear64##Skylight##EnableLocalLights, TEXT("/Engine/Private/MobileBasePassPixelShader.usf"), TEXT("Main"), SF_Pixel);
#define IMPLEMENT_MOBILE_SHADING_BASEPASS_LIGHTMAPPED_SHADER_TYPE(LightMapPolicyType,LightMapPolicyName) \
IMPLEMENT_MOBILE_SHADING_BASEPASS_LIGHTMAPPED_VERTEX_SHADER_TYPE(LightMapPolicyType, LightMapPolicyName) \
IMPLEMENT_MOBILE_SHADING_BASEPASS_LIGHTMAPPED_PIXEL_SHADER_TYPE(LightMapPolicyType, LightMapPolicyName)
// Implement shader types per lightmap policy
IMPLEMENT_MOBILE_SHADING_BASEPASS_LIGHTMAPPED_SHADER_TYPE(TUniformLightMapPolicy<LMP_NO_LIGHTMAP>, FNoLightMapPolicy);
IMPLEMENT_MOBILE_SHADING_BASEPASS_LIGHTMAPPED_SHADER_TYPE(TUniformLightMapPolicy<LMP_LQ_LIGHTMAP>, TLightMapPolicyLQ);
IMPLEMENT_MOBILE_SHADING_BASEPASS_LIGHTMAPPED_SHADER_TYPE(TUniformLightMapPolicy<LMP_MOBILE_DISTANCE_FIELD_SHADOWS_AND_LQ_LIGHTMAP>, FMobileDistanceFieldShadowsAndLQLightMapPolicy);
IMPLEMENT_MOBILE_SHADING_BASEPASS_LIGHTMAPPED_SHADER_TYPE(TUniformLightMapPolicy<LMP_MOBILE_DISTANCE_FIELD_SHADOWS_LIGHTMAP_AND_CSM>, FMobileDistanceFieldShadowsLightMapAndCSMLightingPolicy);
IMPLEMENT_MOBILE_SHADING_BASEPASS_LIGHTMAPPED_SHADER_TYPE(TUniformLightMapPolicy<LMP_MOBILE_DIRECTIONAL_LIGHT_CSM_AND_LIGHTMAP>, FMobileDirectionalLightCSMAndLightMapPolicy);
IMPLEMENT_MOBILE_SHADING_BASEPASS_LIGHTMAPPED_SHADER_TYPE(TUniformLightMapPolicy<LMP_MOBILE_DIRECTIONAL_LIGHT_AND_SH_INDIRECT>, FMobileDirectionalLightAndSHIndirectPolicy);
IMPLEMENT_MOBILE_SHADING_BASEPASS_LIGHTMAPPED_SHADER_TYPE(TUniformLightMapPolicy<LMP_MOBILE_DIRECTIONAL_LIGHT_CSM_AND_SH_INDIRECT>, FMobileDirectionalLightCSMAndSHIndirectPolicy);
IMPLEMENT_MOBILE_SHADING_BASEPASS_LIGHTMAPPED_SHADER_TYPE(TUniformLightMapPolicy<LMP_MOBILE_MOVABLE_DIRECTIONAL_LIGHT_WITH_LIGHTMAP>, FMobileMovableDirectionalLightWithLightmapPolicy);
IMPLEMENT_MOBILE_SHADING_BASEPASS_LIGHTMAPPED_SHADER_TYPE(TUniformLightMapPolicy<LMP_MOBILE_MOVABLE_DIRECTIONAL_LIGHT_CSM_WITH_LIGHTMAP>, FMobileMovableDirectionalLightCSMWithLightmapPolicy);
IMPLEMENT_MOBILE_SHADING_BASEPASS_LIGHTMAPPED_SHADER_TYPE(TUniformLightMapPolicy<LMP_MOBILE_DIRECTIONAL_LIGHT_CSM>, FMobileDirectionalLightAndCSMPolicy);
template<typename LightMapPolicyType>
bool TMobileBasePassPSPolicyParamType<LightMapPolicyType>::ModifyCompilationEnvironmentForQualityLevel(EShaderPlatform Platform, EMaterialQualityLevel::Type QualityLevel, FShaderCompilerEnvironment& OutEnvironment)
{
// Get quality settings for shader platform
const UShaderPlatformQualitySettings* MaterialShadingQuality = UMaterialShaderQualitySettings::Get()->GetShaderPlatformQualitySettings(Platform);
const FMaterialQualityOverrides& QualityOverrides = MaterialShadingQuality->GetQualityOverrides(QualityLevel);
// the point of this check is to keep the logic between enabling overrides here and in UMaterial::GetQualityLevelUsage() in sync
checkf(QualityOverrides.CanOverride(Platform), TEXT("ShaderPlatform %d was not marked as being able to use quality overrides! Include it in CanOverride() and recook."), static_cast<int32>(Platform));
OutEnvironment.SetDefine(TEXT("MOBILE_QL_FORCE_FULLY_ROUGH"), QualityOverrides.bEnableOverride && QualityOverrides.bForceFullyRough != 0 ? 1u : 0u);
OutEnvironment.SetDefine(TEXT("MOBILE_QL_FORCE_NONMETAL"), QualityOverrides.bEnableOverride && QualityOverrides.bForceNonMetal != 0 ? 1u : 0u);
OutEnvironment.SetDefine(TEXT("QL_FORCEDISABLE_LM_DIRECTIONALITY"), QualityOverrides.bEnableOverride && QualityOverrides.bForceDisableLMDirectionality != 0 ? 1u : 0u);
OutEnvironment.SetDefine(TEXT("MOBILE_QL_FORCE_DISABLE_PREINTEGRATEDGF"), QualityOverrides.bEnableOverride && QualityOverrides.bForceDisablePreintegratedGF != 0 ? 1u : 0u);
OutEnvironment.SetDefine(TEXT("MOBILE_SHADOW_QUALITY"), (uint32)QualityOverrides.MobileShadowQuality);
OutEnvironment.SetDefine(TEXT("MOBILE_QL_DISABLE_MATERIAL_NORMAL"), QualityOverrides.bEnableOverride && QualityOverrides.bDisableMaterialNormalCalculation);
return true;
}
extern void SetupDummyForwardLightUniformParameters(FRDGBuilder& GraphBuilder, FForwardLightData& ForwardLightData);
void SetupMobileBasePassUniformParameters(
FRDGBuilder& GraphBuilder,
const FViewInfo& View,
EMobileBasePass BasePass,
EMobileSceneTextureSetupMode SetupMode,
const FMobileBasePassTextures& MobileBasePassTextures,
FMobileBasePassUniformParameters& BasePassParameters)
{
SetupFogUniformParameters(GraphBuilder, View, BasePassParameters.Fog);
if (View.ForwardLightingResources.ForwardLightData)
{
BasePassParameters.Forward = *View.ForwardLightingResources.ForwardLightData;
}
else
{
SetupDummyForwardLightUniformParameters(GraphBuilder, BasePassParameters.Forward);
}
const FScene* Scene = View.Family->Scene ? View.Family->Scene->GetRenderScene() : nullptr;
const FPlanarReflectionSceneProxy* ReflectionSceneProxy = Scene ? Scene->GetForwardPassGlobalPlanarReflection() : nullptr;
SetupPlanarReflectionUniformParameters(View, ReflectionSceneProxy, BasePassParameters.PlanarReflection);
if (View.PrevViewInfo.MobilePixelProjectedReflection.IsValid())
{
BasePassParameters.PlanarReflection.PlanarReflectionTexture = View.PrevViewInfo.MobilePixelProjectedReflection->GetRHI();
BasePassParameters.PlanarReflection.PlanarReflectionSampler = TStaticSamplerState<SF_Bilinear, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();
}
else if (BasePassParameters.PlanarReflection.PlanarReflectionTexture == nullptr)
{
BasePassParameters.PlanarReflection.PlanarReflectionTexture = GBlackTexture->TextureRHI;
BasePassParameters.PlanarReflection.PlanarReflectionSampler = GBlackTexture->SamplerStateRHI;
}
const FRDGSystemTextures& SystemTextures = FRDGSystemTextures::Get(GraphBuilder);
SetupMobileSceneTextureUniformParameters(GraphBuilder, View.GetSceneTexturesChecked(), SetupMode, BasePassParameters.SceneTextures);
BasePassParameters.PreIntegratedGFTexture = GSystemTextures.PreintegratedGF->GetRHI();
BasePassParameters.PreIntegratedGFSampler = TStaticSamplerState<SF_Bilinear, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();
BasePassParameters.EyeAdaptationBuffer = GraphBuilder.CreateSRV(GetEyeAdaptationBuffer(GraphBuilder, View), PF_A32B32G32R32F);
FRDGTextureRef AmbientOcclusionTexture = SystemTextures.White;
if (BasePass == EMobileBasePass::Opaque && MobileBasePassTextures.ScreenSpaceAO != nullptr)
{
AmbientOcclusionTexture = MobileBasePassTextures.ScreenSpaceAO;
}
BasePassParameters.AmbientOcclusionTexture = AmbientOcclusionTexture;
BasePassParameters.AmbientOcclusionSampler = TStaticSamplerState<SF_Bilinear, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();
BasePassParameters.AmbientOcclusionStaticFraction = FMath::Clamp(View.FinalPostProcessSettings.AmbientOcclusionStaticFraction, 0.0f, 1.0f);
const bool bMobileUsesShadowMaskTexture = MobileUsesShadowMaskTexture(View.GetShaderPlatform());
if (bMobileUsesShadowMaskTexture && GScreenSpaceShadowMaskTextureMobileOutputs.ScreenSpaceShadowMaskTextureMobile.IsValid())
{
FRDGTextureRef ScreenShadowMaskTexture = GraphBuilder.RegisterExternalTexture(GScreenSpaceShadowMaskTextureMobileOutputs.ScreenSpaceShadowMaskTextureMobile, TEXT("ScreenSpaceShadowMaskTextureMobile"));
BasePassParameters.ScreenSpaceShadowMaskTexture = ScreenShadowMaskTexture;
BasePassParameters.ScreenSpaceShadowMaskSampler = TStaticSamplerState<SF_Point, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();
}
else
{
BasePassParameters.ScreenSpaceShadowMaskTexture = GSystemTextures.GetWhiteDummy(GraphBuilder);
BasePassParameters.ScreenSpaceShadowMaskSampler = TStaticSamplerState<SF_Point, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();
}
SetupReflectionUniformParameters(View, BasePassParameters.ReflectionsParameters);
}
TRDGUniformBufferRef<FMobileBasePassUniformParameters> CreateMobileBasePassUniformBuffer(
FRDGBuilder& GraphBuilder,
const FViewInfo& View,
EMobileBasePass BasePass,
EMobileSceneTextureSetupMode SetupMode,
const FMobileBasePassTextures& MobileBasePassTextures)
{
FMobileBasePassUniformParameters* BasePassParameters = GraphBuilder.AllocParameters<FMobileBasePassUniformParameters>();
SetupMobileBasePassUniformParameters(GraphBuilder, View, BasePass, SetupMode, MobileBasePassTextures, *BasePassParameters);
#if WITH_DEBUG_VIEW_MODES
if (View.Family->UseDebugViewPS())
{
SetupDebugViewModePassUniformBufferConstants(View, BasePassParameters->DebugViewMode);
}
#endif
return GraphBuilder.CreateUniformBuffer(BasePassParameters);
}
void SetupMobileDirectionalLightUniformParameters(
const FScene& Scene,
int32 ViewIndex,
const FViewInfo& SceneView,
const TArray<FVisibleLightInfo,SceneRenderingAllocator>& VisibleLightInfos,
int32 ChannelIdx,
bool bDynamicShadows,
FMobileDirectionalLightShaderParameters& Params)
{
ERHIFeatureLevel::Type FeatureLevel = Scene.GetFeatureLevel();
FLightSceneInfo* Light = Scene.MobileDirectionalLights[ChannelIdx];
if (Light)
{
Params.DirectionalLightColor = Light->Proxy->GetSunIlluminanceAccountingForSkyAtmospherePerPixelTransmittance() / PI;
Params.DirectionalLightDirectionAndShadowTransition = FVector4f((FVector3f)-Light->Proxy->GetDirection(), 0.f);
const FVector2D FadeParams = Light->Proxy->GetDirectionalLightDistanceFadeParameters(FeatureLevel, Light->IsPrecomputedLightingValid(), SceneView.MaxShadowCascades);
Params.DirectionalLightDistanceFadeMADAndSpecularScale.X = FadeParams.Y;
Params.DirectionalLightDistanceFadeMADAndSpecularScale.Y = -FadeParams.X * FadeParams.Y;
Params.DirectionalLightDistanceFadeMADAndSpecularScale.Z = Light->Proxy->GetSpecularScale();
if (bDynamicShadows && VisibleLightInfos.IsValidIndex(Light->Id) && VisibleLightInfos[Light->Id].AllProjectedShadows.Num() > 0)
{
const TArray<FProjectedShadowInfo*, SceneRenderingAllocator>& DirectionalLightShadowInfos = VisibleLightInfos[Light->Id].AllProjectedShadows;
static_assert(MAX_MOBILE_SHADOWCASCADES <= 4, "more than 4 cascades not supported by the shader and uniform buffer");
const int32 NumShadowsToCopy = FMath::Min(DirectionalLightShadowInfos.Num(), SceneView.MaxShadowCascades);
int32_t OutShadowIndex = 0;
for (int32 i = 0; i < NumShadowsToCopy; ++i)
{
const FProjectedShadowInfo* ShadowInfo = DirectionalLightShadowInfos[i + ViewIndex * NumShadowsToCopy];
if (ShadowInfo->ShadowDepthView && !ShadowInfo->bRayTracedDistanceField && ShadowInfo->CacheMode != SDCM_StaticPrimitivesOnly)
{
if (OutShadowIndex == 0)
{
const FIntPoint ShadowBufferResolution = ShadowInfo->GetShadowBufferResolution();
const FVector4f ShadowBufferSizeValue((float)ShadowBufferResolution.X, (float)ShadowBufferResolution.Y, 1.0f / (float)ShadowBufferResolution.X, 1.0f / (float)ShadowBufferResolution.Y);
Params.DirectionalLightShadowTexture = ShadowInfo->RenderTargets.DepthTarget->GetRHI();
Params.DirectionalLightDirectionAndShadowTransition.W = 1.0f / ShadowInfo->ComputeTransitionSize();
Params.DirectionalLightShadowSize = ShadowBufferSizeValue;
Params.DirectionalLightDistanceFadeMADAndSpecularScale.W = ShadowInfo->GetShaderReceiverDepthBias();
}
Params.DirectionalLightScreenToShadow[OutShadowIndex] = FMatrix44f(ShadowInfo->GetScreenToShadowMatrix(SceneView)); // LWC_TODO: Precision loss?
Params.DirectionalLightShadowDistances[OutShadowIndex] = ShadowInfo->CascadeSettings.SplitFar;
OutShadowIndex++;
}
}
}
}
}
void SetupMobileSkyReflectionUniformParameters(FSkyLightSceneProxy* SkyLight, FMobileReflectionCaptureShaderParameters& Parameters)
{
float Brightness = 0.f;
float SkyMaxMipIndex = 0.f;
FTexture* CaptureTexture = GBlackTextureCube;
if (SkyLight && SkyLight->ProcessedTexture)
{
check(SkyLight->ProcessedTexture->IsInitialized());
CaptureTexture = SkyLight->ProcessedTexture;
SkyMaxMipIndex = FMath::Log2(static_cast<float>(CaptureTexture->GetSizeX()));
Brightness = SkyLight->AverageBrightness;
}
//To keep ImageBasedReflectionLighting coherence with PC, use AverageBrightness instead of InvAverageBrightness to calculate the IBL contribution
Parameters.Params = FVector4f(Brightness, SkyMaxMipIndex, 0.f, 0.f);
Parameters.Texture = CaptureTexture->TextureRHI;
Parameters.TextureSampler = CaptureTexture->SamplerStateRHI;
}
void FMobileSceneRenderer::RenderMobileBasePass(FRHICommandListImmediate& RHICmdList, const FViewInfo& View)
{
CSV_SCOPED_TIMING_STAT_EXCLUSIVE(RenderBasePass);
SCOPED_DRAW_EVENT(RHICmdList, MobileBasePass);
SCOPE_CYCLE_COUNTER(STAT_BasePassDrawTime);
SCOPED_GPU_STAT(RHICmdList, Basepass);
RHICmdList.SetViewport(View.ViewRect.Min.X, View.ViewRect.Min.Y, 0, View.ViewRect.Max.X, View.ViewRect.Max.Y, 1);
View.ParallelMeshDrawCommandPasses[EMeshPass::BasePass].DispatchDraw(nullptr, RHICmdList, &MeshPassInstanceCullingDrawParams[EMeshPass::BasePass]);
if (View.Family->EngineShowFlags.Atmosphere)
{
View.ParallelMeshDrawCommandPasses[EMeshPass::SkyPass].DispatchDraw(nullptr, RHICmdList, &MeshPassInstanceCullingDrawParams[EMeshPass::SkyPass]);
}
// editor primitives
FMeshPassProcessorRenderState DrawRenderState;
DrawRenderState.SetBlendState(TStaticBlendStateWriteMask<CW_RGBA>::GetRHI());
DrawRenderState.SetDepthStencilAccess(Scene->DefaultBasePassDepthStencilAccess);
DrawRenderState.SetDepthStencilState(TStaticDepthStencilState<true, CF_DepthNearOrEqual>::GetRHI());
RenderMobileEditorPrimitives(RHICmdList, View, DrawRenderState);
}
void FMobileSceneRenderer::RenderMobileEditorPrimitives(FRHICommandList& RHICmdList, const FViewInfo& View, const FMeshPassProcessorRenderState& DrawRenderState)
{
QUICK_SCOPE_CYCLE_COUNTER(STAT_EditorDynamicPrimitiveDrawTime);
SCOPED_DRAW_EVENT(RHICmdList, DynamicEd);
View.SimpleElementCollector.DrawBatchedElements(RHICmdList, DrawRenderState, View, EBlendModeFilter::OpaqueAndMasked, SDPG_World);
View.SimpleElementCollector.DrawBatchedElements(RHICmdList, DrawRenderState, View, EBlendModeFilter::OpaqueAndMasked, SDPG_Foreground);
if (!View.Family->EngineShowFlags.CompositeEditorPrimitives)
{
const bool bNeedToSwitchVerticalAxis = RHINeedsToSwitchVerticalAxis(GShaderPlatformForFeatureLevel[FeatureLevel]) && !IsMobileHDR();
DrawDynamicMeshPass(View, RHICmdList,
[&View, &DrawRenderState](FDynamicPassMeshDrawListContext* DynamicMeshPassContext)
{
FEditorPrimitivesBasePassMeshProcessor PassMeshProcessor(
View.Family->Scene->GetRenderScene(),
View.GetFeatureLevel(),
&View,
DrawRenderState,
false,
DynamicMeshPassContext);
const uint64 DefaultBatchElementMask = ~0ull;
for (int32 MeshIndex = 0; MeshIndex < View.ViewMeshElements.Num(); MeshIndex++)
{
const FMeshBatch& MeshBatch = View.ViewMeshElements[MeshIndex];
PassMeshProcessor.AddMeshBatch(MeshBatch, DefaultBatchElementMask, nullptr);
}
});
// Draw the view's batched simple elements(lines, sprites, etc).
View.BatchedViewElements.Draw(RHICmdList, DrawRenderState, FeatureLevel, bNeedToSwitchVerticalAxis, View, false);
DrawDynamicMeshPass(View, RHICmdList,
[&View, &DrawRenderState](FDynamicPassMeshDrawListContext* DynamicMeshPassContext)
{
FEditorPrimitivesBasePassMeshProcessor PassMeshProcessor(
View.Family->Scene->GetRenderScene(),
View.GetFeatureLevel(),
&View,
DrawRenderState,
false,
DynamicMeshPassContext);
const uint64 DefaultBatchElementMask = ~0ull;
for (int32 MeshIndex = 0; MeshIndex < View.TopViewMeshElements.Num(); MeshIndex++)
{
const FMeshBatch& MeshBatch = View.TopViewMeshElements[MeshIndex];
PassMeshProcessor.AddMeshBatch(MeshBatch, DefaultBatchElementMask, nullptr);
}
});
// Draw the view's batched simple elements(lines, sprites, etc).
View.TopBatchedViewElements.Draw(RHICmdList, DrawRenderState, FeatureLevel, bNeedToSwitchVerticalAxis, View, false);
}
}