You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#rb none #preflight 62716a75e16e280be615c60e #ROBOMERGE-AUTHOR: guillaume.abadie #ROBOMERGE-SOURCE: CL 20028907 via CL 20029052 via CL 20029067 #ROBOMERGE-BOT: UE5 (Release-Engine-Staging -> Main) (v943-19904690) [CL 20035006 by guillaume abadie in ue5-main branch]
568 lines
25 KiB
C++
568 lines
25 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#if WITH_EDITOR
|
|
|
|
#include "PostProcess/PostProcessCompositeEditorPrimitives.h"
|
|
#include "EditorPrimitivesRendering.h"
|
|
#include "MeshPassProcessor.inl"
|
|
#include "BasePassRendering.h"
|
|
#include "MobileBasePassRendering.h"
|
|
#include "SceneRenderingUtils.h"
|
|
#include "PixelShaderUtils.h"
|
|
#include "ScenePrivate.h"
|
|
|
|
namespace
|
|
{
|
|
TAutoConsoleVariable<int32> CVarEditorTemporalUpsampleDepth(
|
|
TEXT("r.Editor.TemporalUpsampleDepth"), 2,
|
|
TEXT("Temporal upsample factor of the depth buffer for depth testing editor primitives against."),
|
|
ECVF_RenderThreadSafe);
|
|
|
|
class FTemporalUpsampleEditorDepthPS : public FGlobalShader
|
|
{
|
|
public:
|
|
DECLARE_GLOBAL_SHADER(FTemporalUpsampleEditorDepthPS);
|
|
SHADER_USE_PARAMETER_STRUCT(FTemporalUpsampleEditorDepthPS, FGlobalShader);
|
|
|
|
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
|
|
SHADER_PARAMETER_STRUCT_REF(FViewUniformShaderParameters, View)
|
|
SHADER_PARAMETER_STRUCT(FScreenPassTextureViewportParameters, Depth)
|
|
SHADER_PARAMETER_STRUCT(FScreenPassTextureViewportParameters, PrevHistory)
|
|
SHADER_PARAMETER_STRUCT(FScreenPassTextureViewportParameters, History)
|
|
SHADER_PARAMETER(FVector2f, DepthTextureJitter)
|
|
SHADER_PARAMETER(int32, bCameraCut)
|
|
|
|
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, DepthTexture)
|
|
SHADER_PARAMETER_SAMPLER(SamplerState, DepthSampler)
|
|
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, VelocityTexture)
|
|
SHADER_PARAMETER_SAMPLER(SamplerState, VelocitySampler)
|
|
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, PrevHistoryTexture)
|
|
SHADER_PARAMETER_SAMPLER(SamplerState, PrevHistorySampler)
|
|
|
|
RENDER_TARGET_BINDING_SLOTS()
|
|
END_SHADER_PARAMETER_STRUCT()
|
|
|
|
static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
|
|
{
|
|
// Only PC platforms render editor primitives.
|
|
return IsPCPlatform(Parameters.Platform);
|
|
}
|
|
};
|
|
|
|
class FPopulateEditorDepthPS : public FGlobalShader
|
|
{
|
|
public:
|
|
DECLARE_GLOBAL_SHADER(FPopulateEditorDepthPS);
|
|
SHADER_USE_PARAMETER_STRUCT(FPopulateEditorDepthPS, FGlobalShader);
|
|
|
|
class FUseMSAADimension : SHADER_PERMUTATION_BOOL("USE_MSAA");
|
|
using FPermutationDomain = TShaderPermutationDomain<FUseMSAADimension>;
|
|
|
|
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
|
|
SHADER_PARAMETER_STRUCT_REF(FViewUniformShaderParameters, View)
|
|
SHADER_PARAMETER_STRUCT(FScreenPassTextureViewportParameters, Color)
|
|
SHADER_PARAMETER_STRUCT(FScreenPassTextureViewportParameters, Depth)
|
|
SHADER_PARAMETER(FVector2f, DepthTextureJitter)
|
|
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, DepthTexture)
|
|
SHADER_PARAMETER_SAMPLER(SamplerState, DepthSampler)
|
|
RENDER_TARGET_BINDING_SLOTS()
|
|
END_SHADER_PARAMETER_STRUCT()
|
|
|
|
static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
|
|
{
|
|
const FPermutationDomain PermutationVector(Parameters.PermutationId);
|
|
const bool bUseMSAA = PermutationVector.Get<FUseMSAADimension>();
|
|
|
|
// Only SM5+ platforms supports MSAA.
|
|
if (!IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5) && bUseMSAA)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Only PC platforms render editor primitives.
|
|
return IsPCPlatform(Parameters.Platform);
|
|
}
|
|
};
|
|
|
|
class FCompositeEditorPrimitivesPS : public FEditorPrimitiveShader
|
|
{
|
|
public:
|
|
DECLARE_GLOBAL_SHADER(FCompositeEditorPrimitivesPS);
|
|
SHADER_USE_PARAMETER_STRUCT(FCompositeEditorPrimitivesPS, FEditorPrimitiveShader);
|
|
|
|
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
|
|
SHADER_PARAMETER_STRUCT_REF(FViewUniformShaderParameters, View)
|
|
SHADER_PARAMETER_STRUCT(FScreenPassTextureViewportParameters, Color)
|
|
SHADER_PARAMETER_STRUCT(FScreenPassTextureViewportParameters, Depth)
|
|
SHADER_PARAMETER_STRUCT(FScreenPassTextureViewportParameters, Output)
|
|
SHADER_PARAMETER_ARRAY(FVector4f, SampleOffsetArray, [FEditorPrimitiveShader::kEditorMSAASampleCountMax])
|
|
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, EditorPrimitivesDepth)
|
|
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, EditorPrimitivesColor)
|
|
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, ColorTexture)
|
|
SHADER_PARAMETER_SAMPLER(SamplerState, ColorSampler)
|
|
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, DepthTexture)
|
|
SHADER_PARAMETER_SAMPLER(SamplerState, DepthSampler)
|
|
SHADER_PARAMETER(uint32, bOpaqueEditorGizmo)
|
|
SHADER_PARAMETER(uint32, bCompositeAnyNonNullDepth)
|
|
SHADER_PARAMETER(FVector2f, DepthTextureJitter)
|
|
RENDER_TARGET_BINDING_SLOTS()
|
|
END_SHADER_PARAMETER_STRUCT()
|
|
|
|
static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment)
|
|
{
|
|
FGlobalShader::ModifyCompilationEnvironment(Parameters, OutEnvironment);
|
|
OutEnvironment.SetDefine(TEXT("OUTPUT_SRGB_BUFFER"), IsMobileColorsRGB() && IsMobilePlatform(Parameters.Platform));
|
|
}
|
|
};
|
|
|
|
IMPLEMENT_GLOBAL_SHADER(FTemporalUpsampleEditorDepthPS, "/Engine/Private/PostProcessCompositeEditorPrimitives.usf", "MainTemporalUpsampleEditorDepthPS", SF_Pixel);
|
|
IMPLEMENT_GLOBAL_SHADER(FPopulateEditorDepthPS, "/Engine/Private/PostProcessCompositeEditorPrimitives.usf", "MainPopulateSceneDepthPS", SF_Pixel);
|
|
IMPLEMENT_GLOBAL_SHADER(FCompositeEditorPrimitivesPS, "/Engine/Private/PostProcessCompositeEditorPrimitives.usf", "MainCompositeEditorPrimitivesPS", SF_Pixel);
|
|
|
|
void RenderEditorPrimitives(FRHICommandListImmediate& RHICmdList, const FViewInfo& View, FMeshPassProcessorRenderState& DrawRenderState, FInstanceCullingManager& InstanceCullingManager)
|
|
{
|
|
// Always depth test against other editor primitives
|
|
DrawRenderState.SetDepthStencilState(TStaticDepthStencilState<
|
|
true, CF_DepthNearOrEqual,
|
|
true, CF_Always, SO_Keep, SO_Keep, SO_Replace,
|
|
false, CF_Always, SO_Keep, SO_Keep, SO_Keep,
|
|
0xFF, GET_STENCIL_BIT_MASK(RECEIVE_DECAL, 1) | STENCIL_LIGHTING_CHANNELS_MASK(0x7)>::GetRHI());
|
|
|
|
DrawDynamicMeshPass(View, RHICmdList,
|
|
[&View, &DrawRenderState](FDynamicPassMeshDrawListContext* DynamicMeshPassContext)
|
|
{
|
|
FEditorPrimitivesBasePassMeshProcessor PassMeshProcessor(
|
|
View.Family->Scene->GetRenderScene(),
|
|
View.GetFeatureLevel(),
|
|
&View,
|
|
DrawRenderState,
|
|
false,
|
|
DynamicMeshPassContext);
|
|
|
|
const uint64 DefaultBatchElementMask = ~0ull;
|
|
const int32 NumDynamicEditorMeshBatches = View.DynamicEditorMeshElements.Num();
|
|
|
|
for (int32 MeshIndex = 0; MeshIndex < NumDynamicEditorMeshBatches; MeshIndex++)
|
|
{
|
|
const FMeshBatchAndRelevance& MeshAndRelevance = View.DynamicEditorMeshElements[MeshIndex];
|
|
|
|
if (MeshAndRelevance.GetHasOpaqueOrMaskedMaterial() || View.Family->EngineShowFlags.Wireframe)
|
|
{
|
|
PassMeshProcessor.AddMeshBatch(*MeshAndRelevance.Mesh, DefaultBatchElementMask, MeshAndRelevance.PrimitiveSceneProxy);
|
|
}
|
|
}
|
|
|
|
for (int32 MeshIndex = 0; MeshIndex < View.ViewMeshElements.Num(); MeshIndex++)
|
|
{
|
|
const FMeshBatch& MeshBatch = View.ViewMeshElements[MeshIndex];
|
|
PassMeshProcessor.AddMeshBatch(MeshBatch, DefaultBatchElementMask, nullptr);
|
|
}
|
|
});
|
|
|
|
View.EditorSimpleElementCollector.DrawBatchedElements(RHICmdList, DrawRenderState, View, EBlendModeFilter::OpaqueAndMasked, SDPG_World);
|
|
|
|
const auto FeatureLevel = View.GetFeatureLevel();
|
|
const auto ShaderPlatform = GShaderPlatformForFeatureLevel[FeatureLevel];
|
|
const bool bNeedToSwitchVerticalAxis = RHINeedsToSwitchVerticalAxis(ShaderPlatform);
|
|
|
|
// Draw the view's batched simple elements(lines, sprites, etc).
|
|
View.BatchedViewElements.Draw(RHICmdList, DrawRenderState, FeatureLevel, bNeedToSwitchVerticalAxis, View, false, 1.0f);
|
|
}
|
|
|
|
void RenderForegroundEditorPrimitives(FRHICommandList& RHICmdList, const FViewInfo& View, FMeshPassProcessorRenderState& DrawRenderState, FInstanceCullingManager& InstanceCullingManager)
|
|
{
|
|
const auto FeatureLevel = View.GetFeatureLevel();
|
|
const auto ShaderPlatform = GShaderPlatformForFeatureLevel[FeatureLevel];
|
|
const bool bNeedToSwitchVerticalAxis = RHINeedsToSwitchVerticalAxis(ShaderPlatform);
|
|
|
|
// Draw a first time the foreground primitive without depth test to over right depth from non-foreground editor primitives.
|
|
{
|
|
DrawRenderState.SetDepthStencilState(TStaticDepthStencilState<true, CF_Always>::GetRHI());
|
|
|
|
View.EditorSimpleElementCollector.DrawBatchedElements(RHICmdList, DrawRenderState, View, EBlendModeFilter::OpaqueAndMasked, SDPG_Foreground);
|
|
|
|
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);
|
|
}
|
|
});
|
|
|
|
View.TopBatchedViewElements.Draw(RHICmdList, DrawRenderState, FeatureLevel, bNeedToSwitchVerticalAxis, View, false);
|
|
}
|
|
|
|
// Draw a second time the foreground primitive with depth test to have proper depth test between foreground primitives.
|
|
{
|
|
DrawRenderState.SetDepthStencilState(TStaticDepthStencilState<true, CF_DepthNearOrEqual>::GetRHI());
|
|
|
|
View.EditorSimpleElementCollector.DrawBatchedElements(RHICmdList, DrawRenderState, View, EBlendModeFilter::OpaqueAndMasked, SDPG_Foreground);
|
|
|
|
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);
|
|
}
|
|
});
|
|
|
|
View.TopBatchedViewElements.Draw(RHICmdList, DrawRenderState, FeatureLevel, bNeedToSwitchVerticalAxis, View, false);
|
|
}
|
|
}
|
|
|
|
} //! namespace
|
|
|
|
const FViewInfo* CreateEditorPrimitiveView(const FViewInfo& ParentView, FIntRect ViewRect, uint32 NumSamples)
|
|
{
|
|
FViewInfo* EditorView = ParentView.CreateSnapshot();
|
|
|
|
// Patch view rect.
|
|
EditorView->ViewRect = ViewRect;
|
|
|
|
// Override pre exposure to 1.0f, because rendering after tonemapper.
|
|
EditorView->PreExposure = 1.0f;
|
|
|
|
// Kills material texture mipbias because after TAA.
|
|
EditorView->MaterialTextureMipBias = 0.0f;
|
|
|
|
// Disable decals so that we don't do a SetDepthStencilState() in TMobileBasePassDrawingPolicy::SetupPipelineState()
|
|
EditorView->bSceneHasDecals = false;
|
|
|
|
if (IsTemporalAccumulationBasedMethod(EditorView->AntiAliasingMethod))
|
|
{
|
|
EditorView->ViewMatrices.HackRemoveTemporalAAProjectionJitter();
|
|
}
|
|
|
|
EditorView->InitRHIResources(NumSamples);
|
|
|
|
return EditorView;
|
|
}
|
|
|
|
BEGIN_SHADER_PARAMETER_STRUCT(FEditorPrimitivesPassParameters, )
|
|
SHADER_PARAMETER_STRUCT_INCLUDE(FViewShaderParameters, View)
|
|
SHADER_PARAMETER_STRUCT_REF(FReflectionCaptureShaderData, ReflectionCapture)
|
|
SHADER_PARAMETER_RDG_UNIFORM_BUFFER(FOpaqueBasePassUniformParameters, BasePass)
|
|
SHADER_PARAMETER_RDG_UNIFORM_BUFFER(FMobileBasePassUniformParameters, MobileBasePass)
|
|
SHADER_PARAMETER_RDG_UNIFORM_BUFFER(FInstanceCullingGlobalUniforms, InstanceCulling)
|
|
RENDER_TARGET_BINDING_SLOTS()
|
|
END_SHADER_PARAMETER_STRUCT()
|
|
|
|
FScreenPassTexture AddEditorPrimitivePass(
|
|
FRDGBuilder& GraphBuilder,
|
|
const FViewInfo& View,
|
|
const FEditorPrimitiveInputs& Inputs,
|
|
FInstanceCullingManager& InstanceCullingManager)
|
|
{
|
|
check(Inputs.SceneColor.IsValid());
|
|
check(Inputs.SceneDepth.IsValid());
|
|
check(Inputs.BasePassType != FEditorPrimitiveInputs::EBasePassType::MAX);
|
|
|
|
const FSceneTextures& SceneTextures = View.GetSceneTextures();
|
|
const uint32 NumSamples = SceneTextures.Config.EditorPrimitiveNumSamples;
|
|
const FViewInfo* EditorView = CreateEditorPrimitiveView(View, Inputs.SceneColor.ViewRect, NumSamples);
|
|
|
|
// Load the color target if it already exists.
|
|
const bool bProducedByPriorPass = HasBeenProduced(SceneTextures.EditorPrimitiveColor);
|
|
|
|
FRDGTextureRef EditorPrimitiveColor;
|
|
FRDGTextureRef EditorPrimitiveDepth;
|
|
if (bProducedByPriorPass)
|
|
{
|
|
ensureMsgf(
|
|
Inputs.SceneColor.ViewRect == Inputs.SceneDepth.ViewRect,
|
|
TEXT("Temporal upsampling should be disabled when drawing directly to EditorPrimitivesColor."));
|
|
EditorPrimitiveColor = SceneTextures.EditorPrimitiveColor;
|
|
EditorPrimitiveDepth = SceneTextures.EditorPrimitiveDepth;
|
|
}
|
|
else
|
|
{
|
|
const FSceneTexturesConfig& Config = SceneTextures.Config;
|
|
|
|
FIntPoint Extent = Inputs.SceneColor.Texture->Desc.Extent;
|
|
|
|
const FRDGTextureDesc ColorDesc = FRDGTextureDesc::Create2D(
|
|
Extent,
|
|
PF_B8G8R8A8,
|
|
FClearValueBinding::Transparent,
|
|
TexCreate_ShaderResource | TexCreate_RenderTargetable,
|
|
1,
|
|
Config.EditorPrimitiveNumSamples);
|
|
|
|
const FRDGTextureDesc DepthDesc = FRDGTextureDesc::Create2D(
|
|
Extent,
|
|
PF_DepthStencil,
|
|
FClearValueBinding::DepthFar,
|
|
TexCreate_ShaderResource | TexCreate_DepthStencilTargetable,
|
|
1,
|
|
Config.EditorPrimitiveNumSamples);
|
|
|
|
EditorPrimitiveColor = GraphBuilder.CreateTexture(ColorDesc, TEXT("Editor.PrimitivesColor"));
|
|
EditorPrimitiveDepth = GraphBuilder.CreateTexture(DepthDesc, TEXT("Editor.PrimitivesDepth"));
|
|
}
|
|
|
|
// Load the color target if it already exists.
|
|
const FScreenPassTextureViewport EditorPrimitivesViewport(EditorPrimitiveColor, Inputs.SceneColor.ViewRect);
|
|
|
|
RDG_GPU_STAT_SCOPE(GraphBuilder, EditorPrimitives);
|
|
RDG_EVENT_SCOPE(GraphBuilder, "CompositeEditorPrimitives %dx%d MSAA=%d",
|
|
EditorPrimitivesViewport.Rect.Width(),
|
|
EditorPrimitivesViewport.Rect.Height(),
|
|
NumSamples);
|
|
|
|
FScreenPassTexture SceneDepth = Inputs.SceneDepth;
|
|
FVector2f SceneDepthJitter = FVector2f(View.TemporalJitterPixels);
|
|
|
|
// The editor primitive composition pass is also used when rendering VMI_WIREFRAME in order to use MSAA.
|
|
// So we need to check whether the editor primitives are enabled inside this function.
|
|
if (View.Family->EngineShowFlags.CompositeEditorPrimitives)
|
|
{
|
|
// Populate depth if a prior pass did not already do it.
|
|
if (!bProducedByPriorPass)
|
|
{
|
|
// Upscale factor of the depth buffer that might be needed.
|
|
const float UpscaleFactor = float(EditorPrimitivesViewport.Rect.Width()) / float(Inputs.SceneDepth.ViewRect.Width());
|
|
|
|
// Upscale factor shouldn't be higher than there is TAA samples, or that means there will be unrendered pixels.
|
|
const int32 ComputeMaxUpsampleFactorDueToTAA = FMath::FloorToInt(FMath::Sqrt(float(View.TemporalJitterSequenceLength) / (UpscaleFactor * UpscaleFactor)));
|
|
|
|
const int32 ComputeMaxUpsampleFactor = FMath::Clamp(ComputeMaxUpsampleFactorDueToTAA, 0, 4);
|
|
|
|
const int32 DepthUpsampleFactor = FMath::Clamp(CVarEditorTemporalUpsampleDepth.GetValueOnRenderThread(), 0, ComputeMaxUpsampleFactor);
|
|
|
|
// Upsample the depth at higher resolution to reduce depth intersection instability of editor primitives.
|
|
if (DepthUpsampleFactor > 0 && View.ViewState && IsTemporalAccumulationBasedMethod(View.AntiAliasingMethod))
|
|
{
|
|
FScreenPassTexture History;
|
|
{
|
|
const FRDGTextureDesc Desc = FRDGTextureDesc::Create2D(
|
|
EditorPrimitivesViewport.Extent * DepthUpsampleFactor,
|
|
PF_R32_FLOAT,
|
|
FClearValueBinding::None,
|
|
TexCreate_ShaderResource | TexCreate_RenderTargetable);
|
|
|
|
History.Texture = GraphBuilder.CreateTexture(Desc, TEXT("Editor.PrimitivesDepthHistory"));
|
|
History.ViewRect = EditorPrimitivesViewport.Rect * DepthUpsampleFactor;
|
|
}
|
|
|
|
FTemporalUpsampleEditorDepthPS::FParameters* PassParameters = GraphBuilder.AllocParameters<FTemporalUpsampleEditorDepthPS::FParameters>();
|
|
PassParameters->View = View.ViewUniformBuffer;
|
|
PassParameters->Depth = GetScreenPassTextureViewportParameters(FScreenPassTextureViewport(Inputs.SceneDepth));
|
|
PassParameters->History = GetScreenPassTextureViewportParameters(FScreenPassTextureViewport(History));
|
|
PassParameters->DepthTextureJitter = FVector2f(View.TemporalJitterPixels);
|
|
|
|
PassParameters->DepthTexture = Inputs.SceneDepth.Texture;
|
|
PassParameters->DepthSampler = TStaticSamplerState<SF_Point, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();
|
|
|
|
// TODO
|
|
PassParameters->VelocityTexture = GraphBuilder.RegisterExternalTexture(GSystemTextures.BlackDummy);
|
|
PassParameters->VelocitySampler = TStaticSamplerState<SF_Point, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();
|
|
|
|
if (View.PrevViewInfo.EditorPrimtiveDepthHistory.IsValid())
|
|
{
|
|
PassParameters->PrevHistory = GetScreenPassTextureViewportParameters(FScreenPassTextureViewport(
|
|
View.PrevViewInfo.EditorPrimtiveDepthHistory.RT[0]->GetDesc().Extent, View.PrevViewInfo.EditorPrimtiveDepthHistory.ViewportRect));
|
|
PassParameters->PrevHistoryTexture = GraphBuilder.RegisterExternalTexture(View.PrevViewInfo.EditorPrimtiveDepthHistory.RT[0]);
|
|
PassParameters->PrevHistorySampler = TStaticSamplerState<SF_Bilinear, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();
|
|
PassParameters->bCameraCut = false;
|
|
}
|
|
else
|
|
{
|
|
PassParameters->PrevHistory = GetScreenPassTextureViewportParameters(FScreenPassTextureViewport(
|
|
FIntPoint(1, 1), FIntRect(FIntPoint(0, 0), FIntPoint(1, 1))));
|
|
PassParameters->PrevHistoryTexture = GraphBuilder.RegisterExternalTexture(GSystemTextures.BlackDummy);
|
|
PassParameters->PrevHistorySampler = TStaticSamplerState<SF_Point, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();
|
|
PassParameters->bCameraCut = true;
|
|
}
|
|
|
|
PassParameters->RenderTargets[0] = FRenderTargetBinding(History.Texture, ERenderTargetLoadAction::ENoAction);
|
|
|
|
TShaderMapRef<FTemporalUpsampleEditorDepthPS> PixelShader(View.ShaderMap);
|
|
FPixelShaderUtils::AddFullscreenPass(
|
|
GraphBuilder,
|
|
View.ShaderMap,
|
|
RDG_EVENT_NAME("TemporalUpsampleDepth %dx%d -> %dx%d",
|
|
Inputs.SceneDepth.ViewRect.Width(),
|
|
Inputs.SceneDepth.ViewRect.Height(),
|
|
History.ViewRect.Width(),
|
|
History.ViewRect.Height()),
|
|
PixelShader,
|
|
PassParameters,
|
|
History.ViewRect);
|
|
|
|
if (!View.bStatePrevViewInfoIsReadOnly)
|
|
{
|
|
FTemporalAAHistory* OutputHistory = &View.ViewState->PrevFrameViewInfo.EditorPrimtiveDepthHistory;
|
|
OutputHistory->SafeRelease();
|
|
|
|
GraphBuilder.QueueTextureExtraction(History.Texture, &OutputHistory->RT[0]);
|
|
OutputHistory->ViewportRect = History.ViewRect;
|
|
OutputHistory->ReferenceBufferSize = History.Texture->Desc.Extent;
|
|
}
|
|
|
|
SceneDepth = History;
|
|
SceneDepthJitter = FVector2f::ZeroVector;
|
|
}
|
|
|
|
// Populate the MSAA depth buffer from depth buffer or temporally upscaled depth buffer
|
|
{
|
|
FPopulateEditorDepthPS::FParameters* PassParameters = GraphBuilder.AllocParameters<FPopulateEditorDepthPS::FParameters>();
|
|
PassParameters->View = View.ViewUniformBuffer;
|
|
PassParameters->Color = GetScreenPassTextureViewportParameters(FScreenPassTextureViewport(Inputs.SceneColor));
|
|
PassParameters->Depth = GetScreenPassTextureViewportParameters(FScreenPassTextureViewport(SceneDepth));
|
|
PassParameters->DepthTextureJitter = SceneDepthJitter;
|
|
PassParameters->DepthTexture = SceneDepth.Texture;
|
|
PassParameters->DepthSampler = TStaticSamplerState<SF_Point, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();
|
|
PassParameters->RenderTargets[0] = FRenderTargetBinding(EditorPrimitiveColor, ERenderTargetLoadAction::EClear);
|
|
PassParameters->RenderTargets.DepthStencil = FDepthStencilBinding(EditorPrimitiveDepth, ERenderTargetLoadAction::EClear, ERenderTargetLoadAction::EClear, FExclusiveDepthStencil::DepthWrite_StencilWrite);
|
|
|
|
FPopulateEditorDepthPS::FPermutationDomain PermutationVector;
|
|
PermutationVector.Set<FPopulateEditorDepthPS::FUseMSAADimension>(NumSamples > 1);
|
|
TShaderMapRef<FPopulateEditorDepthPS> PixelShader(View.ShaderMap, PermutationVector);
|
|
|
|
FPixelShaderUtils::AddFullscreenPass(
|
|
GraphBuilder,
|
|
View.ShaderMap,
|
|
RDG_EVENT_NAME("PopulateDepth %dx%d%s",
|
|
EditorPrimitivesViewport.Rect.Width(),
|
|
EditorPrimitivesViewport.Rect.Height(),
|
|
NumSamples > 1 ? TEXT(" MSAA") : TEXT("")),
|
|
PixelShader,
|
|
PassParameters,
|
|
EditorPrimitivesViewport.Rect,
|
|
/* BlendState = */ nullptr,
|
|
/* RasterizerState = */ nullptr,
|
|
TStaticDepthStencilState<true, CF_Always>::GetRHI());
|
|
}
|
|
}
|
|
|
|
// Draws the editors primitives
|
|
{
|
|
FEditorPrimitivesPassParameters* PassParameters = GraphBuilder.AllocParameters<FEditorPrimitivesPassParameters>();
|
|
PassParameters->View = EditorView->GetShaderParameters();
|
|
PassParameters->ReflectionCapture = View.ReflectionCaptureUniformBuffer;
|
|
PassParameters->InstanceCulling = InstanceCullingManager.GetDummyInstanceCullingUniformBuffer();
|
|
PassParameters->RenderTargets[0] = FRenderTargetBinding(EditorPrimitiveColor, ERenderTargetLoadAction::ELoad);
|
|
PassParameters->RenderTargets.DepthStencil = FDepthStencilBinding(EditorPrimitiveDepth, ERenderTargetLoadAction::ELoad, ERenderTargetLoadAction::ELoad, FExclusiveDepthStencil::DepthWrite_StencilWrite);
|
|
|
|
const FEditorPrimitiveInputs::EBasePassType BasePassType = Inputs.BasePassType;
|
|
|
|
if (BasePassType == FEditorPrimitiveInputs::EBasePassType::Deferred)
|
|
{
|
|
PassParameters->BasePass = CreateOpaqueBasePassUniformBuffer(GraphBuilder, *EditorView, 0);
|
|
}
|
|
else
|
|
{
|
|
PassParameters->MobileBasePass = CreateMobileBasePassUniformBuffer(GraphBuilder, *EditorView, EMobileBasePass::Translucent, EMobileSceneTextureSetupMode::None);
|
|
}
|
|
|
|
GraphBuilder.AddPass(
|
|
RDG_EVENT_NAME("EditorPrimitives %dx%d MSAA=%d",
|
|
EditorPrimitivesViewport.Rect.Width(),
|
|
EditorPrimitivesViewport.Rect.Height(),
|
|
NumSamples),
|
|
PassParameters,
|
|
ERDGPassFlags::Raster,
|
|
[&View, &InstanceCullingManager, PassParameters, EditorView, EditorPrimitivesViewport, BasePassType, NumSamples](FRHICommandListImmediate& RHICmdList)
|
|
{
|
|
RHICmdList.SetViewport(EditorPrimitivesViewport.Rect.Min.X, EditorPrimitivesViewport.Rect.Min.Y, 0.0f, EditorPrimitivesViewport.Rect.Max.X, EditorPrimitivesViewport.Rect.Max.Y, 1.0f);
|
|
|
|
FMeshPassProcessorRenderState DrawRenderState;
|
|
DrawRenderState.SetDepthStencilAccess(FExclusiveDepthStencil::DepthWrite_StencilWrite);
|
|
DrawRenderState.SetBlendState(TStaticBlendStateWriteMask<CW_RGBA>::GetRHI());
|
|
|
|
// Draw editor primitives.
|
|
{
|
|
SCOPED_DRAW_EVENTF(RHICmdList, EditorPrimitives,
|
|
TEXT("RenderViewEditorPrimitives %dx%d msaa=%d"),
|
|
EditorPrimitivesViewport.Rect.Width(), EditorPrimitivesViewport.Rect.Height(), NumSamples);
|
|
|
|
RenderEditorPrimitives(RHICmdList, *EditorView, DrawRenderState, InstanceCullingManager);
|
|
}
|
|
|
|
// Draw foreground editor primitives.
|
|
{
|
|
SCOPED_DRAW_EVENTF(RHICmdList, EditorPrimitives,
|
|
TEXT("RenderViewEditorForegroundPrimitives %dx%d msaa=%d"),
|
|
EditorPrimitivesViewport.Rect.Width(), EditorPrimitivesViewport.Rect.Height(), NumSamples);
|
|
|
|
RenderForegroundEditorPrimitives(RHICmdList, *EditorView, DrawRenderState, InstanceCullingManager);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
FScreenPassRenderTarget Output = Inputs.OverrideOutput;
|
|
|
|
if (!Output.IsValid())
|
|
{
|
|
Output = FScreenPassRenderTarget::CreateFromInput(GraphBuilder, Inputs.SceneColor, View.GetOverwriteLoadAction(), TEXT("Editor.Primitives"));
|
|
}
|
|
|
|
{
|
|
FRHISamplerState* PointClampSampler = TStaticSamplerState<SF_Point, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();
|
|
|
|
const bool bOpaqueEditorGizmo = View.Family->EngineShowFlags.OpaqueCompositeEditorPrimitives || View.Family->EngineShowFlags.Wireframe;
|
|
|
|
FCompositeEditorPrimitivesPS::FParameters* PassParameters = GraphBuilder.AllocParameters<FCompositeEditorPrimitivesPS::FParameters>();
|
|
PassParameters->RenderTargets[0] = Output.GetRenderTargetBinding();
|
|
PassParameters->View = View.ViewUniformBuffer;
|
|
PassParameters->Color = GetScreenPassTextureViewportParameters(FScreenPassTextureViewport(Inputs.SceneColor));
|
|
PassParameters->Depth = GetScreenPassTextureViewportParameters(FScreenPassTextureViewport(SceneDepth));
|
|
PassParameters->Output = GetScreenPassTextureViewportParameters(FScreenPassTextureViewport(Output));
|
|
PassParameters->ColorTexture = Inputs.SceneColor.Texture;
|
|
PassParameters->ColorSampler = PointClampSampler;
|
|
PassParameters->DepthTexture = SceneDepth.Texture;
|
|
PassParameters->DepthSampler = PointClampSampler;
|
|
PassParameters->EditorPrimitivesDepth = EditorPrimitiveDepth;
|
|
PassParameters->EditorPrimitivesColor = EditorPrimitiveColor;
|
|
PassParameters->bOpaqueEditorGizmo = bOpaqueEditorGizmo;
|
|
PassParameters->bCompositeAnyNonNullDepth = bProducedByPriorPass;
|
|
PassParameters->DepthTextureJitter = SceneDepthJitter;
|
|
|
|
for (int32 i = 0; i < int32(NumSamples); i++)
|
|
{
|
|
PassParameters->SampleOffsetArray[i].X = GetMSAASampleOffsets(NumSamples, i).X;
|
|
PassParameters->SampleOffsetArray[i].Y = GetMSAASampleOffsets(NumSamples, i).Y;
|
|
}
|
|
|
|
FCompositeEditorPrimitivesPS::FPermutationDomain PermutationVector;
|
|
PermutationVector.Set<FCompositeEditorPrimitivesPS::FSampleCountDimension>(NumSamples);
|
|
|
|
TShaderMapRef<FCompositeEditorPrimitivesPS> PixelShader(View.ShaderMap, PermutationVector);
|
|
FPixelShaderUtils::AddFullscreenPass(
|
|
GraphBuilder,
|
|
View.ShaderMap,
|
|
RDG_EVENT_NAME("Composite %dx%d MSAA=%d", Output.ViewRect.Width(), Output.ViewRect.Height(), NumSamples),
|
|
PixelShader,
|
|
PassParameters,
|
|
Output.ViewRect);
|
|
}
|
|
|
|
return MoveTemp(Output);
|
|
}
|
|
|
|
#endif |