You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#rb ben.woodhouse #ROBOMERGE-OWNER: ryan.vance #ROBOMERGE-AUTHOR: jeff.newquist #ROBOMERGE-SOURCE: CL 5830660 via CL 5830670 via CL 5835167 via CL 5835925 #ROBOMERGE-BOT: DEVVR (Main -> Dev-VR) [CL 5876639 by jeff newquist in Dev-VR branch]
318 lines
18 KiB
C++
318 lines
18 KiB
C++
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*=============================================================================
|
|
MobileBasePassRendering.cpp: Base pass rendering implementation.
|
|
=============================================================================*/
|
|
|
|
#include "MobileBasePassRendering.h"
|
|
#include "DynamicPrimitiveDrawing.h"
|
|
#include "ScenePrivate.h"
|
|
#include "ShaderPlatformQualitySettings.h"
|
|
#include "MaterialShaderQualitySettings.h"
|
|
#include "PrimitiveSceneInfo.h"
|
|
#include "MeshPassProcessor.h"
|
|
#include "MeshPassProcessor.inl"
|
|
#include "EditorPrimitivesRendering.h"
|
|
|
|
#include "FramePro/FrameProProfiler.h"
|
|
|
|
// Changing this causes a full shader recompile
|
|
static TAutoConsoleVariable<int32> CVarMobileDisableVertexFog(
|
|
TEXT("r.Mobile.DisableVertexFog"),
|
|
1,
|
|
TEXT("Set to 1 to disable vertex fogging in all mobile shaders."),
|
|
ECVF_ReadOnly | ECVF_RenderThreadSafe);
|
|
|
|
|
|
static TAutoConsoleVariable<int32> CVarMobileUseLegacyShadingModel(
|
|
TEXT("r.Mobile.UseLegacyShadingModel"),
|
|
0,
|
|
TEXT("If 1 then use legacy (pre 4.20) shading model (such as spherical guassian specular calculation.) (will cause a shader rebuild)"),
|
|
ECVF_ReadOnly | ECVF_RenderThreadSafe);
|
|
|
|
static TAutoConsoleVariable<int32> CVarMobileEnableMovableSpotLights(
|
|
TEXT("r.Mobile.EnableMovableSpotlights"),
|
|
0,
|
|
TEXT("If 1 then enable movable spotlight support"),
|
|
ECVF_ReadOnly | ECVF_RenderThreadSafe);
|
|
|
|
|
|
IMPLEMENT_GLOBAL_SHADER_PARAMETER_STRUCT(FMobileBasePassUniformParameters, "MobileBasePass");
|
|
|
|
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);
|
|
|
|
|
|
#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,NumMovablePointLights) \
|
|
typedef TMobileBasePassPS< LightMapPolicyType, LDR_GAMMA_32, false, NumMovablePointLights > TMobileBasePassPS##LightMapPolicyName##NumMovablePointLights##LDRGamma32; \
|
|
typedef TMobileBasePassPS< LightMapPolicyType, HDR_LINEAR_64, false, NumMovablePointLights > TMobileBasePassPS##LightMapPolicyName##NumMovablePointLights##HDRLinear64; \
|
|
typedef TMobileBasePassPS< LightMapPolicyType, LDR_GAMMA_32, true, NumMovablePointLights > TMobileBasePassPS##LightMapPolicyName##NumMovablePointLights##LDRGamma32##Skylight; \
|
|
typedef TMobileBasePassPS< LightMapPolicyType, HDR_LINEAR_64, true, NumMovablePointLights > TMobileBasePassPS##LightMapPolicyName##NumMovablePointLights##HDRLinear64##Skylight; \
|
|
IMPLEMENT_MATERIAL_SHADER_TYPE(template<>, TMobileBasePassPS##LightMapPolicyName##NumMovablePointLights##LDRGamma32, TEXT("/Engine/Private/MobileBasePassPixelShader.usf"), TEXT("Main"), SF_Pixel); \
|
|
IMPLEMENT_MATERIAL_SHADER_TYPE(template<>, TMobileBasePassPS##LightMapPolicyName##NumMovablePointLights##HDRLinear64, TEXT("/Engine/Private/MobileBasePassPixelShader.usf"), TEXT("Main"), SF_Pixel); \
|
|
IMPLEMENT_MATERIAL_SHADER_TYPE(template<>, TMobileBasePassPS##LightMapPolicyName##NumMovablePointLights##LDRGamma32##Skylight, TEXT("/Engine/Private/MobileBasePassPixelShader.usf"), TEXT("Main"), SF_Pixel); \
|
|
IMPLEMENT_MATERIAL_SHADER_TYPE(template<>, TMobileBasePassPS##LightMapPolicyName##NumMovablePointLights##HDRLinear64##Skylight, TEXT("/Engine/Private/MobileBasePassPixelShader.usf"), TEXT("Main"), SF_Pixel);
|
|
|
|
static_assert(MAX_BASEPASS_DYNAMIC_POINT_LIGHTS == 4, "If you change MAX_BASEPASS_DYNAMIC_POINT_LIGHTS, you need to add shader types below");
|
|
|
|
// Permutations for the number of point lights to support. INT32_MAX indicates the shader should use branching to support a variable number of point lights.
|
|
#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, 0) \
|
|
IMPLEMENT_MOBILE_SHADING_BASEPASS_LIGHTMAPPED_PIXEL_SHADER_TYPE(LightMapPolicyType, LightMapPolicyName, 1) \
|
|
IMPLEMENT_MOBILE_SHADING_BASEPASS_LIGHTMAPPED_PIXEL_SHADER_TYPE(LightMapPolicyType, LightMapPolicyName, 2) \
|
|
IMPLEMENT_MOBILE_SHADING_BASEPASS_LIGHTMAPPED_PIXEL_SHADER_TYPE(LightMapPolicyType, LightMapPolicyName, 3) \
|
|
IMPLEMENT_MOBILE_SHADING_BASEPASS_LIGHTMAPPED_PIXEL_SHADER_TYPE(LightMapPolicyType, LightMapPolicyName, 4) \
|
|
IMPLEMENT_MOBILE_SHADING_BASEPASS_LIGHTMAPPED_PIXEL_SHADER_TYPE(LightMapPolicyType, LightMapPolicyName, INT32_MAX)
|
|
|
|
// 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_AND_SH_INDIRECT>, FMobileDirectionalLightAndSHIndirectPolicy);
|
|
IMPLEMENT_MOBILE_SHADING_BASEPASS_LIGHTMAPPED_SHADER_TYPE(TUniformLightMapPolicy<LMP_MOBILE_MOVABLE_DIRECTIONAL_LIGHT_AND_SH_INDIRECT>, FMobileMovableDirectionalLightAndSHIndirectPolicy);
|
|
IMPLEMENT_MOBILE_SHADING_BASEPASS_LIGHTMAPPED_SHADER_TYPE(TUniformLightMapPolicy<LMP_MOBILE_MOVABLE_DIRECTIONAL_LIGHT_CSM_AND_SH_INDIRECT>, FMobileMovableDirectionalLightCSMAndSHIndirectPolicy);
|
|
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>, FMobileMovableDirectionalLightLightingPolicy);
|
|
IMPLEMENT_MOBILE_SHADING_BASEPASS_LIGHTMAPPED_SHADER_TYPE(TUniformLightMapPolicy<LMP_MOBILE_MOVABLE_DIRECTIONAL_LIGHT_CSM>, FMobileMovableDirectionalLightCSMLightingPolicy);
|
|
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);
|
|
|
|
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);
|
|
|
|
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_LQ_REFLECTIONS"), QualityOverrides.bEnableOverride && QualityOverrides.bForceLQReflections != 0 ? 1u : 0u);
|
|
OutEnvironment.SetDefine(TEXT("MOBILE_CSM_QUALITY"), (uint32)QualityOverrides.MobileCSMQuality);
|
|
OutEnvironment.SetDefine(TEXT("MOBILE_QL_DISABLE_MATERIAL_NORMAL"), QualityOverrides.bEnableOverride && QualityOverrides.bDisableMaterialNormalCalculation);
|
|
return true;
|
|
}
|
|
|
|
FMobileBasePassMovableLightInfo::FMobileBasePassMovableLightInfo(const FPrimitiveSceneProxy* InSceneProxy)
|
|
: NumMovablePointLights(0)
|
|
{
|
|
static auto* MobileNumDynamicPointLightsCVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.MobileNumDynamicPointLights"));
|
|
const int32 MobileNumDynamicPointLights = MobileNumDynamicPointLightsCVar->GetValueOnRenderThread();
|
|
|
|
if (InSceneProxy != nullptr)
|
|
{
|
|
for (FLightPrimitiveInteraction* LPI = InSceneProxy->GetPrimitiveSceneInfo()->LightList; LPI && NumMovablePointLights < MobileNumDynamicPointLights; LPI = LPI->GetNextLight())
|
|
{
|
|
FLightSceneProxy* LightProxy = LPI->GetLight()->Proxy;
|
|
const uint8 LightType = LightProxy->GetLightType();
|
|
const bool bIsValidLightType =
|
|
LightType == LightType_Point
|
|
|| LightType == LightType_Rect
|
|
|| (LightType == LightType_Spot && CVarMobileEnableMovableSpotLights.GetValueOnRenderThread());
|
|
|
|
if (bIsValidLightType && LightProxy->IsMovable() && (LightProxy->GetLightingChannelMask() & InSceneProxy->GetLightingChannelMask()) != 0)
|
|
{
|
|
FLightShaderParameters LightParameters;
|
|
LightProxy->GetLightShaderParameters(LightParameters);
|
|
|
|
LightPositionAndInvRadius[NumMovablePointLights] = FVector4(LightParameters.Position, LightParameters.InvRadius);
|
|
LightColorAndFalloffExponent[NumMovablePointLights] = FVector4(LightParameters.Color, LightParameters.FalloffExponent);
|
|
SpotLightDirection[NumMovablePointLights] = LightParameters.Direction;
|
|
SpotLightAngles[NumMovablePointLights].Set(LightParameters.SpotAngles.X, LightParameters.SpotAngles.Y, 0.f, LightType == LightType_Spot ? 1.0f : 0.0f);
|
|
|
|
if (LightType == LightType_Rect)
|
|
{
|
|
// Treat rect lights as point lights.
|
|
LightColorAndFalloffExponent[NumMovablePointLights] = FVector4(LightParameters.Color, LightParameters.FalloffExponent);
|
|
}
|
|
|
|
if (LightProxy->IsInverseSquared())
|
|
{
|
|
LightColorAndFalloffExponent[NumMovablePointLights].W = 0;
|
|
}
|
|
|
|
NumMovablePointLights++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void SetupMobileBasePassUniformParameters(
|
|
FRHICommandListImmediate& RHICmdList,
|
|
const FViewInfo& View,
|
|
bool bTranslucentPass,
|
|
FMobileBasePassUniformParameters& BasePassParameters)
|
|
{
|
|
SetupFogUniformParameters(View, BasePassParameters.Fog);
|
|
|
|
const FScene* Scene = View.Family->Scene ? View.Family->Scene->GetRenderScene() : nullptr;
|
|
const FPlanarReflectionSceneProxy* ReflectionSceneProxy = Scene ? Scene->GetForwardPassGlobalPlanarReflection() : nullptr;
|
|
SetupPlanarReflectionUniformParameters(View, ReflectionSceneProxy, BasePassParameters.PlanarReflection);
|
|
|
|
FSceneRenderTargets& SceneContext = FSceneRenderTargets::Get(RHICmdList);
|
|
SetupMobileSceneTextureUniformParameters(SceneContext, View.FeatureLevel, bTranslucentPass, BasePassParameters.SceneTextures);
|
|
}
|
|
|
|
void CreateMobileBasePassUniformBuffer(
|
|
FRHICommandListImmediate& RHICmdList,
|
|
const FViewInfo& View,
|
|
bool bTranslucentPass,
|
|
TUniformBufferRef<FMobileBasePassUniformParameters>& BasePassUniformBuffer)
|
|
{
|
|
FMobileBasePassUniformParameters BasePassParameters;
|
|
SetupMobileBasePassUniformParameters(RHICmdList, View, bTranslucentPass, BasePassParameters);
|
|
BasePassUniformBuffer = TUniformBufferRef<FMobileBasePassUniformParameters>::CreateUniformBufferImmediate(BasePassParameters, UniformBuffer_SingleFrame);
|
|
}
|
|
|
|
void SetupMobileDirectionalLightUniformParameters(
|
|
const FScene& Scene,
|
|
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->GetColor() / PI;
|
|
Params.DirectionalLightDirectionAndShadowTransition = FVector4(-Light->Proxy->GetDirection(), 0.f);
|
|
|
|
const FVector2D FadeParams = Light->Proxy->GetDirectionalLightDistanceFadeParameters(FeatureLevel, Light->IsPrecomputedLightingValid(), SceneView.MaxShadowCascades);
|
|
Params.DirectionalLightDistanceFadeMAD.X = FadeParams.Y;
|
|
Params.DirectionalLightDistanceFadeMAD.Y = -FadeParams.X * FadeParams.Y;
|
|
|
|
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 FProjectedShadowInfo* ShadowInfo = DirectionalLightShadowInfos[0];
|
|
const FIntPoint ShadowBufferResolution = ShadowInfo->GetShadowBufferResolution();
|
|
const FVector4 ShadowBufferSizeValue((float)ShadowBufferResolution.X, (float)ShadowBufferResolution.Y, 1.0f / (float)ShadowBufferResolution.X, 1.0f / (float)ShadowBufferResolution.Y);
|
|
|
|
Params.DirectionalLightShadowTexture = ShadowInfo->RenderTargets.DepthTarget->GetRenderTargetItem().ShaderResourceTexture.GetReference();
|
|
Params.DirectionalLightDirectionAndShadowTransition.W = 1.0f / ShadowInfo->ComputeTransitionSize();
|
|
Params.DirectionalLightShadowSize = ShadowBufferSizeValue;
|
|
}
|
|
|
|
const int32 NumShadowsToCopy = FMath::Min(DirectionalLightShadowInfos.Num(), MAX_MOBILE_SHADOWCASCADES);
|
|
for (int32 i = 0; i < NumShadowsToCopy; ++i)
|
|
{
|
|
const FProjectedShadowInfo* ShadowInfo = DirectionalLightShadowInfos[i];
|
|
Params.DirectionalLightScreenToShadow[i] = ShadowInfo->GetScreenToShadowMatrix(SceneView);
|
|
Params.DirectionalLightShadowDistances[i] = ShadowInfo->CascadeSettings.SplitFar;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void FMobileSceneRenderer::RenderMobileBasePass(FRHICommandListImmediate& RHICmdList, const TArrayView<const FViewInfo*> PassViews)
|
|
{
|
|
CSV_SCOPED_TIMING_STAT_EXCLUSIVE(RenderBasePass);
|
|
SCOPED_DRAW_EVENT(RHICmdList, MobileBasePass);
|
|
SCOPE_CYCLE_COUNTER(STAT_BasePassDrawTime);
|
|
|
|
for (int32 ViewIndex = 0; ViewIndex < PassViews.Num(); ViewIndex++)
|
|
{
|
|
SCOPED_CONDITIONAL_DRAW_EVENTF(RHICmdList, EventView, Views.Num() > 1, TEXT("View%d"), ViewIndex);
|
|
const FViewInfo& View = *PassViews[ViewIndex];
|
|
if (!View.ShouldRenderView())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (Scene->UniformBuffers.UpdateViewUniformBuffer(View))
|
|
{
|
|
UpdateOpaqueBasePassUniformBuffer(RHICmdList, View);
|
|
UpdateDirectionalLightUniformBuffers(RHICmdList, View);
|
|
}
|
|
|
|
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);
|
|
|
|
// editor primitives
|
|
{
|
|
FMeshPassProcessorRenderState DrawRenderState(View, Scene->UniformBuffers.MobileOpaqueBasePassUniformBuffer);
|
|
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);
|
|
}
|
|
}
|