Files
UnrealEngineUWP/Engine/Source/Runtime/Renderer/Private/PostProcess/PostProcessVisualizeLevelInstance.cpp
roey borsteinas f41d79e4f5 Visualize Level Instance editing
Applies a post processing effect to all actors which do not belong to the currently editing LevelInstance. Can be toggled with the Viewport show options under visualization.

#rb patrick.enfedaque graham.wihlidal jeremy.moore
#jira none

#ROBOMERGE-OWNER: roey.borsteinas
#ROBOMERGE-AUTHOR: roey.borsteinas
#ROBOMERGE-SOURCE: CL 14322972 in //UE5/Release-5.0-M2/...
#ROBOMERGE-BOT: STARSHIP (Release-5.0-M2 -> Main) (v738-14305781)

[CL 14323217 by roey borsteinas in ue5-main branch]
2020-09-15 17:20:22 -04:00

208 lines
8.8 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#if WITH_EDITOR
#include "PostProcess/PostProcessVisualizeLevelInstance.h"
#include "PostProcess/PostProcessCompositeEditorPrimitives.h"
#include "SceneTextureParameters.h"
#include "CanvasTypes.h"
#include "RenderTargetTemp.h"
#include "ClearQuad.h"
namespace
{
class FVisualizeLevelInstancePS : public FEditorPrimitiveShader
{
public:
DECLARE_GLOBAL_SHADER(FVisualizeLevelInstancePS);
SHADER_USE_PARAMETER_STRUCT(FVisualizeLevelInstancePS, 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(FScreenPassTextureViewportTransform, ColorToDepth)
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, ColorTexture)
SHADER_PARAMETER_SAMPLER(SamplerState, ColorSampler)
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, DepthTexture)
SHADER_PARAMETER_SAMPLER(SamplerState, DepthSampler)
SHADER_PARAMETER_RDG_TEXTURE(Texture2D, EditorPrimitivesDepth)
SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D, EditorPrimitivesStencil)
RENDER_TARGET_BINDING_SLOTS()
END_SHADER_PARAMETER_STRUCT()
};
IMPLEMENT_GLOBAL_SHADER(FVisualizeLevelInstancePS, "/Engine/Private/PostProcessVisualizeLevelInstance.usf", "MainPS", SF_Pixel);
} //! namespace
FScreenPassTexture AddVisualizeLevelInstancePass(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FVisualizeLevelInstanceInputs& Inputs, const Nanite::FRasterResults *NaniteRasterResults)
{
check(Inputs.SceneColor.IsValid());
check(Inputs.SceneDepth.IsValid());
const bool bNaniteEnabled = DoesPlatformSupportNanite(GMaxRHIShaderPlatform); // TODO: Respect r.Nanite
RDG_EVENT_SCOPE(GraphBuilder, "EditorVisualizeLevelInstance");
uint32 MsaaSampleCount = 0;
// Patch uniform buffers with updated state for rendering the outline mesh draw commands.
{
FScene* Scene = View.Family->Scene->GetRenderScene();
FSceneRenderTargets& SceneContext = FSceneRenderTargets::Get(GraphBuilder.RHICmdList);
MsaaSampleCount = SceneContext.GetEditorMSAACompositingSampleCount();
UpdateEditorPrimitiveView(Scene->UniformBuffers, SceneContext, View, Inputs.SceneColor.ViewRect);
FSceneTexturesUniformParameters SceneTextureParameters;
SetupSceneTextureUniformParameters(SceneContext, View.FeatureLevel, ESceneTextureSetupMode::None, SceneTextureParameters);
Scene->UniformBuffers.EditorVisualizeLevelInstancePassUniformBuffer.UpdateUniformBufferImmediate(SceneTextureParameters);
}
FRDGTextureRef DepthStencilTexture = nullptr;
// Generate custom depth / stencil for outline shapes.
{
{
FRDGTextureDesc DepthStencilDesc = Inputs.SceneColor.Texture->Desc;
DepthStencilDesc.Reset();
DepthStencilDesc.Format = PF_DepthStencil;
DepthStencilDesc.Flags = TexCreate_None;
// This is a reversed Z depth surface, so 0.0f is the far plane.
DepthStencilDesc.ClearValue = FClearValueBinding((float)ERHIZBuffer::FarPlane, 0);
// Mark targetable as TexCreate_ShaderResource because we actually do want to sample from the unresolved MSAA target in this case.
DepthStencilDesc.TargetableFlags = TexCreate_DepthStencilTargetable | TexCreate_ShaderResource;
DepthStencilDesc.NumSamples = MsaaSampleCount;
DepthStencilDesc.bForceSharedTargetAndShaderResource = true;
DepthStencilTexture = GraphBuilder.CreateTexture(DepthStencilDesc, TEXT("LevelInstanceDepth"));
}
FScene* Scene = View.Family->Scene->GetRenderScene();
const FScreenPassTextureViewport SceneColorViewport(Inputs.SceneColor);
auto* PassParameters = GraphBuilder.AllocParameters<FNaniteVisualizeLevelInstanceParameters>();
if (bNaniteEnabled)
{
Nanite::GetEditorVisualizeLevelInstancePassParameters(GraphBuilder, *Scene, View, SceneColorViewport.Rect, NaniteRasterResults, PassParameters);
}
PassParameters->RenderTargets.DepthStencil = FDepthStencilBinding(
DepthStencilTexture,
ERenderTargetLoadAction::EClear,
ERenderTargetLoadAction::EClear,
FExclusiveDepthStencil::DepthWrite_StencilWrite);
GraphBuilder.AddPass(
RDG_EVENT_NAME("LevelInstanceDepth %dx%d", SceneColorViewport.Rect.Width(), SceneColorViewport.Rect.Height()),
PassParameters,
ERDGPassFlags::Raster,
[&View, SceneColorViewport, DepthStencilTexture, NaniteRasterResults, PassParameters, bNaniteEnabled](FRHICommandListImmediate& RHICmdList)
{
RHICmdList.SetViewport(SceneColorViewport.Rect.Min.X, SceneColorViewport.Rect.Min.Y, 0.0f, SceneColorViewport.Rect.Max.X, SceneColorViewport.Rect.Max.Y, 1.0f);
{
SCOPED_DRAW_EVENT(RHICmdList, EditorLevelInstance);
// Run LevelInstance pass on static elements
View.ParallelMeshDrawCommandPasses[EMeshPass::EditorLevelInstance].DispatchDraw(nullptr, RHICmdList);
}
// Render Nanite mesh outlines after regular meshes
if (bNaniteEnabled)
{
Nanite::DrawEditorVisualizeLevelInstance(RHICmdList, View, SceneColorViewport.Rect, *PassParameters);
}
});
}
FScreenPassRenderTarget Output = Inputs.OverrideOutput;
if (!Output.IsValid())
{
Output = FScreenPassRenderTarget::CreateFromInput(GraphBuilder, Inputs.SceneColor, View.GetOverwriteLoadAction(), TEXT("LevelInstanceColor"));
}
// Render grey-post process effect.
{
const FScreenPassTextureViewport OutputViewport(Output);
const FScreenPassTextureViewport ColorViewport(Inputs.SceneColor);
const FScreenPassTextureViewport DepthViewport(Inputs.SceneDepth);
FRHISamplerState* PointClampSampler = TStaticSamplerState<SF_Point, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();
FVisualizeLevelInstancePS::FParameters* PassParameters = GraphBuilder.AllocParameters<FVisualizeLevelInstancePS::FParameters>();
PassParameters->RenderTargets[0] = Output.GetRenderTargetBinding();
PassParameters->View = View.ViewUniformBuffer;
PassParameters->Color = GetScreenPassTextureViewportParameters(ColorViewport);
PassParameters->Depth = GetScreenPassTextureViewportParameters(DepthViewport);
PassParameters->ColorToDepth = GetScreenPassTextureViewportTransform(PassParameters->Color, PassParameters->Depth);
PassParameters->ColorTexture = Inputs.SceneColor.Texture;
PassParameters->ColorSampler = PointClampSampler;
PassParameters->DepthTexture = Inputs.SceneDepth.Texture;
PassParameters->DepthSampler = PointClampSampler;
PassParameters->EditorPrimitivesDepth = DepthStencilTexture;
PassParameters->EditorPrimitivesStencil = GraphBuilder.CreateSRV(FRDGTextureSRVDesc::CreateWithPixelFormat(DepthStencilTexture, PF_X24_G8));
FVisualizeLevelInstancePS::FPermutationDomain PermutationVector;
PermutationVector.Set<FVisualizeLevelInstancePS::FSampleCountDimension>(MsaaSampleCount);
TShaderMapRef<FVisualizeLevelInstancePS> PixelShader(View.ShaderMap, PermutationVector);
AddDrawScreenPass(
GraphBuilder,
RDG_EVENT_NAME("LevelInstanceColor %dx%d", OutputViewport.Rect.Width(), OutputViewport.Rect.Height()),
View,
OutputViewport,
ColorViewport,
PixelShader,
PassParameters);
}
return MoveTemp(Output);
}
FRenderingCompositeOutputRef AddVisualizeLevelInstancePass(FRenderingCompositionGraph& Graph, FRenderingCompositeOutputRef Input, const Nanite::FRasterResults *NaniteRasterResults)
{
FRenderingCompositePass* Pass = Graph.RegisterPass(
new(FMemStack::Get()) TRCPassForRDG<1, 1>(
[NaniteRasterResults](FRenderingCompositePass* InPass, FRenderingCompositePassContext& InContext)
{
FRDGBuilder GraphBuilder(InContext.RHICmdList);
FRDGTextureRef SceneColorTexture = InPass->CreateRDGTextureForRequiredInput(GraphBuilder, ePId_Input0, TEXT("SceneColor"));
const FIntRect SceneColorViewRect = InContext.GetSceneColorDestRect(InPass);
const FSceneRenderTargets& SceneContext = FSceneRenderTargets::Get(GraphBuilder.RHICmdList);
FRDGTextureRef SceneDepthTexture = GraphBuilder.RegisterExternalTexture(SceneContext.SceneDepthZ, TEXT("SceneDepthZ"));
FVisualizeLevelInstanceInputs Inputs;
Inputs.SceneColor.Texture = SceneColorTexture;
Inputs.SceneColor.ViewRect = SceneColorViewRect;
Inputs.SceneDepth.Texture = SceneDepthTexture;
Inputs.SceneDepth.ViewRect = InContext.View.ViewRect;
if (FRDGTextureRef OutputTexture = InPass->FindRDGTextureForOutput(GraphBuilder, ePId_Output0, TEXT("BackBuffer")))
{
Inputs.OverrideOutput.Texture = OutputTexture;
Inputs.OverrideOutput.ViewRect = InContext.GetSceneColorDestRect(InPass->GetOutput(ePId_Output0)->PooledRenderTarget->GetRenderTargetItem());
Inputs.OverrideOutput.LoadAction = InContext.View.IsFirstInFamily() ? ERenderTargetLoadAction::EClear : ERenderTargetLoadAction::ELoad;
}
FScreenPassTexture Outputs = AddVisualizeLevelInstancePass(GraphBuilder, InContext.View, Inputs, NaniteRasterResults);
InPass->ExtractRDGTextureForOutput(GraphBuilder, ePId_Output0, Outputs.Texture);
GraphBuilder.Execute();
}));
Pass->SetInput(ePId_Input0, Input);
return Pass;
}
#endif