Files
UnrealEngineUWP/Engine/Source/Runtime/Renderer/Private/PostProcess/PostProcessVisualizeLevelInstance.cpp

168 lines
6.9 KiB
C++
Raw Normal View History

// Copyright Epic Games, Inc. All Rights Reserved.
#if WITH_EDITOR
#include "PostProcess/PostProcessVisualizeLevelInstance.h"
Moved rendering the debug draw helper execution to after post process pass to avoid ghosting of TAA/TSR/MB. The EditorPrimitives compositing code was the only PostProcess pass that composited appropriately, but was not setup to accept non-editor draws. DrawDebug also needs to be available to Debug and Development builds, so moving the debug draw calls to this pass directly was not straight forward, and there was no other existing option. SimpleElement draws used by debug were also non-trivial to setup with velocity to compensate for Temporal/Blur passes, so fixing this in the base pass was also not straight forward. Then an additional issue was that the color and depth textures used in post process after temporal passes were mismatched in size (as depth is not necessarily automatically included in the temporal upscale pass). However EditorPrimitives had hard coded temporal upsample depth code in it's main AddEditorPrimitivesPass function. Refactored PostProcessEditorPrimitives code to move the hard coded temporal upscale depth pass to a common file which is protected by UE_ENABLE_DEBUG_DRAWING (which is blocked from compiling in shipping, and works with editor). Also ensured the relevant shader compiles remain protected by these macros. The temporal and populate functions have been slightly rewritten so that a generic temporal history is created rather than an editor only one, and also populate depth can now also output the background colour (to reduce unnecessary draw calls as, depending on the setup, the previous scene may still needs to be drawn to the output color texture). After that refactor, there is a new set of draw debug composite files which now also use the temporal upsample depth code (when color and depth are mismatched, ignored if not), now that it has been isolated into it's own re-usable structure. This means that we can use a simple draw elements call, stripped of all shader variables except the view, to overlay the draw debug primitives on the scene color along with upscaled depth. Also moved draw debug to it's own SimpleElement array in the View to avoid conflating it with other simple element draws (e.g. non-opaque, or ones setup in plugins). This code can be extended for those at a later date if needed though. #jira UE-177222 #rb Jason.Nadro, Massimo.Tristano #preflight 64189a2a3f3d31c94aa0c48d #fyi Guillaume.Abadie [CL 24731449 by Jon Cain in ue5-main branch]
2023-03-21 09:56:41 -04:00
#include "PostProcess/PostProcessCompositePrimitivesCommon.h"
#include "SceneRendering.h"
#include "SceneTextureParameters.h"
#include "CanvasTypes.h"
#include "ClearQuad.h"
#include "ScenePrivate.h"
namespace
{
Moved rendering the debug draw helper execution to after post process pass to avoid ghosting of TAA/TSR/MB. The EditorPrimitives compositing code was the only PostProcess pass that composited appropriately, but was not setup to accept non-editor draws. DrawDebug also needs to be available to Debug and Development builds, so moving the debug draw calls to this pass directly was not straight forward, and there was no other existing option. SimpleElement draws used by debug were also non-trivial to setup with velocity to compensate for Temporal/Blur passes, so fixing this in the base pass was also not straight forward. Then an additional issue was that the color and depth textures used in post process after temporal passes were mismatched in size (as depth is not necessarily automatically included in the temporal upscale pass). However EditorPrimitives had hard coded temporal upsample depth code in it's main AddEditorPrimitivesPass function. Refactored PostProcessEditorPrimitives code to move the hard coded temporal upscale depth pass to a common file which is protected by UE_ENABLE_DEBUG_DRAWING (which is blocked from compiling in shipping, and works with editor). Also ensured the relevant shader compiles remain protected by these macros. The temporal and populate functions have been slightly rewritten so that a generic temporal history is created rather than an editor only one, and also populate depth can now also output the background colour (to reduce unnecessary draw calls as, depending on the setup, the previous scene may still needs to be drawn to the output color texture). After that refactor, there is a new set of draw debug composite files which now also use the temporal upsample depth code (when color and depth are mismatched, ignored if not), now that it has been isolated into it's own re-usable structure. This means that we can use a simple draw elements call, stripped of all shader variables except the view, to overlay the draw debug primitives on the scene color along with upscaled depth. Also moved draw debug to it's own SimpleElement array in the View to avoid conflating it with other simple element draws (e.g. non-opaque, or ones setup in plugins). This code can be extended for those at a later date if needed though. #jira UE-177222 #rb Jason.Nadro, Massimo.Tristano #preflight 64189a2a3f3d31c94aa0c48d #fyi Guillaume.Abadie [CL 24731449 by Jon Cain in ue5-main branch]
2023-03-21 09:56:41 -04:00
class FVisualizeLevelInstancePS : public FCompositePrimitiveShaderBase
{
public:
DECLARE_GLOBAL_SHADER(FVisualizeLevelInstancePS);
Moved rendering the debug draw helper execution to after post process pass to avoid ghosting of TAA/TSR/MB. The EditorPrimitives compositing code was the only PostProcess pass that composited appropriately, but was not setup to accept non-editor draws. DrawDebug also needs to be available to Debug and Development builds, so moving the debug draw calls to this pass directly was not straight forward, and there was no other existing option. SimpleElement draws used by debug were also non-trivial to setup with velocity to compensate for Temporal/Blur passes, so fixing this in the base pass was also not straight forward. Then an additional issue was that the color and depth textures used in post process after temporal passes were mismatched in size (as depth is not necessarily automatically included in the temporal upscale pass). However EditorPrimitives had hard coded temporal upsample depth code in it's main AddEditorPrimitivesPass function. Refactored PostProcessEditorPrimitives code to move the hard coded temporal upscale depth pass to a common file which is protected by UE_ENABLE_DEBUG_DRAWING (which is blocked from compiling in shipping, and works with editor). Also ensured the relevant shader compiles remain protected by these macros. The temporal and populate functions have been slightly rewritten so that a generic temporal history is created rather than an editor only one, and also populate depth can now also output the background colour (to reduce unnecessary draw calls as, depending on the setup, the previous scene may still needs to be drawn to the output color texture). After that refactor, there is a new set of draw debug composite files which now also use the temporal upsample depth code (when color and depth are mismatched, ignored if not), now that it has been isolated into it's own re-usable structure. This means that we can use a simple draw elements call, stripped of all shader variables except the view, to overlay the draw debug primitives on the scene color along with upscaled depth. Also moved draw debug to it's own SimpleElement array in the View to avoid conflating it with other simple element draws (e.g. non-opaque, or ones setup in plugins). This code can be extended for those at a later date if needed though. #jira UE-177222 #rb Jason.Nadro, Massimo.Tristano #preflight 64189a2a3f3d31c94aa0c48d #fyi Guillaume.Abadie [CL 24731449 by Jon Cain in ue5-main branch]
2023-03-21 09:56:41 -04:00
SHADER_USE_PARAMETER_STRUCT(FVisualizeLevelInstancePS, FCompositePrimitiveShaderBase);
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
SHADER_PARAMETER_STRUCT_REF(FViewUniformShaderParameters, View)
SHADER_PARAMETER_STRUCT(FScreenPassTextureViewportParameters, Color)
SHADER_PARAMETER_STRUCT(FScreenPassTextureViewportParameters, Depth)
SHADER_PARAMETER(FScreenTransform, 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
BEGIN_SHADER_PARAMETER_STRUCT(FVisualizeLevelInstancePassParameters, )
SHADER_PARAMETER_STRUCT_REF(FViewUniformShaderParameters, View)
SHADER_PARAMETER_STRUCT_INCLUDE(FSceneTextureShaderParameters, SceneTextures)
SHADER_PARAMETER_STRUCT_INCLUDE(FInstanceCullingDrawParams, InstanceCullingDrawParams)
RENDER_TARGET_BINDING_SLOTS()
END_SHADER_PARAMETER_STRUCT()
FScreenPassTexture AddVisualizeLevelInstancePass(
FRDGBuilder& GraphBuilder,
const FViewInfo& View,
FSceneUniformBuffer &SceneUniformBuffer,
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");
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
const uint32 NumSamples = View.GetSceneTexturesConfig().NumSamples;
// Patch uniform buffers with updated state for rendering the outline mesh draw commands.
Moved rendering the debug draw helper execution to after post process pass to avoid ghosting of TAA/TSR/MB. The EditorPrimitives compositing code was the only PostProcess pass that composited appropriately, but was not setup to accept non-editor draws. DrawDebug also needs to be available to Debug and Development builds, so moving the debug draw calls to this pass directly was not straight forward, and there was no other existing option. SimpleElement draws used by debug were also non-trivial to setup with velocity to compensate for Temporal/Blur passes, so fixing this in the base pass was also not straight forward. Then an additional issue was that the color and depth textures used in post process after temporal passes were mismatched in size (as depth is not necessarily automatically included in the temporal upscale pass). However EditorPrimitives had hard coded temporal upsample depth code in it's main AddEditorPrimitivesPass function. Refactored PostProcessEditorPrimitives code to move the hard coded temporal upscale depth pass to a common file which is protected by UE_ENABLE_DEBUG_DRAWING (which is blocked from compiling in shipping, and works with editor). Also ensured the relevant shader compiles remain protected by these macros. The temporal and populate functions have been slightly rewritten so that a generic temporal history is created rather than an editor only one, and also populate depth can now also output the background colour (to reduce unnecessary draw calls as, depending on the setup, the previous scene may still needs to be drawn to the output color texture). After that refactor, there is a new set of draw debug composite files which now also use the temporal upsample depth code (when color and depth are mismatched, ignored if not), now that it has been isolated into it's own re-usable structure. This means that we can use a simple draw elements call, stripped of all shader variables except the view, to overlay the draw debug primitives on the scene color along with upscaled depth. Also moved draw debug to it's own SimpleElement array in the View to avoid conflating it with other simple element draws (e.g. non-opaque, or ones setup in plugins). This code can be extended for those at a later date if needed though. #jira UE-177222 #rb Jason.Nadro, Massimo.Tristano #preflight 64189a2a3f3d31c94aa0c48d #fyi Guillaume.Abadie [CL 24731449 by Jon Cain in ue5-main branch]
2023-03-21 09:56:41 -04:00
const FViewInfo* EditorView = CreateCompositePrimitiveView(View, Inputs.SceneColor.ViewRect, NumSamples);
FRDGTextureRef DepthStencilTexture = nullptr;
// Generate custom depth / stencil for outline shapes.
{
const FScreenPassTextureViewport SceneColorViewport(Inputs.SceneColor);
RDG_EVENT_SCOPE(GraphBuilder, "LevelInstanceDepth %dx%d", SceneColorViewport.Rect.Width(), SceneColorViewport.Rect.Height());
FScene* Scene = View.Family->Scene->GetRenderScene();
{
FRDGTextureDesc DepthStencilDesc = Inputs.SceneColor.Texture->Desc;
DepthStencilDesc.Reset();
DepthStencilDesc.Format = PF_DepthStencil;
// This is a reversed Z depth surface, so 0.0f is the far plane.
DepthStencilDesc.ClearValue = FClearValueBinding((float)ERHIZBuffer::FarPlane, 0);
DepthStencilDesc.Flags = TexCreate_DepthStencilTargetable | TexCreate_ShaderResource;
DepthStencilDesc.NumSamples = NumSamples;
DepthStencilTexture = GraphBuilder.CreateTexture(DepthStencilDesc, TEXT("LevelInstanceDepth"));
}
{
auto* PassParameters = GraphBuilder.AllocParameters<FVisualizeLevelInstancePassParameters>();
PassParameters->View = EditorView->ViewUniformBuffer;
PassParameters->SceneTextures = Inputs.SceneTextures;
PassParameters->RenderTargets.DepthStencil = FDepthStencilBinding(
DepthStencilTexture,
ERenderTargetLoadAction::EClear,
ERenderTargetLoadAction::EClear,
FExclusiveDepthStencil::DepthWrite_StencilWrite);
const_cast<FViewInfo&>(View).ParallelMeshDrawCommandPasses[EMeshPass::EditorLevelInstance].BuildRenderingCommands(GraphBuilder, Scene->GPUScene, PassParameters->InstanceCullingDrawParams);
GraphBuilder.AddPass(
RDG_EVENT_NAME("EditorLevelInstance"),
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);
// Run LevelInstance pass on static elements
View.ParallelMeshDrawCommandPasses[EMeshPass::EditorLevelInstance].DispatchDraw(nullptr, RHICmdList, &PassParameters->InstanceCullingDrawParams);
}
);
}
if (bNaniteEnabled)
{
Nanite::DrawEditorVisualizeLevelInstance(GraphBuilder, DepthStencilTexture, *Scene, View, *EditorView, SceneUniformBuffer, NaniteRasterResults);
}
}
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();
FRHISamplerState* BilinearClampSampler = TStaticSamplerState<SF_Bilinear, 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 = FScreenTransform::ChangeTextureUVCoordinateFromTo(ColorViewport, DepthViewport);
PassParameters->ColorTexture = Inputs.SceneColor.Texture;
PassParameters->ColorSampler = PointClampSampler;
PassParameters->DepthTexture = Inputs.SceneDepth.Texture;
PassParameters->DepthSampler = BilinearClampSampler;
PassParameters->EditorPrimitivesDepth = DepthStencilTexture;
PassParameters->EditorPrimitivesStencil = GraphBuilder.CreateSRV(FRDGTextureSRVDesc::CreateWithPixelFormat(DepthStencilTexture, PF_X24_G8));
FVisualizeLevelInstancePS::FPermutationDomain PermutationVector;
PermutationVector.Set<FVisualizeLevelInstancePS::FSampleCountDimension>(NumSamples);
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);
}
#endif