Graphics: Add data-driven pipeline passes
Fix compilation
This commit is contained in:
parent
4995364418
commit
8fb6ea728d
|
|
@ -62,7 +62,6 @@ int main(int argc, char* argv[])
|
|||
Nz::Vector2ui windowSize = window.GetSize();
|
||||
|
||||
Nz::Camera camera(&windowSwapchain);
|
||||
camera.EnableFramePipelinePasses(Nz::FramePipelineExtraPass::GammaCorrection);
|
||||
//camera.UpdateClearColor(Nz::Color::Gray);
|
||||
|
||||
Nz::ViewerInstance& viewerInstance = camera.GetViewerInstance();
|
||||
|
|
@ -77,7 +76,7 @@ int main(int argc, char* argv[])
|
|||
|
||||
Nz::ElementRendererRegistry elementRegistry;
|
||||
Nz::ForwardFramePipeline framePipeline(elementRegistry);
|
||||
[[maybe_unused]] std::size_t cameraIndex = framePipeline.RegisterViewer(&camera, 0, Nz::FramePipelineAllExtraPasses);
|
||||
[[maybe_unused]] std::size_t cameraIndex = framePipeline.RegisterViewer(&camera, 0);
|
||||
std::size_t worldInstanceIndex1 = framePipeline.RegisterWorldInstance(modelInstance);
|
||||
framePipeline.RegisterRenderable(worldInstanceIndex1, Nz::FramePipeline::NoSkeletonInstance, &model, 0xFFFFFFFF, scissorBox);
|
||||
|
||||
|
|
|
|||
|
|
@ -351,7 +351,6 @@ int main(int argc, char* argv[])
|
|||
auto& cameraComponent = cameraEntity.emplace<Nz::CameraComponent>(&windowSwapchain, Nz::ProjectionType::Perspective);
|
||||
cameraComponent.UpdateFOV(70.f);
|
||||
cameraComponent.UpdateClearColor(Nz::Color::sRGBToLinear(Nz::Color(0.46f, 0.48f, 0.84f, 1.f)));
|
||||
cameraComponent.EnableFramePipelinePasses(Nz::FramePipelineExtraPass::GammaCorrection);
|
||||
}
|
||||
|
||||
auto UpdateCamera = [&]
|
||||
|
|
|
|||
|
|
@ -8,32 +8,31 @@
|
|||
#define NAZARA_GRAPHICS_CAMERA_HPP
|
||||
|
||||
#include <NazaraUtils/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/AbstractViewer.hpp>
|
||||
#include <Nazara/Graphics/Enums.hpp>
|
||||
#include <Nazara/Graphics/PipelineViewer.hpp>
|
||||
#include <Nazara/Graphics/ViewerInstance.hpp>
|
||||
#include <Nazara/Math/Rect.hpp>
|
||||
#include <Nazara/Math/Vector2.hpp>
|
||||
#include <Nazara/Renderer/RenderTarget.hpp>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_GRAPHICS_API Camera : public AbstractViewer
|
||||
class PipelinePassList;
|
||||
|
||||
class NAZARA_GRAPHICS_API Camera : public PipelineViewer
|
||||
{
|
||||
public:
|
||||
inline Camera(const RenderTarget* renderTarget, ProjectionType projectionType = ProjectionType::Perspective);
|
||||
inline Camera(const RenderTarget* renderTarget, std::shared_ptr<PipelinePassList> pipelinePasses, ProjectionType projectionType = ProjectionType::Perspective);
|
||||
Camera(const RenderTarget* renderTarget, ProjectionType projectionType = ProjectionType::Perspective);
|
||||
inline Camera(const Camera& camera);
|
||||
inline Camera(Camera&& camera) noexcept;
|
||||
~Camera() = default;
|
||||
|
||||
inline void DisableFramePipelinePasses(FramePipelineExtraPassFlags framePipelineExtraPassFlags);
|
||||
inline void EnableFramePipelinePasses(FramePipelineExtraPassFlags framePipelineExtraPassFlags);
|
||||
std::vector<std::unique_ptr<FramePipelinePass>> BuildPasses(FramePipelinePass::PassData& passData) const override;
|
||||
|
||||
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;
|
||||
|
|
@ -46,9 +45,10 @@ namespace Nz
|
|||
inline float GetZFar() const;
|
||||
inline float GetZNear() const;
|
||||
|
||||
std::size_t RegisterPasses(const std::vector<std::unique_ptr<FramePipelinePass>>& passes, FrameGraph& frameGraph) const override;
|
||||
|
||||
inline void UpdateClearColor(Color color);
|
||||
inline void UpdateFOV(DegreeAnglef fov);
|
||||
inline void UpdateFramePipelinePasses(FramePipelineExtraPassFlags framePipelineExtraFlags);
|
||||
inline void UpdateProjectionType(ProjectionType projectionType);
|
||||
inline void UpdateRenderMask(UInt32 renderMask);
|
||||
inline void UpdateRenderOrder(Int32 renderOrder);
|
||||
|
|
@ -70,10 +70,10 @@ namespace Nz
|
|||
NazaraSlot(RenderTarget, OnRenderTargetRelease, m_onRenderTargetRelease);
|
||||
NazaraSlot(RenderTarget, OnRenderTargetSizeChange, m_onRenderTargetSizeChange);
|
||||
|
||||
std::shared_ptr<PipelinePassList> m_framePipelinePasses;
|
||||
const RenderTarget* m_renderTarget;
|
||||
Color m_clearColor;
|
||||
DegreeAnglef m_fov;
|
||||
FramePipelineExtraPassFlags m_framePipelineExtraPassFlags;
|
||||
Int32 m_renderOrder;
|
||||
ProjectionType m_projectionType;
|
||||
Rectf m_targetRegion;
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
inline Camera::Camera(const RenderTarget* renderTarget, ProjectionType projectionType) :
|
||||
inline Camera::Camera(const RenderTarget* renderTarget, std::shared_ptr<PipelinePassList> pipelinePasses, ProjectionType projectionType) :
|
||||
m_framePipelinePasses(std::move(pipelinePasses)),
|
||||
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),
|
||||
|
|
@ -21,17 +21,14 @@ 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);
|
||||
}
|
||||
|
||||
inline Camera::Camera(const Camera& camera) :
|
||||
m_framePipelinePasses(camera.m_framePipelinePasses),
|
||||
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),
|
||||
|
|
@ -46,10 +43,10 @@ namespace Nz
|
|||
}
|
||||
|
||||
inline Camera::Camera(Camera&& camera) noexcept :
|
||||
m_framePipelinePasses(std::move(camera.m_framePipelinePasses)),
|
||||
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),
|
||||
|
|
@ -63,16 +60,6 @@ namespace Nz
|
|||
UpdateTarget(camera.m_renderTarget);
|
||||
}
|
||||
|
||||
inline void Camera::DisableFramePipelinePasses(FramePipelineExtraPassFlags framePipelineExtraPassFlags)
|
||||
{
|
||||
m_framePipelineExtraPassFlags &= ~framePipelineExtraPassFlags;
|
||||
}
|
||||
|
||||
inline void Camera::EnableFramePipelinePasses(FramePipelineExtraPassFlags framePipelineExtraPassFlags)
|
||||
{
|
||||
m_framePipelineExtraPassFlags |= framePipelineExtraPassFlags;
|
||||
}
|
||||
|
||||
inline float Camera::GetAspectRatio() const
|
||||
{
|
||||
return m_aspectRatio;
|
||||
|
|
@ -83,11 +70,6 @@ namespace Nz
|
|||
return m_fov;
|
||||
}
|
||||
|
||||
inline FramePipelineExtraPassFlags Camera::GetFramePipelineExtraPassFlags() const
|
||||
{
|
||||
return m_framePipelineExtraPassFlags;
|
||||
}
|
||||
|
||||
inline ProjectionType Camera::GetProjectionType() const
|
||||
{
|
||||
return m_projectionType;
|
||||
|
|
@ -129,11 +111,6 @@ namespace Nz
|
|||
UpdateProjectionMatrix();
|
||||
}
|
||||
|
||||
inline void Camera::UpdateFramePipelinePasses(FramePipelineExtraPassFlags framePipelineExtraFlags)
|
||||
{
|
||||
m_framePipelineExtraPassFlags = framePipelineExtraFlags;
|
||||
}
|
||||
|
||||
inline void Camera::UpdateZFar(float zFar)
|
||||
{
|
||||
m_zFar = zFar;
|
||||
|
|
@ -150,7 +127,7 @@ namespace Nz
|
|||
|
||||
inline Camera& Camera::operator=(const Camera& camera)
|
||||
{
|
||||
m_framePipelineExtraPassFlags = camera.m_framePipelineExtraPassFlags;
|
||||
m_framePipelinePasses = camera.m_framePipelinePasses;
|
||||
m_fov = camera.m_fov;
|
||||
m_projectionType = camera.m_projectionType;
|
||||
m_targetRegion = camera.m_targetRegion;
|
||||
|
|
@ -167,7 +144,7 @@ namespace Nz
|
|||
|
||||
inline Camera& Camera::operator=(Camera&& camera) noexcept
|
||||
{
|
||||
m_framePipelineExtraPassFlags = camera.m_framePipelineExtraPassFlags;
|
||||
m_framePipelinePasses = std::move(camera.m_framePipelinePasses);
|
||||
m_fov = camera.m_fov;
|
||||
m_projectionType = camera.m_projectionType;
|
||||
m_targetRegion = camera.m_targetRegion;
|
||||
|
|
@ -281,4 +258,3 @@ namespace Nz
|
|||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
#include "Camera.hpp"
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <NazaraUtils/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/FramePipelinePass.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
|
|
@ -17,24 +18,26 @@ namespace Nz
|
|||
class FrameGraph;
|
||||
class FramePass;
|
||||
class FramePipeline;
|
||||
class ParameterList;
|
||||
class RenderFrame;
|
||||
|
||||
class NAZARA_GRAPHICS_API DebugDrawPipelinePass : public FramePipelinePass
|
||||
{
|
||||
public:
|
||||
DebugDrawPipelinePass(FramePipeline& owner, AbstractViewer* viewer);
|
||||
DebugDrawPipelinePass(PassData& passData, std::string passName, const ParameterList& parameters = {});
|
||||
DebugDrawPipelinePass(const DebugDrawPipelinePass&) = delete;
|
||||
DebugDrawPipelinePass(DebugDrawPipelinePass&&) = delete;
|
||||
~DebugDrawPipelinePass() = default;
|
||||
|
||||
void Prepare(RenderFrame& renderFrame);
|
||||
void Prepare(FrameData& frameData) override;
|
||||
|
||||
FramePass& RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t inputColorBufferIndex, std::size_t outputColorBufferIndex);
|
||||
FramePass& RegisterToFrameGraph(FrameGraph& frameGraph, const PassInputOuputs& inputOuputs) override;
|
||||
|
||||
DebugDrawPipelinePass& operator=(const DebugDrawPipelinePass&) = delete;
|
||||
DebugDrawPipelinePass& operator=(DebugDrawPipelinePass&&) = delete;
|
||||
|
||||
private:
|
||||
std::string m_passName;
|
||||
AbstractViewer* m_viewer;
|
||||
FramePipeline& m_pipeline;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,6 +6,13 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
inline DebugDrawPipelinePass::DebugDrawPipelinePass(PassData& passData, std::string passName, const ParameterList& /*parameters*/) :
|
||||
FramePipelinePass({}),
|
||||
m_passName(std::move(passName)),
|
||||
m_viewer(passData.viewer),
|
||||
m_pipeline(passData.pipeline)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
|
|
|
|||
|
|
@ -30,24 +30,28 @@ namespace Nz
|
|||
class NAZARA_GRAPHICS_API DepthPipelinePass : public FramePipelinePass
|
||||
{
|
||||
public:
|
||||
DepthPipelinePass(FramePipeline& owner, ElementRendererRegistry& elementRegistry, AbstractViewer* viewer, std::size_t passIndex, std::string passName);
|
||||
inline DepthPipelinePass(PassData& passData, std::string passName, const ParameterList& parameters);
|
||||
inline DepthPipelinePass(PassData& passData, std::string passName, std::size_t materialPassIndex);
|
||||
DepthPipelinePass(const DepthPipelinePass&) = delete;
|
||||
DepthPipelinePass(DepthPipelinePass&&) = delete;
|
||||
~DepthPipelinePass() = default;
|
||||
|
||||
inline void InvalidateCommandBuffers();
|
||||
inline void InvalidateElements();
|
||||
void InvalidateElements() override;
|
||||
|
||||
void Prepare(RenderFrame& renderFrame, const Frustumf& frustum, const std::vector<FramePipelinePass::VisibleRenderable>& visibleRenderables, std::size_t visibilityHash);
|
||||
void Prepare(FrameData& frameData) override;
|
||||
|
||||
void RegisterMaterialInstance(const MaterialInstance& materialInstance);
|
||||
FramePass& RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t outputAttachment);
|
||||
void RegisterMaterialInstance(const MaterialInstance& materialInstance) override;
|
||||
|
||||
void UnregisterMaterialInstance(const MaterialInstance& materialInstance);
|
||||
FramePass& RegisterToFrameGraph(FrameGraph& frameGraph, const PassInputOuputs& inputOuputs) override;
|
||||
|
||||
void UnregisterMaterialInstance(const MaterialInstance& materialInstance) override;
|
||||
|
||||
DepthPipelinePass& operator=(const DepthPipelinePass&) = delete;
|
||||
DepthPipelinePass& operator=(DepthPipelinePass&&) = delete;
|
||||
|
||||
static std::size_t GetMaterialPassIndex(const ParameterList& parameters);
|
||||
|
||||
private:
|
||||
struct MaterialPassEntry
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6,6 +6,24 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
inline DepthPipelinePass::DepthPipelinePass(PassData& passData, std::string passName, const ParameterList& parameters) :
|
||||
DepthPipelinePass(passData, std::move(passName), GetMaterialPassIndex(parameters))
|
||||
{
|
||||
}
|
||||
|
||||
inline DepthPipelinePass::DepthPipelinePass(PassData& passData, std::string passName, std::size_t materialPassIndex) :
|
||||
FramePipelinePass(FramePipelineNotification::ElementInvalidation | FramePipelineNotification::MaterialInstanceRegistration),
|
||||
m_passIndex(materialPassIndex),
|
||||
m_lastVisibilityHash(0),
|
||||
m_passName(std::move(passName)),
|
||||
m_viewer(passData.viewer),
|
||||
m_elementRegistry(passData.elementRegistry),
|
||||
m_pipeline(passData.pipeline),
|
||||
m_rebuildCommandBuffer(false),
|
||||
m_rebuildElements(false)
|
||||
{
|
||||
}
|
||||
|
||||
inline void DepthPipelinePass::InvalidateCommandBuffers()
|
||||
{
|
||||
m_rebuildCommandBuffer = true;
|
||||
|
|
|
|||
|
|
@ -41,25 +41,22 @@ namespace Nz
|
|||
Volume
|
||||
};
|
||||
|
||||
enum class FramePipelineExtraPass
|
||||
enum class FramePipelineNotification
|
||||
{
|
||||
DebugDraw,
|
||||
DepthPrepass,
|
||||
GammaCorrection,
|
||||
ElementInvalidation,
|
||||
MaterialInstanceRegistration,
|
||||
|
||||
Max = GammaCorrection
|
||||
Max = MaterialInstanceRegistration
|
||||
};
|
||||
|
||||
template<>
|
||||
struct EnumAsFlags<FramePipelineExtraPass>
|
||||
struct EnumAsFlags<FramePipelineNotification>
|
||||
{
|
||||
static constexpr FramePipelineExtraPass max = FramePipelineExtraPass::Max;
|
||||
static constexpr FramePipelineNotification max = FramePipelineNotification::Max;
|
||||
};
|
||||
|
||||
using FramePipelineExtraPassFlags = Flags<FramePipelineExtraPass>;
|
||||
using FramePipelineNotificationFlags = Flags<FramePipelineNotification>;
|
||||
|
||||
constexpr FramePipelineExtraPassFlags FramePipelineAllExtraPasses = FramePipelineExtraPass::DebugDraw | FramePipelineExtraPass::DepthPrepass | FramePipelineExtraPass::GammaCorrection;
|
||||
|
||||
enum class MaterialPropertyType
|
||||
{
|
||||
Bool,
|
||||
|
|
|
|||
|
|
@ -55,7 +55,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, FramePipelineExtraPassFlags passFlags) override;
|
||||
std::size_t RegisterViewer(PipelineViewer* viewerInstance, Int32 renderOrder) override;
|
||||
std::size_t RegisterWorldInstance(WorldInstancePtr worldInstance) override;
|
||||
|
||||
const Light* RetrieveLight(std::size_t lightIndex) const override;
|
||||
|
|
@ -140,14 +140,8 @@ namespace Nz
|
|||
};
|
||||
|
||||
std::size_t finalColorAttachment;
|
||||
std::size_t forwardColorAttachment;
|
||||
std::size_t debugColorAttachment;
|
||||
std::size_t depthStencilAttachment;
|
||||
std::unique_ptr<DepthPipelinePass> depthPrepass;
|
||||
std::unique_ptr<ForwardPipelinePass> forwardPass;
|
||||
std::unique_ptr<DebugDrawPipelinePass> debugDrawPass;
|
||||
std::unique_ptr<PostProcessPipelinePass> gammaCorrectionPass;
|
||||
AbstractViewer* viewer;
|
||||
std::vector<std::unique_ptr<FramePipelinePass>> passes;
|
||||
PipelineViewer* viewer;
|
||||
Int32 renderOrder = 0;
|
||||
RenderQueueRegistry forwardRegistry;
|
||||
RenderQueue<RenderElement*> forwardRenderQueue;
|
||||
|
|
|
|||
|
|
@ -34,20 +34,21 @@ namespace Nz
|
|||
class NAZARA_GRAPHICS_API ForwardPipelinePass : public FramePipelinePass, TransferInterface
|
||||
{
|
||||
public:
|
||||
ForwardPipelinePass(FramePipeline& owner, ElementRendererRegistry& elementRegistry, AbstractViewer* viewer);
|
||||
ForwardPipelinePass(PassData& passData, std::string passName, const ParameterList& parameters = {});
|
||||
ForwardPipelinePass(const ForwardPipelinePass&) = delete;
|
||||
ForwardPipelinePass(ForwardPipelinePass&&) = delete;
|
||||
~ForwardPipelinePass() = default;
|
||||
|
||||
inline void InvalidateCommandBuffers();
|
||||
inline void InvalidateElements();
|
||||
void InvalidateElements() override;
|
||||
|
||||
void Prepare(RenderFrame& renderFrame, const Frustumf& frustum, const std::vector<FramePipelinePass::VisibleRenderable>& visibleRenderables, const Bitset<UInt64>& visibleLights, std::size_t visibilityHash);
|
||||
void Prepare(FrameData& frameData) override;
|
||||
|
||||
void RegisterMaterialInstance(const MaterialInstance& material);
|
||||
FramePass& RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t colorBufferIndex, std::size_t depthBufferIndex, bool hasDepthPrepass);
|
||||
void RegisterMaterialInstance(const MaterialInstance& material) override;
|
||||
|
||||
void UnregisterMaterialInstance(const MaterialInstance& material);
|
||||
FramePass& RegisterToFrameGraph(FrameGraph& frameGraph, const PassInputOuputs& inputOuputs) override;
|
||||
|
||||
void UnregisterMaterialInstance(const MaterialInstance& material) override;
|
||||
|
||||
ForwardPipelinePass& operator=(const ForwardPipelinePass&) = delete;
|
||||
ForwardPipelinePass& operator=(ForwardPipelinePass&&) = delete;
|
||||
|
|
@ -79,6 +80,7 @@ namespace Nz
|
|||
std::size_t m_forwardPassIndex;
|
||||
std::size_t m_lastVisibilityHash;
|
||||
std::shared_ptr<RenderBuffer> m_lightDataBuffer;
|
||||
std::string m_passName;
|
||||
std::vector<std::unique_ptr<ElementRendererData>> m_elementRendererData;
|
||||
std::vector<RenderElementOwner> m_renderElements;
|
||||
std::unordered_map<const MaterialInstance*, MaterialPassEntry> m_materialInstances;
|
||||
|
|
|
|||
|
|
@ -20,11 +20,11 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
class AbstractViewer;
|
||||
class InstancedRenderable;
|
||||
class Light;
|
||||
class LightShadowData;
|
||||
class MaterialInstance;
|
||||
class PipelineViewer;
|
||||
class RenderFrame;
|
||||
|
||||
class NAZARA_GRAPHICS_API FramePipeline
|
||||
|
|
@ -47,7 +47,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, FramePipelineExtraPassFlags passFlags) = 0;
|
||||
virtual std::size_t RegisterViewer(PipelineViewer* viewerInstance, Int32 renderOrder) = 0;
|
||||
virtual std::size_t RegisterWorldInstance(WorldInstancePtr worldInstance) = 0;
|
||||
|
||||
virtual const Light* RetrieveLight(std::size_t lightIndex) const = 0;
|
||||
|
|
|
|||
|
|
@ -9,25 +9,80 @@
|
|||
|
||||
#include <NazaraUtils/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/Enums.hpp>
|
||||
#include <Nazara/Math/Frustum.hpp>
|
||||
#include <Nazara/Math/Rect.hpp>
|
||||
#include <NazaraUtils/Bitset.hpp>
|
||||
#include <limits>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class AbstractViewer;
|
||||
class ElementRendererRegistry;
|
||||
class FrameGraph;
|
||||
class FramePass;
|
||||
class FramePipeline;
|
||||
class InstancedRenderable;
|
||||
class MaterialInstance;
|
||||
class RenderFrame;
|
||||
class SkeletonInstance;
|
||||
class WorldInstance;
|
||||
|
||||
class NAZARA_GRAPHICS_API FramePipelinePass
|
||||
{
|
||||
public:
|
||||
FramePipelinePass() = default;
|
||||
struct FrameData;
|
||||
struct PassData;
|
||||
struct PassInputOuputs;
|
||||
struct VisibleRenderable;
|
||||
|
||||
inline FramePipelinePass(FramePipelineNotificationFlags notificationFlags);
|
||||
FramePipelinePass(const FramePipelinePass&) = delete;
|
||||
FramePipelinePass(FramePipelinePass&&) = delete;
|
||||
virtual ~FramePipelinePass();
|
||||
|
||||
virtual void InvalidateElements();
|
||||
|
||||
virtual void Prepare(FrameData& frameData) = 0;
|
||||
|
||||
virtual void RegisterMaterialInstance(const MaterialInstance& materialInstance);
|
||||
|
||||
virtual FramePass& RegisterToFrameGraph(FrameGraph& frameGraph, const PassInputOuputs& inputOuputs) = 0;
|
||||
|
||||
inline bool ShouldNotify(FramePipelineNotification notification) const;
|
||||
|
||||
virtual void UnregisterMaterialInstance(const MaterialInstance& materialInstance);
|
||||
|
||||
FramePipelinePass& operator=(const FramePipelinePass&) = delete;
|
||||
FramePipelinePass& operator=(FramePipelinePass&&) = delete;
|
||||
|
||||
struct FrameData
|
||||
{
|
||||
const Bitset<UInt64>* visibleLights;
|
||||
const Frustumf& frustum;
|
||||
RenderFrame& renderFrame;
|
||||
const std::vector<VisibleRenderable>& visibleRenderables;
|
||||
std::size_t visibilityHash;
|
||||
};
|
||||
|
||||
struct PassData
|
||||
{
|
||||
AbstractViewer* viewer;
|
||||
ElementRendererRegistry& elementRegistry;
|
||||
FramePipeline& pipeline;
|
||||
};
|
||||
|
||||
struct PassInputOuputs
|
||||
{
|
||||
// TODO: Add Nz::View / Nz::Span
|
||||
const std::size_t* inputAttachments;
|
||||
const std::size_t* outputAttachments;
|
||||
std::size_t depthStencilInput = InvalidAttachmentIndex;
|
||||
std::size_t depthStencilOutput = InvalidAttachmentIndex;
|
||||
std::size_t inputCount = 0;
|
||||
std::size_t outputCount = 0;
|
||||
};
|
||||
|
||||
struct VisibleRenderable
|
||||
{
|
||||
const InstancedRenderable* instancedRenderable;
|
||||
|
|
@ -35,6 +90,11 @@ namespace Nz
|
|||
const WorldInstance* worldInstance;
|
||||
Recti scissorBox;
|
||||
};
|
||||
|
||||
static constexpr std::size_t InvalidAttachmentIndex = std::numeric_limits<std::size_t>::max();
|
||||
|
||||
private:
|
||||
FramePipelineNotificationFlags m_notificationFlags;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,15 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
inline FramePipelinePass::FramePipelinePass(FramePipelineNotificationFlags notificationFlags) :
|
||||
m_notificationFlags(notificationFlags)
|
||||
{
|
||||
}
|
||||
|
||||
inline bool FramePipelinePass::ShouldNotify(FramePipelineNotification notification) const
|
||||
{
|
||||
return m_notificationFlags.Test(notification);
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_GRAPHICS_FRAMEPIPELINEPASSREGISTRY_HPP
|
||||
#define NAZARA_GRAPHICS_FRAMEPIPELINEPASSREGISTRY_HPP
|
||||
|
||||
#include <NazaraUtils/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/FramePipelinePass.hpp>
|
||||
#include <NazaraUtils/Algorithm.hpp>
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class ParameterList;
|
||||
|
||||
class FramePipelinePassRegistry
|
||||
{
|
||||
public:
|
||||
using Factory = std::function<std::unique_ptr<FramePipelinePass>(FramePipelinePass::PassData& passData, std::string passName, const ParameterList& parameters)>;
|
||||
|
||||
FramePipelinePassRegistry() = default;
|
||||
FramePipelinePassRegistry(const FramePipelinePassRegistry&) = default;
|
||||
FramePipelinePassRegistry(FramePipelinePassRegistry&&) = default;
|
||||
~FramePipelinePassRegistry() = default;
|
||||
|
||||
inline std::unique_ptr<FramePipelinePass> BuildPass(std::size_t passIndex, FramePipelinePass::PassData& passData, std::string passName, const ParameterList& parameters) const;
|
||||
|
||||
inline std::size_t GetPassIndex(std::string_view passName) const;
|
||||
|
||||
template<typename T> std::size_t RegisterPass(std::string passName);
|
||||
inline std::size_t RegisterPass(std::string passName, Factory factory);
|
||||
|
||||
FramePipelinePassRegistry& operator=(const FramePipelinePassRegistry&) = default;
|
||||
FramePipelinePassRegistry& operator=(FramePipelinePassRegistry&&) = default;
|
||||
|
||||
private:
|
||||
std::list<std::string> m_passNames; //< in order to allow std::string_view as a key in C++17 (keep std::string stable as well because of SSO)
|
||||
std::unordered_map<std::string_view, std::size_t> m_passIndex;
|
||||
std::vector<Factory> m_passFactories;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/FramePipelinePassRegistry.inl>
|
||||
|
||||
#endif // NAZARA_GRAPHICS_FRAMEPIPELINEPASSREGISTRY_HPP
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <cassert>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline std::unique_ptr<FramePipelinePass> FramePipelinePassRegistry::BuildPass(std::size_t passIndex, FramePipelinePass::PassData& passData, std::string passName, const ParameterList& parameters) const
|
||||
{
|
||||
assert(passIndex < m_passFactories.size());
|
||||
return m_passFactories[passIndex](passData, passName, parameters);
|
||||
}
|
||||
|
||||
inline std::size_t FramePipelinePassRegistry::GetPassIndex(std::string_view passName) const
|
||||
{
|
||||
auto it = m_passIndex.find(passName);
|
||||
if (it == m_passIndex.end())
|
||||
throw std::runtime_error("pass " + std::string(passName) + " must be registered before being used");
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::size_t FramePipelinePassRegistry::RegisterPass(std::string passName)
|
||||
{
|
||||
return RegisterPass(std::move(passName), [](FramePipelinePass::PassData& passData, std::string passName, const ParameterList& parameters) -> std::unique_ptr<FramePipelinePass>
|
||||
{
|
||||
return std::make_unique<T>(passData, std::move(passName), parameters);
|
||||
});
|
||||
}
|
||||
|
||||
inline std::size_t FramePipelinePassRegistry::RegisterPass(std::string passName, Factory factory)
|
||||
{
|
||||
if (m_passIndex.find(passName) != m_passIndex.end())
|
||||
throw std::runtime_error("pass " + passName + " is already registered");
|
||||
|
||||
m_passNames.push_back(std::move(passName));
|
||||
|
||||
std::size_t passIndex = m_passIndex.size();
|
||||
m_passIndex.emplace(m_passNames.back(), passIndex);
|
||||
m_passFactories.emplace_back(std::move(factory));
|
||||
|
||||
return passIndex;
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
|
|
@ -9,9 +9,11 @@
|
|||
|
||||
#include <NazaraUtils/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/FramePipelinePassRegistry.hpp>
|
||||
#include <Nazara/Graphics/Material.hpp>
|
||||
#include <Nazara/Graphics/MaterialInstance.hpp>
|
||||
#include <Nazara/Graphics/MaterialPassRegistry.hpp>
|
||||
#include <Nazara/Graphics/PipelinePassList.hpp>
|
||||
#include <Nazara/Graphics/TextureSamplerCache.hpp>
|
||||
#include <Nazara/Renderer/RenderDevice.hpp>
|
||||
#include <Nazara/Renderer/RenderPassCache.hpp>
|
||||
|
|
@ -43,7 +45,10 @@ namespace Nz
|
|||
inline const std::shared_ptr<RenderPipeline>& GetBlitPipeline(bool transparent) const;
|
||||
inline const std::shared_ptr<RenderPipelineLayout>& GetBlitPipelineLayout() const;
|
||||
inline const DefaultMaterials& GetDefaultMaterials() const;
|
||||
inline const std::shared_ptr<PipelinePassList>& GetDefaultPipelinePasses() const;
|
||||
inline const DefaultTextures& GetDefaultTextures() const;
|
||||
inline FramePipelinePassRegistry& GetFramePipelinePassRegistry();
|
||||
inline const FramePipelinePassRegistry& GetFramePipelinePassRegistry() const;
|
||||
inline MaterialPassRegistry& GetMaterialPassRegistry();
|
||||
inline const MaterialPassRegistry& GetMaterialPassRegistry() const;
|
||||
inline MaterialInstanceLoader& GetMaterialInstanceLoader();
|
||||
|
|
@ -88,21 +93,25 @@ namespace Nz
|
|||
private:
|
||||
void BuildBlitPipeline();
|
||||
void BuildDefaultMaterials();
|
||||
void BuildDefaultPipelinePasses();
|
||||
void BuildDefaultTextures();
|
||||
template<std::size_t N> void RegisterEmbedShaderModule(const UInt8(&content)[N]);
|
||||
void RegisterMaterialPasses();
|
||||
void RegisterPipelinePasses();
|
||||
void RegisterShaderModules();
|
||||
void SelectDepthStencilFormats();
|
||||
|
||||
std::optional<RenderPassCache> m_renderPassCache;
|
||||
std::optional<TextureSamplerCache> m_samplerCache;
|
||||
std::shared_ptr<nzsl::FilesystemModuleResolver> m_shaderModuleResolver;
|
||||
std::shared_ptr<PipelinePassList> m_defaultPipelinePasses;
|
||||
std::shared_ptr<RenderDevice> m_renderDevice;
|
||||
std::shared_ptr<RenderPipeline> m_blitPipeline;
|
||||
std::shared_ptr<RenderPipeline> m_blitPipelineTransparent;
|
||||
std::shared_ptr<RenderPipelineLayout> m_blitPipelineLayout;
|
||||
DefaultMaterials m_defaultMaterials;
|
||||
DefaultTextures m_defaultTextures;
|
||||
FramePipelinePassRegistry m_pipelinePassRegistry;
|
||||
MaterialInstanceLoader m_materialInstanceLoader;
|
||||
MaterialLoader m_materialLoader;
|
||||
MaterialPassRegistry m_materialPassRegistry;
|
||||
|
|
|
|||
|
|
@ -21,11 +21,26 @@ namespace Nz
|
|||
return m_defaultMaterials;
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<PipelinePassList>& Graphics::GetDefaultPipelinePasses() const
|
||||
{
|
||||
return m_defaultPipelinePasses;
|
||||
}
|
||||
|
||||
inline auto Graphics::GetDefaultTextures() const -> const DefaultTextures&
|
||||
{
|
||||
return m_defaultTextures;
|
||||
}
|
||||
|
||||
inline FramePipelinePassRegistry& Graphics::GetFramePipelinePassRegistry()
|
||||
{
|
||||
return m_pipelinePassRegistry;
|
||||
}
|
||||
|
||||
inline const FramePipelinePassRegistry& Graphics::GetFramePipelinePassRegistry() const
|
||||
{
|
||||
return m_pipelinePassRegistry;
|
||||
}
|
||||
|
||||
inline MaterialPassRegistry& Graphics::GetMaterialPassRegistry()
|
||||
{
|
||||
return m_materialPassRegistry;
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ namespace Nz
|
|||
|
||||
inline bool IsPerViewer() const;
|
||||
|
||||
virtual void PrepareRendering(RenderFrame& renderFrame, const AbstractViewer* viewer) = 0;
|
||||
virtual void PrepareRendering(RenderFrame& renderFrame, [[maybe_unused]] const AbstractViewer* viewer) = 0;
|
||||
|
||||
virtual void RegisterMaterialInstance(const MaterialInstance& matInstance) = 0;
|
||||
virtual void RegisterPassInputs(FramePass& pass, const AbstractViewer* viewer) = 0;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_GRAPHICS_PIPELINEPASSLIST_HPP
|
||||
#define NAZARA_GRAPHICS_PIPELINEPASSLIST_HPP
|
||||
|
||||
#include <NazaraUtils/Prerequisites.hpp>
|
||||
#include <Nazara/Core/ParameterList.hpp>
|
||||
#include <Nazara/Graphics/Config.hpp>
|
||||
#include <Nazara/Graphics/FramePassAttachment.hpp>
|
||||
#include <Nazara/Graphics/FramePipelinePass.hpp>
|
||||
#include <NazaraUtils/FixedVector.hpp>
|
||||
#include <array>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class FrameGraph;
|
||||
|
||||
class NAZARA_GRAPHICS_API PipelinePassList
|
||||
{
|
||||
public:
|
||||
PipelinePassList() = default;
|
||||
PipelinePassList(const PipelinePassList&) = delete;
|
||||
PipelinePassList(PipelinePassList&&) = delete;
|
||||
~PipelinePassList() = default;
|
||||
|
||||
inline std::size_t AddAttachment(FramePassAttachment attachment);
|
||||
inline std::size_t AddPass(std::string name, std::size_t implIndex, ParameterList parameterList = {});
|
||||
|
||||
std::vector<std::unique_ptr<FramePipelinePass>> BuildPasses(FramePipelinePass::PassData& passData) const;
|
||||
|
||||
std::size_t RegisterPasses(const std::vector<std::unique_ptr<FramePipelinePass>>& passes, FrameGraph& frameGraph) const;
|
||||
|
||||
inline void SetFinalOutput(std::size_t attachmentIndex);
|
||||
inline void SetPassInput(std::size_t passIndex, std::size_t inputIndex, std::size_t attachmentIndex);
|
||||
inline void SetPassOutput(std::size_t passIndex, std::size_t outputIndex, std::size_t attachmentIndex);
|
||||
inline void SetPassDepthStencilInput(std::size_t passIndex, std::size_t attachmentIndex);
|
||||
inline void SetPassDepthStencilOutput(std::size_t passIndex, std::size_t attachmentIndex);
|
||||
|
||||
PipelinePassList& operator=(const PipelinePassList&) = delete;
|
||||
PipelinePassList& operator=(PipelinePassList&&) = delete;
|
||||
|
||||
static constexpr std::size_t MaxPassAttachment = 8;
|
||||
|
||||
private:
|
||||
static constexpr std::size_t NoAttachment = std::numeric_limits<std::size_t>::max();
|
||||
|
||||
struct Pass
|
||||
{
|
||||
FixedVector<std::size_t /*attachmentIndex*/, MaxPassAttachment> inputs;
|
||||
FixedVector<std::size_t /*attachmentIndex*/, MaxPassAttachment> outputs;
|
||||
std::size_t depthStencilInput = NoAttachment;
|
||||
std::size_t depthStencilOutput = NoAttachment;
|
||||
std::size_t implIndex;
|
||||
std::string name;
|
||||
ParameterList parameterList;
|
||||
};
|
||||
|
||||
std::size_t m_finalOutputAttachment;
|
||||
std::vector<FramePassAttachment> m_attachments;
|
||||
std::vector<Pass> m_passes;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/PipelinePassList.inl>
|
||||
|
||||
#endif // NAZARA_GRAPHICS_PIPELINEPASSLIST_HPP
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <cassert>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline std::size_t PipelinePassList::AddAttachment(FramePassAttachment attachment)
|
||||
{
|
||||
std::size_t index = m_attachments.size();
|
||||
m_attachments.emplace_back(std::move(attachment));
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
inline std::size_t PipelinePassList::AddPass(std::string name, std::size_t implIndex, ParameterList parameterList)
|
||||
{
|
||||
std::size_t index = m_passes.size();
|
||||
auto& pass = m_passes.emplace_back();
|
||||
pass.name = std::move(name);
|
||||
pass.implIndex = implIndex;
|
||||
pass.parameterList = std::move(parameterList);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
inline void PipelinePassList::SetFinalOutput(std::size_t attachmentIndex)
|
||||
{
|
||||
m_finalOutputAttachment = attachmentIndex;
|
||||
}
|
||||
|
||||
inline void PipelinePassList::SetPassInput(std::size_t passIndex, std::size_t inputIndex, std::size_t attachmentIndex)
|
||||
{
|
||||
assert(passIndex < m_passes.size());
|
||||
auto& pass = m_passes[passIndex];
|
||||
assert(inputIndex < MaxPassAttachment);
|
||||
|
||||
if (inputIndex >= pass.inputs.size())
|
||||
pass.inputs.resize(inputIndex + 1, NoAttachment);
|
||||
|
||||
pass.inputs[inputIndex] = attachmentIndex;
|
||||
}
|
||||
|
||||
inline void PipelinePassList::SetPassOutput(std::size_t passIndex, std::size_t outputIndex, std::size_t attachmentIndex)
|
||||
{
|
||||
assert(passIndex < m_passes.size());
|
||||
auto& pass = m_passes[passIndex];
|
||||
assert(outputIndex < MaxPassAttachment);
|
||||
|
||||
if (outputIndex >= pass.outputs.size())
|
||||
pass.outputs.resize(outputIndex + 1, NoAttachment);
|
||||
|
||||
pass.outputs[outputIndex] = attachmentIndex;
|
||||
}
|
||||
|
||||
inline void PipelinePassList::SetPassDepthStencilInput(std::size_t passIndex, std::size_t attachmentIndex)
|
||||
{
|
||||
assert(passIndex < m_passes.size());
|
||||
auto& pass = m_passes[passIndex];
|
||||
pass.depthStencilInput = attachmentIndex;
|
||||
}
|
||||
|
||||
inline void PipelinePassList::SetPassDepthStencilOutput(std::size_t passIndex, std::size_t attachmentIndex)
|
||||
{
|
||||
assert(passIndex < m_passes.size());
|
||||
auto& pass = m_passes[passIndex];
|
||||
pass.depthStencilOutput = attachmentIndex;
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_GRAPHICS_PIPELINEVIEWER_HPP
|
||||
#define NAZARA_GRAPHICS_PIPELINEVIEWER_HPP
|
||||
|
||||
#include <NazaraUtils/Prerequisites.hpp>
|
||||
#include <Nazara/Graphics/AbstractViewer.hpp>
|
||||
#include <Nazara/Graphics/FramePipelinePass.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_GRAPHICS_API PipelineViewer : public AbstractViewer
|
||||
{
|
||||
public:
|
||||
PipelineViewer() = default;
|
||||
PipelineViewer(const PipelineViewer&) = delete;
|
||||
PipelineViewer(PipelineViewer&&) = delete;
|
||||
~PipelineViewer() = default;
|
||||
|
||||
virtual std::vector<std::unique_ptr<FramePipelinePass>> BuildPasses(FramePipelinePass::PassData& passData) const = 0;
|
||||
|
||||
virtual std::size_t RegisterPasses(const std::vector<std::unique_ptr<FramePipelinePass>>& passes, FrameGraph& frameGraph) const = 0;
|
||||
|
||||
PipelineViewer& operator=(const PipelineViewer&) = delete;
|
||||
PipelineViewer& operator=(PipelineViewer&&) = delete;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/PipelineViewer.inl>
|
||||
|
||||
#endif // NAZARA_GRAPHICS_PIPELINEVIEWER_HPP
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
|
|
@ -17,6 +17,7 @@ namespace Nz
|
|||
class FrameGraph;
|
||||
class FramePass;
|
||||
class FramePipeline;
|
||||
class ParameterList;
|
||||
class RenderFrame;
|
||||
class RenderPipeline;
|
||||
class ShaderBinding;
|
||||
|
|
@ -24,18 +25,21 @@ namespace Nz
|
|||
class NAZARA_GRAPHICS_API PostProcessPipelinePass : public FramePipelinePass
|
||||
{
|
||||
public:
|
||||
PostProcessPipelinePass(FramePipeline& owner, std::string passName, std::string shaderName);
|
||||
PostProcessPipelinePass(PassData& passData, std::string passName, const ParameterList& parameters);
|
||||
PostProcessPipelinePass(PassData& passData, std::string passName, std::string shaderName);
|
||||
PostProcessPipelinePass(const PostProcessPipelinePass&) = delete;
|
||||
PostProcessPipelinePass(PostProcessPipelinePass&&) = delete;
|
||||
~PostProcessPipelinePass() = default;
|
||||
|
||||
void Prepare(RenderFrame& renderFrame);
|
||||
void Prepare(FrameData& frameData) override;
|
||||
|
||||
FramePass& RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t inputColorBufferIndex, std::size_t outputColorBufferIndex);
|
||||
FramePass& RegisterToFrameGraph(FrameGraph& frameGraph, const PassInputOuputs& inputOuputs) override;
|
||||
|
||||
PostProcessPipelinePass& operator=(const PostProcessPipelinePass&) = delete;
|
||||
PostProcessPipelinePass& operator=(PostProcessPipelinePass&&) = delete;
|
||||
|
||||
static std::string GetShaderName(const ParameterList& parameters);
|
||||
|
||||
private:
|
||||
void BuildPipeline();
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,10 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
inline PostProcessPipelinePass::PostProcessPipelinePass(PassData& passData, std::string passName, const ParameterList& parameters) :
|
||||
PostProcessPipelinePass(passData, std::move(passName), GetShaderName(parameters))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Graphics/DebugOff.hpp>
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ namespace Nz
|
|||
|
||||
inline const ViewerInstance& GetViewerInstance() const;
|
||||
|
||||
void PrepareRendering(RenderFrame& renderFrame, const AbstractViewer* viewer) override;
|
||||
void PrepareRendering(RenderFrame& renderFrame, [[maybe_unused]] const AbstractViewer* viewer) override;
|
||||
|
||||
void RegisterMaterialInstance(const MaterialInstance& matInstance) override;
|
||||
void RegisterPassInputs(FramePass& pass, const AbstractViewer* viewer) override;
|
||||
|
|
|
|||
|
|
@ -3,11 +3,25 @@
|
|||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Graphics/Camera.hpp>
|
||||
#include <Nazara/Graphics/Graphics.hpp>
|
||||
#include <Nazara/Graphics/PipelinePassList.hpp>
|
||||
#include <cassert>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
Camera::Camera(const RenderTarget* renderTarget, ProjectionType projectionType) :
|
||||
Camera(renderTarget, Graphics::Instance()->GetDefaultPipelinePasses(), projectionType)
|
||||
{
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<FramePipelinePass>> Camera::BuildPasses(FramePipelinePass::PassData& passData) const
|
||||
{
|
||||
assert(m_framePipelinePasses);
|
||||
return m_framePipelinePasses->BuildPasses(passData);
|
||||
}
|
||||
|
||||
const Color& Camera::GetClearColor() const
|
||||
{
|
||||
return m_clearColor;
|
||||
|
|
@ -41,6 +55,12 @@ namespace Nz
|
|||
return m_viewport;
|
||||
}
|
||||
|
||||
std::size_t Camera::RegisterPasses(const std::vector<std::unique_ptr<FramePipelinePass>>& passes, FrameGraph& frameGraph) const
|
||||
{
|
||||
assert(m_framePipelinePasses);
|
||||
return m_framePipelinePasses->RegisterPasses(passes, frameGraph);
|
||||
}
|
||||
|
||||
void Camera::UpdateTarget(const RenderTarget* renderTarget)
|
||||
{
|
||||
m_onRenderTargetRelease.Disconnect();
|
||||
|
|
|
|||
|
|
@ -8,31 +8,36 @@
|
|||
#include <Nazara/Graphics/FramePipeline.hpp>
|
||||
#include <Nazara/Graphics/ViewerInstance.hpp>
|
||||
#include <Nazara/Renderer/DebugDrawer.hpp>
|
||||
#include <Nazara/Renderer/RenderFrame.hpp>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
DebugDrawPipelinePass::DebugDrawPipelinePass(FramePipeline& owner, AbstractViewer* viewer) :
|
||||
m_viewer(viewer),
|
||||
m_pipeline(owner)
|
||||
{
|
||||
}
|
||||
|
||||
void DebugDrawPipelinePass::Prepare(RenderFrame& renderFrame)
|
||||
void DebugDrawPipelinePass::Prepare(FrameData& frameData)
|
||||
{
|
||||
DebugDrawer& debugDrawer = m_pipeline.GetDebugDrawer();
|
||||
debugDrawer.SetViewerData(m_viewer->GetViewerInstance().GetViewProjMatrix());
|
||||
debugDrawer.Prepare(renderFrame);
|
||||
debugDrawer.Prepare(frameData.renderFrame);
|
||||
}
|
||||
|
||||
FramePass& DebugDrawPipelinePass::RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t inputColorBufferIndex, std::size_t outputColorBufferIndex)
|
||||
FramePass& DebugDrawPipelinePass::RegisterToFrameGraph(FrameGraph& frameGraph, const PassInputOuputs& inputOuputs)
|
||||
{
|
||||
FramePass& debugDrawPass = frameGraph.AddPass("Debug draw pass");
|
||||
debugDrawPass.AddInput(inputColorBufferIndex);
|
||||
debugDrawPass.AddOutput(outputColorBufferIndex);
|
||||
if (inputOuputs.inputCount != 1)
|
||||
throw std::runtime_error("one input expected");
|
||||
|
||||
debugDrawPass.SetExecutionCallback([&]()
|
||||
if (inputOuputs.outputCount != 1)
|
||||
throw std::runtime_error("one output expected");
|
||||
|
||||
FramePass& debugDrawPass = frameGraph.AddPass("Debug draw pass");
|
||||
debugDrawPass.AddInput(inputOuputs.inputAttachments[0]);
|
||||
debugDrawPass.AddOutput(inputOuputs.outputAttachments[0]);
|
||||
|
||||
if (inputOuputs.depthStencilInput != InvalidAttachmentIndex)
|
||||
debugDrawPass.SetDepthStencilInput(inputOuputs.depthStencilInput);
|
||||
|
||||
if (inputOuputs.depthStencilOutput != InvalidAttachmentIndex)
|
||||
debugDrawPass.SetDepthStencilOutput(inputOuputs.depthStencilInput);
|
||||
|
||||
debugDrawPass.SetExecutionCallback([&]
|
||||
{
|
||||
return FramePassExecution::UpdateAndExecute;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <Nazara/Graphics/ElementRendererRegistry.hpp>
|
||||
#include <Nazara/Graphics/FrameGraph.hpp>
|
||||
#include <Nazara/Graphics/FramePipeline.hpp>
|
||||
#include <Nazara/Graphics/Graphics.hpp>
|
||||
#include <Nazara/Graphics/InstancedRenderable.hpp>
|
||||
#include <Nazara/Graphics/Material.hpp>
|
||||
#include <Nazara/Renderer/RenderFrame.hpp>
|
||||
|
|
@ -15,26 +16,14 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
DepthPipelinePass::DepthPipelinePass(FramePipeline& owner, ElementRendererRegistry& elementRegistry, AbstractViewer* viewer, std::size_t passIndex, std::string passName) :
|
||||
m_passIndex(passIndex),
|
||||
m_lastVisibilityHash(0),
|
||||
m_passName(std::move(passName)),
|
||||
m_viewer(viewer),
|
||||
m_elementRegistry(elementRegistry),
|
||||
m_pipeline(owner),
|
||||
m_rebuildCommandBuffer(false),
|
||||
m_rebuildElements(false)
|
||||
void DepthPipelinePass::Prepare(FrameData& frameData)
|
||||
{
|
||||
}
|
||||
|
||||
void DepthPipelinePass::Prepare(RenderFrame& renderFrame, const Frustumf& frustum, const std::vector<FramePipelinePass::VisibleRenderable>& visibleRenderables, std::size_t visibilityHash)
|
||||
{
|
||||
if (m_lastVisibilityHash != visibilityHash || m_rebuildElements) //< FIXME
|
||||
if (m_lastVisibilityHash != frameData.visibilityHash || m_rebuildElements) //< FIXME
|
||||
{
|
||||
renderFrame.PushForRelease(std::move(m_renderElements));
|
||||
frameData.renderFrame.PushForRelease(std::move(m_renderElements));
|
||||
m_renderElements.clear();
|
||||
|
||||
for (const auto& renderableData : visibleRenderables)
|
||||
for (const auto& renderableData : frameData.visibleRenderables)
|
||||
{
|
||||
InstancedRenderable::ElementData elementData{
|
||||
&renderableData.scissorBox,
|
||||
|
|
@ -56,14 +45,14 @@ namespace Nz
|
|||
|
||||
m_renderQueueRegistry.Finalize();
|
||||
|
||||
m_lastVisibilityHash = visibilityHash;
|
||||
m_lastVisibilityHash = frameData.visibilityHash;
|
||||
m_rebuildElements = true;
|
||||
}
|
||||
|
||||
// TODO: Don't sort every frame if no material pass requires distance sorting
|
||||
m_renderQueue.Sort([&](const RenderElement* element)
|
||||
{
|
||||
return element->ComputeSortingScore(frustum, m_renderQueueRegistry);
|
||||
return element->ComputeSortingScore(frameData.frustum, m_renderQueueRegistry);
|
||||
});
|
||||
|
||||
if (m_rebuildElements)
|
||||
|
|
@ -78,7 +67,7 @@ namespace Nz
|
|||
m_elementRendererData[elementType] = elementRenderer.InstanciateData();
|
||||
}
|
||||
|
||||
elementRenderer.Reset(*m_elementRendererData[elementType], renderFrame);
|
||||
elementRenderer.Reset(*m_elementRendererData[elementType], frameData.renderFrame);
|
||||
});
|
||||
|
||||
const auto& viewerInstance = m_viewer->GetViewerInstance();
|
||||
|
|
@ -89,12 +78,12 @@ namespace Nz
|
|||
{
|
||||
ElementRenderer& elementRenderer = m_elementRegistry.GetElementRenderer(elementType);
|
||||
|
||||
elementRenderer.Prepare(viewerInstance, *m_elementRendererData[elementType], renderFrame, elementCount, elements, SparsePtr(&defaultRenderStates, 0));
|
||||
elementRenderer.Prepare(viewerInstance, *m_elementRendererData[elementType], frameData.renderFrame, elementCount, elements, SparsePtr(&defaultRenderStates, 0));
|
||||
});
|
||||
|
||||
m_elementRegistry.ForEachElementRenderer([&](std::size_t elementType, ElementRenderer& elementRenderer)
|
||||
{
|
||||
elementRenderer.PrepareEnd(renderFrame, *m_elementRendererData[elementType]);
|
||||
elementRenderer.PrepareEnd(frameData.renderFrame, *m_elementRendererData[elementType]);
|
||||
});
|
||||
|
||||
m_rebuildCommandBuffer = true;
|
||||
|
|
@ -128,13 +117,25 @@ namespace Nz
|
|||
it->second.usedCount++;
|
||||
}
|
||||
|
||||
FramePass& DepthPipelinePass::RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t outputAttachment)
|
||||
FramePass& DepthPipelinePass::RegisterToFrameGraph(FrameGraph& frameGraph, const PassInputOuputs& inputOuputs)
|
||||
{
|
||||
if (inputOuputs.inputCount > 0)
|
||||
throw std::runtime_error("no input expected");
|
||||
|
||||
if (inputOuputs.outputCount > 0)
|
||||
throw std::runtime_error("no output expected");
|
||||
|
||||
if (inputOuputs.depthStencilInput != InvalidAttachmentIndex)
|
||||
throw std::runtime_error("no depth-stencil input expected");
|
||||
|
||||
if (inputOuputs.depthStencilOutput == InvalidAttachmentIndex)
|
||||
throw std::runtime_error("expected depth-stencil output");
|
||||
|
||||
FramePass& depthPrepass = frameGraph.AddPass(m_passName);
|
||||
depthPrepass.SetDepthStencilOutput(outputAttachment);
|
||||
depthPrepass.SetDepthStencilOutput(inputOuputs.depthStencilOutput);
|
||||
depthPrepass.SetDepthStencilClear(1.f, 0);
|
||||
|
||||
depthPrepass.SetExecutionCallback([&]()
|
||||
depthPrepass.SetExecutionCallback([&]
|
||||
{
|
||||
return (m_rebuildCommandBuffer) ? FramePassExecution::UpdateAndExecute : FramePassExecution::Execute;
|
||||
});
|
||||
|
|
@ -169,4 +170,24 @@ namespace Nz
|
|||
m_materialInstances.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t DepthPipelinePass::GetMaterialPassIndex(const ParameterList& parameters)
|
||||
{
|
||||
Result<long long, ParameterList::Error> passIndexResult = parameters.GetIntegerParameter("MatPassIndex");
|
||||
if (passIndexResult.IsOk())
|
||||
return passIndexResult.GetValue();
|
||||
// TODO: Log error if key is present but not of the right
|
||||
|
||||
Result<std::string_view, ParameterList::Error> passResult = parameters.GetStringViewParameter("MatPass");
|
||||
if (passIndexResult.IsOk())
|
||||
{
|
||||
auto& materialPassRegistry = Graphics::Instance()->GetMaterialPassRegistry();
|
||||
|
||||
std::string_view passName = passResult.GetValue();
|
||||
return materialPassRegistry.GetPassIndex(passName);
|
||||
}
|
||||
// TODO: Log error if key is present but not of the right
|
||||
|
||||
throw std::runtime_error("DepthPipelinePass expect either MatPass or MatPassIndex parameter");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,7 +118,15 @@ namespace Nz
|
|||
std::size_t visibilityHash = 5U;
|
||||
const auto& visibleRenderables = m_pipeline.FrustumCull(lightFrustum, 0xFFFFFFFF, visibilityHash);
|
||||
|
||||
cascade.depthPass->Prepare(renderFrame, lightFrustum, visibleRenderables, visibilityHash);
|
||||
FramePipelinePass::FrameData passData = {
|
||||
nullptr,
|
||||
frustum,
|
||||
renderFrame,
|
||||
visibleRenderables,
|
||||
visibilityHash
|
||||
};
|
||||
|
||||
cascade.depthPass->Prepare(passData);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -233,7 +241,11 @@ namespace Nz
|
|||
CascadeData& cascade = viewerData.cascades[i];
|
||||
|
||||
cascade.attachmentIndex = frameGraph.AddAttachmentArrayLayer(viewerData.textureArrayAttachmentIndex, i);
|
||||
cascade.depthPass->RegisterToFrameGraph(frameGraph, cascade.attachmentIndex);
|
||||
|
||||
FramePipelinePass::PassInputOuputs passInputOuputs;
|
||||
passInputOuputs.depthStencilOutput = cascade.attachmentIndex;
|
||||
|
||||
cascade.depthPass->RegisterToFrameGraph(frameGraph, passInputOuputs);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -254,7 +266,13 @@ namespace Nz
|
|||
shadowViewer.UpdateRenderMask(0xFFFFFFFF);
|
||||
shadowViewer.UpdateViewport(Recti(0, 0, SafeCast<int>(shadowMapSize), SafeCast<int>(shadowMapSize)));
|
||||
|
||||
cascade.depthPass.emplace(m_pipeline, m_elementRegistry, &shadowViewer, shadowPassIndex, Format("Cascade #{}", cascadeIndex++));
|
||||
FramePipelinePass::PassData passData = {
|
||||
&shadowViewer,
|
||||
m_elementRegistry,
|
||||
m_pipeline
|
||||
};
|
||||
|
||||
cascade.depthPass.emplace(passData, Format("Cascade #{}", cascadeIndex++), shadowPassIndex);
|
||||
}
|
||||
|
||||
m_pipeline.ForEachRegisteredMaterialInstance([&](const MaterialInstance& matInstance)
|
||||
|
|
|
|||
|
|
@ -3,11 +3,11 @@
|
|||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Graphics/ForwardFramePipeline.hpp>
|
||||
#include <Nazara/Graphics/AbstractViewer.hpp>
|
||||
#include <Nazara/Graphics/FrameGraph.hpp>
|
||||
#include <Nazara/Graphics/Graphics.hpp>
|
||||
#include <Nazara/Graphics/InstancedRenderable.hpp>
|
||||
#include <Nazara/Graphics/Material.hpp>
|
||||
#include <Nazara/Graphics/PipelineViewer.hpp>
|
||||
#include <Nazara/Graphics/PointLight.hpp>
|
||||
#include <Nazara/Graphics/PredefinedShaderStructs.hpp>
|
||||
#include <Nazara/Graphics/RenderElement.hpp>
|
||||
|
|
@ -110,16 +110,6 @@ namespace Nz
|
|||
lightData->onLightInvalidated.Connect(lightData->light->OnLightDataInvalided, [=](Light*)
|
||||
{
|
||||
//TODO: Switch lights to storage buffers so they can all be part of GPU memory
|
||||
for (auto& viewerData : m_viewerPool)
|
||||
{
|
||||
if (viewerData.pendingDestruction)
|
||||
continue;
|
||||
|
||||
UInt32 viewerRenderMask = viewerData.viewer->GetRenderMask();
|
||||
|
||||
if (viewerRenderMask & renderMask)
|
||||
viewerData.forwardPass->InvalidateElements();
|
||||
}
|
||||
});
|
||||
|
||||
lightData->onLightShadowCastingChanged.Connect(lightData->light->OnLightShadowCastingChanged, [=](Light* light, bool isCastingShadows)
|
||||
|
|
@ -194,10 +184,11 @@ namespace Nz
|
|||
|
||||
if (viewerRenderMask & renderMask)
|
||||
{
|
||||
if (viewerData.depthPrepass)
|
||||
viewerData.depthPrepass->InvalidateElements();
|
||||
|
||||
viewerData.forwardPass->InvalidateElements();
|
||||
for (auto& passPtr : viewerData.passes)
|
||||
{
|
||||
if (passPtr->ShouldNotify(FramePipelineNotification::ElementInvalidation))
|
||||
passPtr->InvalidateElements();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -213,10 +204,11 @@ namespace Nz
|
|||
if (viewerData.pendingDestruction)
|
||||
continue;
|
||||
|
||||
if (viewerData.depthPrepass)
|
||||
viewerData.depthPrepass->RegisterMaterialInstance(*newMaterial);
|
||||
|
||||
viewerData.forwardPass->RegisterMaterialInstance(*newMaterial);
|
||||
for (auto& passPtr : viewerData.passes)
|
||||
{
|
||||
if (passPtr->ShouldNotify(FramePipelineNotification::MaterialInstanceRegistration))
|
||||
passPtr->RegisterMaterialInstance(*newMaterial);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -230,10 +222,11 @@ namespace Nz
|
|||
if (viewerData.pendingDestruction)
|
||||
continue;
|
||||
|
||||
if (viewerData.depthPrepass)
|
||||
viewerData.depthPrepass->UnregisterMaterialInstance(*prevMaterial);
|
||||
|
||||
viewerData.forwardPass->UnregisterMaterialInstance(*prevMaterial);
|
||||
for (auto& passPtr : viewerData.passes)
|
||||
{
|
||||
if (passPtr->ShouldNotify(FramePipelineNotification::MaterialInstanceRegistration))
|
||||
passPtr->UnregisterMaterialInstance(*prevMaterial);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -250,10 +243,11 @@ namespace Nz
|
|||
if (viewerData.pendingDestruction)
|
||||
continue;
|
||||
|
||||
if (viewerData.depthPrepass)
|
||||
viewerData.depthPrepass->RegisterMaterialInstance(*mat);
|
||||
|
||||
viewerData.forwardPass->RegisterMaterialInstance(*mat);
|
||||
for (auto& passPtr : viewerData.passes)
|
||||
{
|
||||
if (passPtr->ShouldNotify(FramePipelineNotification::MaterialInstanceRegistration))
|
||||
passPtr->RegisterMaterialInstance(*mat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -275,28 +269,24 @@ namespace Nz
|
|||
return skeletonInstanceIndex;
|
||||
}
|
||||
|
||||
std::size_t ForwardFramePipeline::RegisterViewer(AbstractViewer* viewerInstance, Int32 renderOrder, FramePipelineExtraPassFlags passFlags)
|
||||
std::size_t ForwardFramePipeline::RegisterViewer(PipelineViewer* viewerInstance, Int32 renderOrder)
|
||||
{
|
||||
std::size_t depthPassIndex = Graphics::Instance()->GetMaterialPassRegistry().GetPassIndex("DepthPass");
|
||||
|
||||
std::size_t viewerIndex;
|
||||
auto& viewerData = *m_viewerPool.Allocate(viewerIndex);
|
||||
viewerData.renderOrder = renderOrder;
|
||||
viewerData.forwardPass = std::make_unique<ForwardPipelinePass>(*this, m_elementRegistry, viewerInstance);
|
||||
viewerData.viewer = viewerInstance;
|
||||
viewerData.onTransferRequired.Connect(viewerInstance->GetViewerInstance().OnTransferRequired, [this](TransferInterface* transferInterface)
|
||||
{
|
||||
m_transferSet.insert(transferInterface);
|
||||
});
|
||||
|
||||
if (passFlags.Test(FramePipelineExtraPass::DebugDraw))
|
||||
viewerData.debugDrawPass = std::make_unique<DebugDrawPipelinePass>(*this, viewerInstance);
|
||||
FramePipelinePass::PassData passData = {
|
||||
viewerInstance,
|
||||
m_elementRegistry,
|
||||
*this
|
||||
};
|
||||
|
||||
if (passFlags.Test(FramePipelineExtraPass::DepthPrepass))
|
||||
viewerData.depthPrepass = std::make_unique<DepthPipelinePass>(*this, m_elementRegistry, viewerInstance, depthPassIndex, "Depth pre-pass");
|
||||
|
||||
if (passFlags.Test(FramePipelineExtraPass::GammaCorrection))
|
||||
viewerData.gammaCorrectionPass = std::make_unique<PostProcessPipelinePass>(*this, "Gamma correction", "PostProcess.GammaCorrection");
|
||||
viewerData.passes = viewerInstance->BuildPasses(passData);
|
||||
|
||||
m_transferSet.insert(&viewerInstance->GetViewerInstance());
|
||||
|
||||
|
|
@ -446,16 +436,16 @@ namespace Nz
|
|||
std::size_t visibilityHash = 5;
|
||||
const auto& visibleRenderables = FrustumCull(viewerData.frame.frustum, renderMask, visibilityHash);
|
||||
|
||||
if (viewerData.depthPrepass)
|
||||
viewerData.depthPrepass->Prepare(renderFrame, viewerData.frame.frustum, visibleRenderables, visibilityHash);
|
||||
FramePipelinePass::FrameData passData = {
|
||||
&viewerData.frame.visibleLights,
|
||||
viewerData.frame.frustum,
|
||||
renderFrame,
|
||||
visibleRenderables,
|
||||
visibilityHash
|
||||
};
|
||||
|
||||
viewerData.forwardPass->Prepare(renderFrame, viewerData.frame.frustum, visibleRenderables, viewerData.frame.visibleLights, visibilityHash);
|
||||
|
||||
if (viewerData.gammaCorrectionPass)
|
||||
viewerData.gammaCorrectionPass->Prepare(renderFrame);
|
||||
|
||||
if (viewerData.debugDrawPass)
|
||||
viewerData.debugDrawPass->Prepare(renderFrame);
|
||||
for (auto& passPtr : viewerData.passes)
|
||||
passPtr->Prepare(passData);
|
||||
}
|
||||
|
||||
if (frameGraphInvalidated)
|
||||
|
|
@ -587,10 +577,11 @@ namespace Nz
|
|||
if (viewerData.pendingDestruction)
|
||||
continue;
|
||||
|
||||
if (viewerData.depthPrepass)
|
||||
viewerData.depthPrepass->UnregisterMaterialInstance(*material);
|
||||
|
||||
viewerData.forwardPass->UnregisterMaterialInstance(*material);
|
||||
for (auto& passPtr : viewerData.passes)
|
||||
{
|
||||
if (passPtr->ShouldNotify(FramePipelineNotification::MaterialInstanceRegistration))
|
||||
passPtr->UnregisterMaterialInstance(*material);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -654,10 +645,11 @@ namespace Nz
|
|||
|
||||
if (viewerRenderMask & renderableData->renderMask)
|
||||
{
|
||||
if (viewerData.depthPrepass)
|
||||
viewerData.depthPrepass->InvalidateElements();
|
||||
|
||||
viewerData.forwardPass->InvalidateElements();
|
||||
for (auto& passPtr : viewerData.passes)
|
||||
{
|
||||
if (passPtr->ShouldNotify(FramePipelineNotification::ElementInvalidation))
|
||||
passPtr->InvalidateElements();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -677,10 +669,11 @@ namespace Nz
|
|||
|
||||
if (viewerRenderMask & renderableData->renderMask)
|
||||
{
|
||||
if (viewerData.depthPrepass)
|
||||
viewerData.depthPrepass->InvalidateElements();
|
||||
|
||||
viewerData.forwardPass->InvalidateElements();
|
||||
for (auto& passPtr : viewerData.passes)
|
||||
{
|
||||
if (passPtr->ShouldNotify(FramePipelineNotification::ElementInvalidation))
|
||||
passPtr->InvalidateElements();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -720,46 +713,7 @@ namespace Nz
|
|||
lightData->shadowData->RegisterToFrameGraph(frameGraph, viewerData.viewer);
|
||||
}
|
||||
|
||||
viewerData.forwardColorAttachment = frameGraph.AddAttachment({
|
||||
"Forward output",
|
||||
PixelFormat::RGBA8
|
||||
});
|
||||
|
||||
viewerData.depthStencilAttachment = frameGraph.AddAttachment({
|
||||
"Depth-stencil buffer",
|
||||
Graphics::Instance()->GetPreferredDepthStencilFormat()
|
||||
});
|
||||
|
||||
if (viewerData.depthPrepass)
|
||||
viewerData.depthPrepass->RegisterToFrameGraph(frameGraph, viewerData.depthStencilAttachment);
|
||||
|
||||
FramePass& forwardPass = viewerData.forwardPass->RegisterToFrameGraph(frameGraph, viewerData.forwardColorAttachment, viewerData.depthStencilAttachment, viewerData.depthPrepass != nullptr);
|
||||
for (std::size_t i : m_shadowCastingLights.IterBits())
|
||||
{
|
||||
LightData* lightData = m_lightPool.RetrieveFromIndex(i);
|
||||
if ((renderMask & lightData->renderMask) != 0)
|
||||
lightData->shadowData->RegisterPassInputs(forwardPass, (lightData->shadowData->IsPerViewer()) ? viewerData.viewer : nullptr);
|
||||
}
|
||||
|
||||
viewerData.finalColorAttachment = viewerData.forwardColorAttachment;
|
||||
|
||||
if (viewerData.gammaCorrectionPass)
|
||||
{
|
||||
std::size_t postGammaColorAttachment = frameGraph.AddAttachment({
|
||||
"Gamma-corrected output",
|
||||
PixelFormat::RGBA8
|
||||
});
|
||||
|
||||
viewerData.gammaCorrectionPass->RegisterToFrameGraph(frameGraph, viewerData.finalColorAttachment, postGammaColorAttachment);
|
||||
viewerData.finalColorAttachment = postGammaColorAttachment;
|
||||
}
|
||||
|
||||
if (viewerData.debugDrawPass)
|
||||
{
|
||||
viewerData.debugColorAttachment = frameGraph.AddAttachmentProxy("Debug draw output", viewerData.finalColorAttachment);
|
||||
viewerData.debugDrawPass->RegisterToFrameGraph(frameGraph, viewerData.finalColorAttachment, viewerData.debugColorAttachment);
|
||||
viewerData.finalColorAttachment = viewerData.debugColorAttachment;
|
||||
}
|
||||
viewerData.finalColorAttachment = viewerData.viewer->RegisterPasses(viewerData.passes, frameGraph);
|
||||
}
|
||||
|
||||
using ViewerPair = std::pair<const RenderTarget*, const ViewerData*>;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include <Nazara/Graphics/ForwardPipelinePass.hpp>
|
||||
#include <Nazara/Graphics/AbstractViewer.hpp>
|
||||
#include <Nazara/Graphics/DirectionalLight.hpp>
|
||||
#include <Nazara/Graphics/DirectionalLightShadowData.hpp>
|
||||
#include <Nazara/Graphics/ElementRendererRegistry.hpp>
|
||||
#include <Nazara/Graphics/FrameGraph.hpp>
|
||||
#include <Nazara/Graphics/FramePipeline.hpp>
|
||||
|
|
@ -12,9 +13,8 @@
|
|||
#include <Nazara/Graphics/InstancedRenderable.hpp>
|
||||
#include <Nazara/Graphics/Material.hpp>
|
||||
#include <Nazara/Graphics/PointLight.hpp>
|
||||
#include <Nazara/Graphics/SpotLight.hpp>
|
||||
#include <Nazara/Graphics/PredefinedShaderStructs.hpp>
|
||||
#include <Nazara/Graphics/DirectionalLightShadowData.hpp>
|
||||
#include <Nazara/Graphics/SpotLight.hpp>
|
||||
#include <Nazara/Graphics/SpotLightShadowData.hpp>
|
||||
#include <Nazara/Graphics/ViewerInstance.hpp>
|
||||
#include <Nazara/Renderer/CommandBufferBuilder.hpp>
|
||||
|
|
@ -23,11 +23,13 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
ForwardPipelinePass::ForwardPipelinePass(FramePipeline& owner, ElementRendererRegistry& elementRegistry, AbstractViewer* viewer) :
|
||||
ForwardPipelinePass::ForwardPipelinePass(PassData& passData, std::string passName, const ParameterList& /*parameters*/) :
|
||||
FramePipelinePass(FramePipelineNotification::ElementInvalidation | FramePipelineNotification::MaterialInstanceRegistration),
|
||||
m_lastVisibilityHash(0),
|
||||
m_viewer(viewer),
|
||||
m_elementRegistry(elementRegistry),
|
||||
m_pipeline(owner),
|
||||
m_passName(std::move(passName)),
|
||||
m_viewer(passData.viewer),
|
||||
m_elementRegistry(passData.elementRegistry),
|
||||
m_pipeline(passData.pipeline),
|
||||
m_pendingLightUploadAllocation(nullptr),
|
||||
m_rebuildCommandBuffer(false),
|
||||
m_rebuildElements(false)
|
||||
|
|
@ -42,14 +44,16 @@ namespace Nz
|
|||
m_renderState.lightData = RenderBufferView(m_lightDataBuffer.get());
|
||||
}
|
||||
|
||||
void ForwardPipelinePass::Prepare(RenderFrame& renderFrame, const Frustumf& frustum, const std::vector<FramePipelinePass::VisibleRenderable>& visibleRenderables, const Bitset<UInt64>& visibleLights, std::size_t visibilityHash)
|
||||
void ForwardPipelinePass::Prepare(FrameData& frameData)
|
||||
{
|
||||
if (m_lastVisibilityHash != visibilityHash || m_rebuildElements) //< FIXME
|
||||
NazaraAssert(frameData.visibleLights, "visible lights must be valid");
|
||||
|
||||
if (m_lastVisibilityHash != frameData.visibilityHash || m_rebuildElements) //< FIXME
|
||||
{
|
||||
renderFrame.PushForRelease(std::move(m_renderElements));
|
||||
frameData.renderFrame.PushForRelease(std::move(m_renderElements));
|
||||
m_renderElements.clear();
|
||||
|
||||
for (const auto& renderableData : visibleRenderables)
|
||||
for (const auto& renderableData : frameData.visibleRenderables)
|
||||
{
|
||||
InstancedRenderable::ElementData elementData{
|
||||
&renderableData.scissorBox,
|
||||
|
|
@ -71,17 +75,17 @@ namespace Nz
|
|||
|
||||
m_renderQueueRegistry.Finalize();
|
||||
|
||||
m_lastVisibilityHash = visibilityHash;
|
||||
m_lastVisibilityHash = frameData.visibilityHash;
|
||||
InvalidateElements();
|
||||
}
|
||||
|
||||
// TODO: Don't sort every frame if no material pass requires distance sorting
|
||||
m_renderQueue.Sort([&](const RenderElement* element)
|
||||
{
|
||||
return element->ComputeSortingScore(frustum, m_renderQueueRegistry);
|
||||
return element->ComputeSortingScore(frameData.frustum, m_renderQueueRegistry);
|
||||
});
|
||||
|
||||
PrepareLights(renderFrame, frustum, visibleLights);
|
||||
PrepareLights(frameData.renderFrame, frameData.frustum, *frameData.visibleLights);
|
||||
|
||||
if (m_rebuildElements)
|
||||
{
|
||||
|
|
@ -93,7 +97,7 @@ namespace Nz
|
|||
if (!m_elementRendererData[elementType])
|
||||
m_elementRendererData[elementType] = elementRenderer.InstanciateData();
|
||||
|
||||
elementRenderer.Reset(*m_elementRendererData[elementType], renderFrame);
|
||||
elementRenderer.Reset(*m_elementRendererData[elementType], frameData.renderFrame);
|
||||
});
|
||||
|
||||
const auto& viewerInstance = m_viewer->GetViewerInstance();
|
||||
|
|
@ -101,12 +105,12 @@ namespace Nz
|
|||
m_elementRegistry.ProcessRenderQueue(m_renderQueue, [&](std::size_t elementType, const Pointer<const RenderElement>* elements, std::size_t elementCount)
|
||||
{
|
||||
ElementRenderer& elementRenderer = m_elementRegistry.GetElementRenderer(elementType);
|
||||
elementRenderer.Prepare(viewerInstance, *m_elementRendererData[elementType], renderFrame, elementCount, elements, SparsePtr(&m_renderState, 0));
|
||||
elementRenderer.Prepare(viewerInstance, *m_elementRendererData[elementType], frameData.renderFrame, elementCount, elements, SparsePtr(&m_renderState, 0));
|
||||
});
|
||||
|
||||
m_elementRegistry.ForEachElementRenderer([&](std::size_t elementType, ElementRenderer& elementRenderer)
|
||||
{
|
||||
elementRenderer.PrepareEnd(renderFrame, *m_elementRendererData[elementType]);
|
||||
elementRenderer.PrepareEnd(frameData.renderFrame, *m_elementRendererData[elementType]);
|
||||
});
|
||||
|
||||
m_rebuildCommandBuffer = true;
|
||||
|
|
@ -140,14 +144,23 @@ namespace Nz
|
|||
it->second.usedCount++;
|
||||
}
|
||||
|
||||
FramePass& ForwardPipelinePass::RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t colorBufferIndex, std::size_t depthBufferIndex, bool hasDepthPrepass)
|
||||
FramePass& ForwardPipelinePass::RegisterToFrameGraph(FrameGraph& frameGraph, const PassInputOuputs& inputOuputs)
|
||||
{
|
||||
FramePass& forwardPass = frameGraph.AddPass("Forward pass");
|
||||
forwardPass.AddOutput(colorBufferIndex);
|
||||
if (hasDepthPrepass)
|
||||
forwardPass.SetDepthStencilInput(depthBufferIndex);
|
||||
if (inputOuputs.inputCount > 0)
|
||||
throw std::runtime_error("no input expected");
|
||||
|
||||
forwardPass.SetDepthStencilOutput(depthBufferIndex);
|
||||
if (inputOuputs.outputCount != 1)
|
||||
throw std::runtime_error("one output expected");
|
||||
|
||||
if (inputOuputs.depthStencilOutput == InvalidAttachmentIndex)
|
||||
throw std::runtime_error("expected depth-stencil output");
|
||||
|
||||
FramePass& forwardPass = frameGraph.AddPass(m_passName);
|
||||
forwardPass.AddOutput(inputOuputs.outputAttachments[0]);
|
||||
if (inputOuputs.depthStencilInput != FramePipelinePass::InvalidAttachmentIndex)
|
||||
forwardPass.SetDepthStencilInput(inputOuputs.depthStencilInput);
|
||||
|
||||
forwardPass.SetDepthStencilOutput(inputOuputs.depthStencilOutput);
|
||||
|
||||
forwardPass.SetClearColor(0, m_viewer->GetClearColor());
|
||||
forwardPass.SetDepthStencilClear(1.f, 0);
|
||||
|
|
@ -188,7 +201,7 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
void ForwardPipelinePass::OnTransfer(RenderFrame& renderFrame, CommandBufferBuilder& builder)
|
||||
void ForwardPipelinePass::OnTransfer(RenderFrame& /*renderFrame*/, CommandBufferBuilder& builder)
|
||||
{
|
||||
assert(m_pendingLightUploadAllocation);
|
||||
builder.CopyBuffer(*m_pendingLightUploadAllocation, RenderBufferView(m_lightDataBuffer.get()));
|
||||
|
|
|
|||
|
|
@ -8,4 +8,16 @@
|
|||
namespace Nz
|
||||
{
|
||||
FramePipelinePass::~FramePipelinePass() = default;
|
||||
|
||||
void FramePipelinePass::InvalidateElements()
|
||||
{
|
||||
}
|
||||
|
||||
void FramePipelinePass::RegisterMaterialInstance(const MaterialInstance& materialInstance)
|
||||
{
|
||||
}
|
||||
|
||||
void FramePipelinePass::UnregisterMaterialInstance(const MaterialInstance& materialInstance)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,9 +5,13 @@
|
|||
#include <Nazara/Graphics/Graphics.hpp>
|
||||
#include <Nazara/Core/AppFilesystemComponent.hpp>
|
||||
#include <Nazara/Core/CommandLineParameters.hpp>
|
||||
#include <Nazara/Graphics/DepthPipelinePass.hpp>
|
||||
#include <Nazara/Graphics/ForwardPipelinePass.hpp>
|
||||
#include <Nazara/Graphics/GuillotineTextureAtlas.hpp>
|
||||
#include <Nazara/Graphics/MaterialInstance.hpp>
|
||||
#include <Nazara/Graphics/MaterialPipeline.hpp>
|
||||
#include <Nazara/Graphics/PipelinePassList.hpp>
|
||||
#include <Nazara/Graphics/PostProcessPipelinePass.hpp>
|
||||
#include <Nazara/Graphics/PredefinedMaterials.hpp>
|
||||
#include <Nazara/Graphics/PredefinedShaderStructs.hpp>
|
||||
#include <Nazara/Graphics/Formats/TextureLoader.hpp>
|
||||
|
|
@ -148,6 +152,8 @@ namespace Nz
|
|||
|
||||
MaterialPipeline::Initialize();
|
||||
BuildDefaultMaterials();
|
||||
RegisterPipelinePasses();
|
||||
BuildDefaultPipelinePasses();
|
||||
|
||||
Font::SetDefaultAtlas(std::make_shared<GuillotineTextureAtlas>(*m_renderDevice));
|
||||
|
||||
|
|
@ -364,6 +370,43 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
void Graphics::BuildDefaultPipelinePasses()
|
||||
{
|
||||
m_defaultPipelinePasses = std::make_shared<PipelinePassList>();
|
||||
|
||||
// Forward pass
|
||||
std::size_t forwardColorOutput = m_defaultPipelinePasses->AddAttachment({
|
||||
"Forward output",
|
||||
PixelFormat::RGBA16F
|
||||
});
|
||||
|
||||
std::size_t forwardDepthOutput = m_defaultPipelinePasses->AddAttachment({
|
||||
"Depth-stencil buffer",
|
||||
m_preferredDepthStencilFormat
|
||||
});
|
||||
|
||||
std::size_t forwardPass = m_defaultPipelinePasses->AddPass("ForwardPass", m_pipelinePassRegistry.GetPassIndex("Forward"));
|
||||
|
||||
m_defaultPipelinePasses->SetPassOutput(forwardPass, 0, forwardColorOutput);
|
||||
m_defaultPipelinePasses->SetPassDepthStencilOutput(forwardPass, forwardDepthOutput);
|
||||
|
||||
// Gamma correction
|
||||
std::size_t gammaCorrectionOutput = m_defaultPipelinePasses->AddAttachment({
|
||||
"Gamma-corrected output",
|
||||
PixelFormat::RGBA8
|
||||
});
|
||||
|
||||
ParameterList gammaCorrectionParameters;
|
||||
gammaCorrectionParameters.SetParameter("Shader", "PostProcess.GammaCorrection");
|
||||
|
||||
std::size_t gammaCorrectionPass = m_defaultPipelinePasses->AddPass("Gamma correction", m_pipelinePassRegistry.GetPassIndex("PostProcess"), gammaCorrectionParameters);
|
||||
|
||||
m_defaultPipelinePasses->SetPassInput(gammaCorrectionPass, 0, forwardColorOutput);
|
||||
m_defaultPipelinePasses->SetPassOutput(gammaCorrectionPass, 0, gammaCorrectionOutput);
|
||||
|
||||
m_defaultPipelinePasses->SetFinalOutput(gammaCorrectionOutput);
|
||||
}
|
||||
|
||||
void Graphics::BuildDefaultTextures()
|
||||
{
|
||||
// Depth textures (white but with a depth format)
|
||||
|
|
@ -419,6 +462,12 @@ namespace Nz
|
|||
m_materialPassRegistry.RegisterPass("DistanceShadowPass");
|
||||
}
|
||||
|
||||
void Graphics::RegisterPipelinePasses()
|
||||
{
|
||||
m_pipelinePassRegistry.RegisterPass<DepthPipelinePass>("Depth");
|
||||
m_pipelinePassRegistry.RegisterPass<ForwardPipelinePass>("Forward");
|
||||
m_pipelinePassRegistry.RegisterPass<PostProcessPipelinePass>("PostProcess");
|
||||
}
|
||||
void Graphics::RegisterShaderModules()
|
||||
{
|
||||
m_shaderModuleResolver = std::make_shared<nzsl::FilesystemModuleResolver>();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
// Copyright (C) 2023 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Graphics/PipelinePassList.hpp>
|
||||
#include <Nazara/Graphics/FrameGraph.hpp>
|
||||
#include <Nazara/Graphics/FramePipelinePassRegistry.hpp>
|
||||
#include <Nazara/Graphics/Graphics.hpp>
|
||||
#include <NazaraUtils/StackArray.hpp>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
std::vector<std::unique_ptr<FramePipelinePass>> PipelinePassList::BuildPasses(FramePipelinePass::PassData& passData) const
|
||||
{
|
||||
auto& passRegistry = Graphics::Instance()->GetFramePipelinePassRegistry();
|
||||
|
||||
std::vector<std::unique_ptr<FramePipelinePass>> passes;
|
||||
for (const Pass& pass : m_passes)
|
||||
passes.emplace_back(passRegistry.BuildPass(pass.implIndex, passData, pass.name, pass.parameterList));
|
||||
|
||||
return passes;
|
||||
}
|
||||
|
||||
std::size_t PipelinePassList::RegisterPasses(const std::vector<std::unique_ptr<FramePipelinePass>>& passes, FrameGraph& frameGraph) const
|
||||
{
|
||||
NazaraAssert(m_passes.size() == passes.size(), "pass vector size doesn't match passlist size");
|
||||
|
||||
StackArray<std::size_t> attachmentIndices = NazaraStackArrayNoInit(std::size_t, m_attachments.size());
|
||||
for (std::size_t i = 0; i < m_attachments.size(); ++i)
|
||||
attachmentIndices[i] = frameGraph.AddAttachment(m_attachments[i]);
|
||||
|
||||
auto GetAttachmentIndex = [&](std::size_t attachmentIndex)
|
||||
{
|
||||
if (attachmentIndex == NoAttachment)
|
||||
return NoAttachment;
|
||||
|
||||
assert(attachmentIndex < m_attachments.size());
|
||||
return attachmentIndices[attachmentIndex];
|
||||
};
|
||||
|
||||
for (std::size_t i = 0; i < passes.size(); ++i)
|
||||
{
|
||||
const Pass& passData = m_passes[i];
|
||||
|
||||
std::array<std::size_t, MaxPassAttachment> inputs;
|
||||
for (std::size_t j = 0; j < passData.inputs.size(); ++j)
|
||||
inputs[j] = GetAttachmentIndex(passData.inputs[j]);
|
||||
|
||||
std::array<std::size_t, MaxPassAttachment> outputs;
|
||||
for (std::size_t j = 0; j < passData.outputs.size(); ++j)
|
||||
outputs[j] = GetAttachmentIndex(passData.outputs[j]);
|
||||
|
||||
FramePipelinePass::PassInputOuputs passInputOuputs;
|
||||
passInputOuputs.depthStencilInput = GetAttachmentIndex(passData.depthStencilInput);
|
||||
passInputOuputs.depthStencilOutput = GetAttachmentIndex(passData.depthStencilOutput);
|
||||
passInputOuputs.inputAttachments = inputs.data();
|
||||
passInputOuputs.inputCount = passData.inputs.size();
|
||||
passInputOuputs.outputAttachments = outputs.data();
|
||||
passInputOuputs.outputCount = passData.outputs.size();
|
||||
|
||||
passes[i]->RegisterToFrameGraph(frameGraph, passInputOuputs);
|
||||
}
|
||||
|
||||
return GetAttachmentIndex(m_finalOutputAttachment);
|
||||
}
|
||||
}
|
||||
|
|
@ -83,7 +83,13 @@ namespace Nz
|
|||
|
||||
m_pipeline.QueueTransfer(&viewerInstance);
|
||||
|
||||
m_directions[i].depthPass.emplace(m_pipeline, elementRegistry, &viewer, shadowPassIndex, std::string(s_dirNames[i]));
|
||||
FramePipelinePass::PassData passData = {
|
||||
&viewer,
|
||||
elementRegistry,
|
||||
m_pipeline
|
||||
};
|
||||
|
||||
m_directions[i].depthPass.emplace(passData, std::string(s_dirNames[i]), shadowPassIndex);
|
||||
}
|
||||
|
||||
m_pipeline.ForEachRegisteredMaterialInstance([this](const MaterialInstance& matInstance)
|
||||
|
|
@ -106,7 +112,15 @@ namespace Nz
|
|||
std::size_t visibilityHash = 5U;
|
||||
const auto& visibleRenderables = m_pipeline.FrustumCull(frustum, 0xFFFFFFFF, visibilityHash);
|
||||
|
||||
direction.depthPass->Prepare(renderFrame, frustum, visibleRenderables, visibilityHash);
|
||||
FramePipelinePass::FrameData passData = {
|
||||
nullptr,
|
||||
frustum,
|
||||
renderFrame,
|
||||
visibleRenderables,
|
||||
visibilityHash
|
||||
};
|
||||
|
||||
direction.depthPass->Prepare(passData);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -144,7 +158,11 @@ namespace Nz
|
|||
{
|
||||
DirectionData& direction = m_directions[i];
|
||||
direction.attachmentIndex = frameGraph.AddAttachmentCubeFace(m_cubeAttachmentIndex, static_cast<CubemapFace>(i));
|
||||
direction.depthPass->RegisterToFrameGraph(frameGraph, direction.attachmentIndex);
|
||||
|
||||
FramePipelinePass::PassInputOuputs passInputOuputs;
|
||||
passInputOuputs.depthStencilOutput = direction.attachmentIndex;
|
||||
|
||||
direction.depthPass->RegisterToFrameGraph(frameGraph, passInputOuputs);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,10 +11,11 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
PostProcessPipelinePass::PostProcessPipelinePass(FramePipeline& owner, std::string passName, std::string shaderName) :
|
||||
PostProcessPipelinePass::PostProcessPipelinePass(PassData& passData, std::string passName, std::string shaderName) :
|
||||
FramePipelinePass({}),
|
||||
m_passName(std::move(passName)),
|
||||
m_shader(nzsl::ShaderStageType::Fragment | nzsl::ShaderStageType::Vertex, std::move(shaderName)),
|
||||
m_pipeline(owner)
|
||||
m_pipeline(passData.pipeline)
|
||||
{
|
||||
RenderPipelineLayoutInfo layoutInfo;
|
||||
layoutInfo.bindings.assign({
|
||||
|
|
@ -37,25 +38,39 @@ namespace Nz
|
|||
BuildPipeline();
|
||||
}
|
||||
|
||||
void PostProcessPipelinePass::Prepare(RenderFrame& renderFrame)
|
||||
void PostProcessPipelinePass::Prepare(FrameData& frameData)
|
||||
{
|
||||
if (m_nextRenderPipeline)
|
||||
{
|
||||
if (m_renderPipeline)
|
||||
renderFrame.PushForRelease(std::move(m_renderPipeline));
|
||||
frameData.renderFrame.PushForRelease(std::move(m_renderPipeline));
|
||||
|
||||
m_renderPipeline = std::move(m_nextRenderPipeline);
|
||||
m_rebuildFramePass = true;
|
||||
}
|
||||
}
|
||||
|
||||
FramePass& PostProcessPipelinePass::RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t inputColorBufferIndex, std::size_t outputColorBufferIndex)
|
||||
FramePass& PostProcessPipelinePass::RegisterToFrameGraph(FrameGraph& frameGraph, const PassInputOuputs& inputOuputs)
|
||||
{
|
||||
if (inputOuputs.inputCount != 1)
|
||||
throw std::runtime_error("one input expected");
|
||||
|
||||
if (inputOuputs.outputCount != 1)
|
||||
throw std::runtime_error("one output expected");
|
||||
|
||||
if (inputOuputs.depthStencilInput != InvalidAttachmentIndex)
|
||||
throw std::runtime_error("unexpected depth-stencil output");
|
||||
|
||||
if (inputOuputs.depthStencilOutput != InvalidAttachmentIndex)
|
||||
throw std::runtime_error("unexpected depth-stencil output");
|
||||
|
||||
std::size_t inputColorBufferIndex = inputOuputs.inputAttachments[0];
|
||||
|
||||
FramePass& postProcess = frameGraph.AddPass(m_passName);
|
||||
postProcess.AddInput(inputColorBufferIndex);
|
||||
postProcess.AddOutput(outputColorBufferIndex);
|
||||
postProcess.AddOutput(inputOuputs.outputAttachments[0]);
|
||||
|
||||
postProcess.SetExecutionCallback([&]()
|
||||
postProcess.SetExecutionCallback([&]
|
||||
{
|
||||
return (m_rebuildFramePass) ? FramePassExecution::UpdateAndExecute : FramePassExecution::Execute;
|
||||
});
|
||||
|
|
@ -94,6 +109,16 @@ namespace Nz
|
|||
return postProcess;
|
||||
}
|
||||
|
||||
std::string PostProcessPipelinePass::GetShaderName(const ParameterList& parameters)
|
||||
{
|
||||
Result<std::string, ParameterList::Error> shaderResult = parameters.GetStringParameter("Shader");
|
||||
if (shaderResult.IsOk())
|
||||
return std::move(shaderResult).GetValue();
|
||||
// TODO: Log error if key is present but not of the right
|
||||
|
||||
throw std::runtime_error("PostProcessPipelinePass expect a Shader parameter");
|
||||
}
|
||||
|
||||
void PostProcessPipelinePass::BuildPipeline()
|
||||
{
|
||||
std::shared_ptr<RenderDevice> renderDevice = Graphics::Instance()->GetRenderDevice();
|
||||
|
|
|
|||
|
|
@ -48,7 +48,13 @@ namespace Nz
|
|||
|
||||
std::size_t shadowPassIndex = Graphics::Instance()->GetMaterialPassRegistry().GetPassIndex("ShadowPass");
|
||||
|
||||
m_depthPass.emplace(m_pipeline, elementRegistry, &m_viewer, shadowPassIndex, "Spotlight shadow mapping");
|
||||
FramePipelinePass::PassData passData = {
|
||||
&m_viewer,
|
||||
elementRegistry,
|
||||
m_pipeline
|
||||
};
|
||||
|
||||
m_depthPass.emplace(passData, "Spotlight shadow mapping", shadowPassIndex);
|
||||
m_pipeline.ForEachRegisteredMaterialInstance([this](const MaterialInstance& matInstance)
|
||||
{
|
||||
m_depthPass->RegisterMaterialInstance(matInstance);
|
||||
|
|
@ -66,7 +72,15 @@ namespace Nz
|
|||
std::size_t visibilityHash = 5U;
|
||||
const auto& visibleRenderables = m_pipeline.FrustumCull(frustum, 0xFFFFFFFF, visibilityHash);
|
||||
|
||||
m_depthPass->Prepare(renderFrame, frustum, visibleRenderables, visibilityHash);
|
||||
FramePipelinePass::FrameData passData = {
|
||||
nullptr,
|
||||
frustum,
|
||||
renderFrame,
|
||||
visibleRenderables,
|
||||
visibilityHash
|
||||
};
|
||||
|
||||
m_depthPass->Prepare(passData);
|
||||
}
|
||||
|
||||
void SpotLightShadowData::RegisterMaterialInstance(const MaterialInstance& matInstance)
|
||||
|
|
@ -94,7 +108,10 @@ namespace Nz
|
|||
shadowMapSize, shadowMapSize,
|
||||
});
|
||||
|
||||
m_depthPass->RegisterToFrameGraph(frameGraph, m_attachmentIndex);
|
||||
FramePipelinePass::PassInputOuputs passInputOuputs;
|
||||
passInputOuputs.depthStencilOutput = m_attachmentIndex;
|
||||
|
||||
m_depthPass->RegisterToFrameGraph(frameGraph, passInputOuputs);
|
||||
}
|
||||
|
||||
const Texture* SpotLightShadowData::RetrieveLightShadowmap(const BakedFrameGraph& bakedGraph, const AbstractViewer* /*viewer*/) const
|
||||
|
|
|
|||
|
|
@ -344,7 +344,7 @@ namespace Nz
|
|||
CameraEntity* cameraEntity = m_cameraEntityPool.Allocate(poolIndex);
|
||||
cameraEntity->poolIndex = poolIndex;
|
||||
cameraEntity->entity = entity;
|
||||
cameraEntity->viewerIndex = m_pipeline->RegisterViewer(&entityCamera, entityCamera.GetRenderOrder(), entityCamera.GetFramePipelineExtraPassFlags());
|
||||
cameraEntity->viewerIndex = m_pipeline->RegisterViewer(&entityCamera, entityCamera.GetRenderOrder());
|
||||
cameraEntity->onNodeInvalidation.Connect(entityNode.OnNodeInvalidation, [this, cameraEntity](const Node* /*node*/)
|
||||
{
|
||||
m_invalidatedCameraNode.insert(cameraEntity);
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ namespace Nz
|
|||
pipelineInfo.pipelineLayout = m_renderPipelineLayout;
|
||||
pipelineInfo.shaderModules.push_back(std::move(debugDrawShader));
|
||||
pipelineInfo.depthBuffer = true;
|
||||
pipelineInfo.depthWrite = false;
|
||||
pipelineInfo.depthWrite = true;
|
||||
|
||||
pipelineInfo.blending = true;
|
||||
pipelineInfo.blend.srcColor = BlendFunc::SrcAlpha;
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ int main()
|
|||
|
||||
Nz::ElementRendererRegistry elementRegistry;
|
||||
Nz::ForwardFramePipeline framePipeline(elementRegistry);
|
||||
[[maybe_unused]] std::size_t cameraIndex = framePipeline.RegisterViewer(&camera, 0, Nz::FramePipelineAllExtraPasses);
|
||||
[[maybe_unused]] std::size_t cameraIndex = framePipeline.RegisterViewer(&camera, 0);
|
||||
std::size_t worldInstanceIndex1 = framePipeline.RegisterWorldInstance(modelInstance);
|
||||
std::size_t worldInstanceIndex2 = framePipeline.RegisterWorldInstance(modelInstance2);
|
||||
framePipeline.RegisterRenderable(worldInstanceIndex1, Nz::FramePipeline::NoSkeletonInstance, &model, 0xFFFFFFFF, scissorBox);
|
||||
|
|
|
|||
Loading…
Reference in New Issue