From b09b4d241961f741bdfa40bdac90a6eb836c78a9 Mon Sep 17 00:00:00 2001 From: SirLynix Date: Sun, 8 Oct 2023 23:44:24 +0200 Subject: [PATCH] Graphics: Add a way to set which passes are enabled in a frame pipeline This will be replaced soon with a better system --- examples/PhysicallyBasedRendering/main.cpp | 2 +- include/Nazara/Graphics/Camera.hpp | 4 +++ include/Nazara/Graphics/Camera.inl | 24 +++++++++++++++++ include/Nazara/Graphics/Enums.hpp | 18 +++++++++++++ .../Nazara/Graphics/ForwardFramePipeline.hpp | 3 ++- include/Nazara/Graphics/FramePipeline.hpp | 2 +- src/Nazara/Graphics/ForwardFramePipeline.cpp | 27 +++++++++++++------ src/Nazara/Graphics/Systems/RenderSystem.cpp | 2 +- tests/GraphicsTest/main.cpp | 2 +- 9 files changed, 71 insertions(+), 13 deletions(-) diff --git a/examples/PhysicallyBasedRendering/main.cpp b/examples/PhysicallyBasedRendering/main.cpp index 880e4a158..5482e87d6 100644 --- a/examples/PhysicallyBasedRendering/main.cpp +++ b/examples/PhysicallyBasedRendering/main.cpp @@ -75,7 +75,7 @@ int main(int argc, char* argv[]) Nz::ElementRendererRegistry elementRegistry; Nz::ForwardFramePipeline framePipeline(elementRegistry); - [[maybe_unused]] std::size_t cameraIndex = framePipeline.RegisterViewer(&camera, 0); + [[maybe_unused]] std::size_t cameraIndex = framePipeline.RegisterViewer(&camera, 0, Nz::FramePipelineAllExtraPasses); std::size_t worldInstanceIndex1 = framePipeline.RegisterWorldInstance(modelInstance); framePipeline.RegisterRenderable(worldInstanceIndex1, Nz::FramePipeline::NoSkeletonInstance, &model, 0xFFFFFFFF, scissorBox); diff --git a/include/Nazara/Graphics/Camera.hpp b/include/Nazara/Graphics/Camera.hpp index 70d191c8b..319cf1507 100644 --- a/include/Nazara/Graphics/Camera.hpp +++ b/include/Nazara/Graphics/Camera.hpp @@ -30,6 +30,8 @@ namespace Nz inline float GetAspectRatio() const; const Color& GetClearColor() const override; inline DegreeAnglef GetFOV() const; + inline FramePipelineExtraPassFlags GetFramePipelineExtraPassFlags() const; + inline ProjectionType GetProjectionType() const; UInt32 GetRenderMask() const override; inline Int32 GetRenderOrder() const; const RenderTarget& GetRenderTarget() const override; @@ -43,6 +45,7 @@ namespace Nz inline void UpdateClearColor(Color color); inline void UpdateFOV(DegreeAnglef fov); + inline void UpdateFramePipelineExtraPassFlags(FramePipelineExtraPassFlags framePipelineExtraFlags); inline void UpdateProjectionType(ProjectionType projectionType); inline void UpdateRenderMask(UInt32 renderMask); inline void UpdateRenderOrder(Int32 renderOrder); @@ -67,6 +70,7 @@ namespace Nz const RenderTarget* m_renderTarget; Color m_clearColor; DegreeAnglef m_fov; + FramePipelineExtraPassFlags m_framePipelineExtraPassFlags; Int32 m_renderOrder; ProjectionType m_projectionType; Rectf m_targetRegion; diff --git a/include/Nazara/Graphics/Camera.inl b/include/Nazara/Graphics/Camera.inl index 39b526fc3..12fb55060 100644 --- a/include/Nazara/Graphics/Camera.inl +++ b/include/Nazara/Graphics/Camera.inl @@ -11,6 +11,7 @@ namespace Nz m_renderTarget(nullptr), m_clearColor(Color::Black()), m_fov(90.f), + m_framePipelineExtraPassFlags(FramePipelineExtraPass::DebugDraw), m_renderOrder(0), m_projectionType(projectionType), m_targetRegion(0.f, 0.f, 1.f, 1.f), @@ -20,6 +21,9 @@ namespace Nz m_zFar((projectionType == ProjectionType::Perspective) ? 1000.f : 1.f), m_zNear((projectionType == ProjectionType::Perspective) ? 1.f : -1.f) { + if (projectionType == ProjectionType::Perspective) + m_framePipelineExtraPassFlags |= FramePipelineExtraPass::DepthPrepass; + UpdateTarget(renderTarget); } @@ -27,6 +31,7 @@ namespace Nz m_renderTarget(nullptr), m_clearColor(camera.m_clearColor), m_fov(camera.m_fov), + m_framePipelineExtraPassFlags(camera.m_framePipelineExtraPassFlags), m_renderOrder(camera.m_renderOrder), m_projectionType(camera.m_projectionType), m_targetRegion(camera.m_targetRegion), @@ -44,6 +49,7 @@ namespace Nz m_renderTarget(nullptr), m_clearColor(camera.m_clearColor), m_fov(camera.m_fov), + m_framePipelineExtraPassFlags(camera.m_framePipelineExtraPassFlags), m_renderOrder(camera.m_renderOrder), m_projectionType(camera.m_projectionType), m_targetRegion(camera.m_targetRegion), @@ -67,6 +73,16 @@ namespace Nz return m_fov; } + inline FramePipelineExtraPassFlags Camera::GetFramePipelineExtraPassFlags() const + { + return m_framePipelineExtraPassFlags; + } + + inline ProjectionType Camera::GetProjectionType() const + { + return m_projectionType; + } + inline Int32 Camera::GetRenderOrder() const { return m_renderOrder; @@ -103,6 +119,11 @@ namespace Nz UpdateProjectionMatrix(); } + inline void Camera::UpdateFramePipelineExtraPassFlags(FramePipelineExtraPassFlags framePipelineExtraFlags) + { + m_framePipelineExtraPassFlags = framePipelineExtraFlags; + } + inline void Camera::UpdateZFar(float zFar) { m_zFar = zFar; @@ -119,6 +140,7 @@ namespace Nz inline Camera& Camera::operator=(const Camera& camera) { + m_framePipelineExtraPassFlags = camera.m_framePipelineExtraPassFlags; m_fov = camera.m_fov; m_projectionType = camera.m_projectionType; m_targetRegion = camera.m_targetRegion; @@ -135,6 +157,7 @@ namespace Nz inline Camera& Camera::operator=(Camera&& camera) noexcept { + m_framePipelineExtraPassFlags = camera.m_framePipelineExtraPassFlags; m_fov = camera.m_fov; m_projectionType = camera.m_projectionType; m_targetRegion = camera.m_targetRegion; @@ -246,3 +269,4 @@ namespace Nz } #include +#include "Camera.hpp" diff --git a/include/Nazara/Graphics/Enums.hpp b/include/Nazara/Graphics/Enums.hpp index 51c9892e8..870ab2ed7 100644 --- a/include/Nazara/Graphics/Enums.hpp +++ b/include/Nazara/Graphics/Enums.hpp @@ -41,6 +41,24 @@ namespace Nz Volume }; + enum class FramePipelineExtraPass + { + DebugDraw, + DepthPrepass, + + Max = DepthPrepass + }; + + template<> + struct EnumAsFlags + { + static constexpr FramePipelineExtraPass max = FramePipelineExtraPass::Max; + }; + + using FramePipelineExtraPassFlags = Flags; + + constexpr FramePipelineExtraPassFlags FramePipelineAllExtraPasses = FramePipelineExtraPass::DebugDraw | FramePipelineExtraPass::DepthPrepass; + enum class MaterialPropertyType { Bool, diff --git a/include/Nazara/Graphics/ForwardFramePipeline.hpp b/include/Nazara/Graphics/ForwardFramePipeline.hpp index 8f21f4ea4..a9a294b5a 100644 --- a/include/Nazara/Graphics/ForwardFramePipeline.hpp +++ b/include/Nazara/Graphics/ForwardFramePipeline.hpp @@ -54,7 +54,7 @@ namespace Nz std::size_t RegisterLight(const Light* light, UInt32 renderMask) override; std::size_t RegisterRenderable(std::size_t worldInstanceIndex, std::size_t skeletonInstanceIndex, const InstancedRenderable* instancedRenderable, UInt32 renderMask, const Recti& scissorBox) override; std::size_t RegisterSkeleton(SkeletonInstancePtr skeletonInstance) override; - std::size_t RegisterViewer(AbstractViewer* viewerInstance, Int32 renderOrder) override; + std::size_t RegisterViewer(AbstractViewer* viewerInstance, Int32 renderOrder, FramePipelineExtraPassFlags passFlags) override; std::size_t RegisterWorldInstance(WorldInstancePtr worldInstance) override; const Light* RetrieveLight(std::size_t lightIndex) const override; @@ -131,6 +131,7 @@ namespace Nz struct ViewerData { + std::size_t finalColorAttachment; std::size_t forwardColorAttachment; std::size_t debugColorAttachment; std::size_t depthStencilAttachment; diff --git a/include/Nazara/Graphics/FramePipeline.hpp b/include/Nazara/Graphics/FramePipeline.hpp index f882d6e8a..54894d041 100644 --- a/include/Nazara/Graphics/FramePipeline.hpp +++ b/include/Nazara/Graphics/FramePipeline.hpp @@ -46,7 +46,7 @@ namespace Nz virtual std::size_t RegisterLight(const Light* light, UInt32 renderMask) = 0; virtual std::size_t RegisterRenderable(std::size_t worldInstanceIndex, std::size_t skeletonInstanceIndex, const InstancedRenderable* instancedRenderable, UInt32 renderMask, const Recti& scissorBox) = 0; virtual std::size_t RegisterSkeleton(SkeletonInstancePtr skeletonInstance) = 0; - virtual std::size_t RegisterViewer(AbstractViewer* viewerInstance, Int32 renderOrder) = 0; + virtual std::size_t RegisterViewer(AbstractViewer* viewerInstance, Int32 renderOrder, FramePipelineExtraPassFlags passFlags) = 0; virtual std::size_t RegisterWorldInstance(WorldInstancePtr worldInstance) = 0; virtual const Light* RetrieveLight(std::size_t lightIndex) const = 0; diff --git a/src/Nazara/Graphics/ForwardFramePipeline.cpp b/src/Nazara/Graphics/ForwardFramePipeline.cpp index 731129529..34f04a50a 100644 --- a/src/Nazara/Graphics/ForwardFramePipeline.cpp +++ b/src/Nazara/Graphics/ForwardFramePipeline.cpp @@ -237,15 +237,13 @@ namespace Nz return skeletonInstanceIndex; } - std::size_t ForwardFramePipeline::RegisterViewer(AbstractViewer* viewerInstance, Int32 renderOrder) + std::size_t ForwardFramePipeline::RegisterViewer(AbstractViewer* viewerInstance, Int32 renderOrder, FramePipelineExtraPassFlags passFlags) { std::size_t depthPassIndex = Graphics::Instance()->GetMaterialPassRegistry().GetPassIndex("DepthPass"); std::size_t viewerIndex; auto& viewerData = *m_viewerPool.Allocate(viewerIndex); viewerData.renderOrder = renderOrder; - viewerData.debugDrawPass = std::make_unique(*this, viewerInstance); - viewerData.depthPrepass = std::make_unique(*this, m_elementRegistry, viewerInstance, depthPassIndex, "Depth pre-pass"); viewerData.forwardPass = std::make_unique(*this, m_elementRegistry, viewerInstance); viewerData.viewer = viewerInstance; viewerData.onTransferRequired.Connect(viewerInstance->GetViewerInstance().OnTransferRequired, [this](TransferInterface* transferInterface) @@ -253,6 +251,12 @@ namespace Nz m_transferSet.insert(transferInterface); }); + if (passFlags.Test(FramePipelineExtraPass::DebugDraw)) + viewerData.debugDrawPass = std::make_unique(*this, viewerInstance); + + if (passFlags.Test(FramePipelineExtraPass::DepthPrepass)) + viewerData.depthPrepass = std::make_unique(*this, m_elementRegistry, viewerInstance, depthPassIndex, "Depth pre-pass"); + m_transferSet.insert(&viewerInstance->GetViewerInstance()); m_rebuildFrameGraph = true; @@ -394,7 +398,8 @@ namespace Nz viewerData.forwardPass->Prepare(renderFrame, frustum, visibleRenderables, m_visibleLights, visibilityHash); - viewerData.debugDrawPass->Prepare(renderFrame); + if (viewerData.debugDrawPass) + viewerData.debugDrawPass->Prepare(renderFrame); } if (frameGraphInvalidated) @@ -410,7 +415,7 @@ namespace Nz { 0, ShaderBinding::SampledTextureBinding { - m_bakedFrameGraph.GetAttachmentTexture(viewerData.debugColorAttachment).get(), + m_bakedFrameGraph.GetAttachmentTexture(viewerData.finalColorAttachment).get(), sampler.get() } } @@ -606,7 +611,6 @@ namespace Nz PixelFormat::RGBA8 }); - viewerData.debugColorAttachment = frameGraph.AddAttachmentProxy("Debug draw output", viewerData.forwardColorAttachment); viewerData.depthStencilAttachment = frameGraph.AddAttachment({ "Depth-stencil buffer", @@ -623,7 +627,14 @@ namespace Nz lightData->shadowData->RegisterPassInputs(forwardPass); } - viewerData.debugDrawPass->RegisterToFrameGraph(frameGraph, viewerData.forwardColorAttachment, viewerData.debugColorAttachment); + if (viewerData.debugDrawPass) + { + viewerData.debugColorAttachment = frameGraph.AddAttachmentProxy("Debug draw output", viewerData.forwardColorAttachment); + viewerData.debugDrawPass->RegisterToFrameGraph(frameGraph, viewerData.forwardColorAttachment, viewerData.debugColorAttachment); + viewerData.finalColorAttachment = viewerData.debugColorAttachment; + } + else + viewerData.finalColorAttachment = viewerData.forwardColorAttachment; } using ViewerPair = std::pair; @@ -661,7 +672,7 @@ namespace Nz }); for (const ViewerData* viewerData : targetViewers) - mergePass.AddInput(viewerData->debugColorAttachment); + mergePass.AddInput(viewerData->finalColorAttachment); mergePass.AddOutput(renderTargetData.finalAttachment); mergePass.SetClearColor(0, Color::Black()); diff --git a/src/Nazara/Graphics/Systems/RenderSystem.cpp b/src/Nazara/Graphics/Systems/RenderSystem.cpp index d64f8c6b6..412fdb53e 100644 --- a/src/Nazara/Graphics/Systems/RenderSystem.cpp +++ b/src/Nazara/Graphics/Systems/RenderSystem.cpp @@ -330,7 +330,7 @@ namespace Nz CameraEntity* cameraEntity = m_cameraEntityPool.Allocate(poolIndex); cameraEntity->poolIndex = poolIndex; cameraEntity->entity = entity; - cameraEntity->viewerIndex = m_pipeline->RegisterViewer(&entityCamera, entityCamera.GetRenderOrder()); + cameraEntity->viewerIndex = m_pipeline->RegisterViewer(&entityCamera, entityCamera.GetRenderOrder(), entityCamera.GetFramePipelineExtraPassFlags()); cameraEntity->onNodeInvalidation.Connect(entityNode.OnNodeInvalidation, [this, cameraEntity](const Node* /*node*/) { m_invalidatedCameraNode.insert(cameraEntity); diff --git a/tests/GraphicsTest/main.cpp b/tests/GraphicsTest/main.cpp index 5087295dd..2fcbd1213 100644 --- a/tests/GraphicsTest/main.cpp +++ b/tests/GraphicsTest/main.cpp @@ -93,7 +93,7 @@ int main() Nz::ElementRendererRegistry elementRegistry; Nz::ForwardFramePipeline framePipeline(elementRegistry); - [[maybe_unused]] std::size_t cameraIndex = framePipeline.RegisterViewer(&camera, 0); + [[maybe_unused]] std::size_t cameraIndex = framePipeline.RegisterViewer(&camera, 0, Nz::FramePipelineAllExtraPasses); std::size_t worldInstanceIndex1 = framePipeline.RegisterWorldInstance(modelInstance); std::size_t worldInstanceIndex2 = framePipeline.RegisterWorldInstance(modelInstance2); framePipeline.RegisterRenderable(worldInstanceIndex1, Nz::FramePipeline::NoSkeletonInstance, &model, 0xFFFFFFFF, scissorBox);