Graphics: Add FramePipelinePassFlag to fix shadows

This commit is contained in:
SirLynix 2023-11-03 11:24:41 +01:00 committed by Jérôme Leclercq
parent 8fb6ea728d
commit ef0a34b7b1
13 changed files with 85 additions and 34 deletions

View File

@ -45,7 +45,7 @@ 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;
std::size_t RegisterPasses(const std::vector<std::unique_ptr<FramePipelinePass>>& passes, FrameGraph& frameGraph, const FunctionRef<void(std::size_t passIndex, FramePass& framePass, FramePipelinePassFlags flags)>& passCallback = nullptr) const override;
inline void UpdateClearColor(Color color);
inline void UpdateFOV(DegreeAnglef fov);

View File

@ -8,6 +8,7 @@
#define NAZARA_GRAPHICS_DEBUGDRAWPIPELINEPASS_HPP
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/Core/ParameterList.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/FramePipelinePass.hpp>
#include <string>
@ -18,7 +19,6 @@ namespace Nz
class FrameGraph;
class FramePass;
class FramePipeline;
class ParameterList;
class RenderFrame;
class NAZARA_GRAPHICS_API DebugDrawPipelinePass : public FramePipelinePass

View File

@ -8,6 +8,7 @@
#define NAZARA_GRAPHICS_DEPTHPIPELINEPASS_HPP
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/Core/ParameterList.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/ElementRenderer.hpp>
#include <Nazara/Graphics/FramePipelinePass.hpp>

View File

@ -41,6 +41,20 @@ namespace Nz
Volume
};
enum class EngineShaderBinding
{
InstanceDataUbo,
LightDataUbo,
OverlayTexture,
ShadowmapDirectional,
ShadowmapPoint,
ShadowmapSpot,
SkeletalDataUbo,
ViewerDataUbo,
Max = ViewerDataUbo
};
enum class FramePipelineNotification
{
ElementInvalidation,
@ -57,6 +71,21 @@ namespace Nz
using FramePipelineNotificationFlags = Flags<FramePipelineNotification>;
enum class FramePipelinePassFlag
{
LightShadowing,
Max = LightShadowing
};
template<>
struct EnumAsFlags<FramePipelinePassFlag>
{
static constexpr FramePipelinePassFlag max = FramePipelinePassFlag::Max;
};
using FramePipelinePassFlags = Flags<FramePipelinePassFlag>;
enum class MaterialPropertyType
{
Bool,
@ -116,20 +145,6 @@ namespace Nz
Orthographic,
Perspective
};
enum class EngineShaderBinding
{
InstanceDataUbo,
LightDataUbo,
OverlayTexture,
ShadowmapDirectional,
ShadowmapPoint,
ShadowmapSpot,
SkeletalDataUbo,
ViewerDataUbo,
Max = ViewerDataUbo
};
}
#endif // NAZARA_GRAPHICS_ENUMS_HPP

View File

@ -8,6 +8,7 @@
#define NAZARA_GRAPHICS_FORWARDPIPELINEPASS_HPP
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/Core/ParameterList.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/ElementRenderer.hpp>
#include <Nazara/Graphics/FramePipelinePass.hpp>

View File

@ -10,9 +10,11 @@
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/Core/ParameterList.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/Enums.hpp>
#include <Nazara/Graphics/FramePassAttachment.hpp>
#include <Nazara/Graphics/FramePipelinePass.hpp>
#include <NazaraUtils/FixedVector.hpp>
#include <NazaraUtils/FunctionRef.hpp>
#include <array>
#include <limits>
#include <string>
@ -34,13 +36,16 @@ namespace Nz
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 EnablePassFlags(std::size_t passIndex, FramePipelinePassFlags flags);
std::size_t RegisterPasses(const std::vector<std::unique_ptr<FramePipelinePass>>& passes, FrameGraph& frameGraph, const FunctionRef<void(std::size_t passIndex, FramePass& framePass, FramePipelinePassFlags flags)>& passCallback = nullptr) 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);
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);
PipelinePassList& operator=(const PipelinePassList&) = delete;
PipelinePassList& operator=(PipelinePassList&&) = delete;
@ -52,12 +57,13 @@ namespace Nz
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;
FixedVector<std::size_t /*attachmentIndex*/, MaxPassAttachment> inputs;
FixedVector<std::size_t /*attachmentIndex*/, MaxPassAttachment> outputs;
FramePipelinePassFlags flags;
ParameterList parameterList;
};

View File

@ -26,6 +26,13 @@ namespace Nz
return index;
}
inline void PipelinePassList::EnablePassFlags(std::size_t passIndex, FramePipelinePassFlags flags)
{
assert(passIndex < m_passes.size());
auto& pass = m_passes[passIndex];
pass.flags = flags;
}
inline void PipelinePassList::SetFinalOutput(std::size_t attachmentIndex)
{
m_finalOutputAttachment = attachmentIndex;

View File

@ -9,11 +9,15 @@
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/Graphics/AbstractViewer.hpp>
#include <Nazara/Graphics/Enums.hpp>
#include <Nazara/Graphics/FramePipelinePass.hpp>
#include <NazaraUtils/FunctionRef.hpp>
#include <vector>
namespace Nz
{
class FramePass;
class NAZARA_GRAPHICS_API PipelineViewer : public AbstractViewer
{
public:
@ -24,7 +28,7 @@ namespace Nz
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;
virtual std::size_t RegisterPasses(const std::vector<std::unique_ptr<FramePipelinePass>>& passes, FrameGraph& frameGraph, const FunctionRef<void(std::size_t passIndex, FramePass& framePass, FramePipelinePassFlags flags)>& passCallback = nullptr) const = 0;
PipelineViewer& operator=(const PipelineViewer&) = delete;
PipelineViewer& operator=(PipelineViewer&&) = delete;

View File

@ -8,6 +8,7 @@
#define NAZARA_GRAPHICS_POSTPROCESSPIPELINEPASS_HPP
#include <NazaraUtils/Prerequisites.hpp>
#include <Nazara/Core/ParameterList.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/FramePipelinePass.hpp>
#include <Nazara/Graphics/UberShader.hpp>
@ -17,7 +18,6 @@ namespace Nz
class FrameGraph;
class FramePass;
class FramePipeline;
class ParameterList;
class RenderFrame;
class RenderPipeline;
class ShaderBinding;

View File

@ -55,10 +55,10 @@ namespace Nz
return m_viewport;
}
std::size_t Camera::RegisterPasses(const std::vector<std::unique_ptr<FramePipelinePass>>& passes, FrameGraph& frameGraph) const
std::size_t Camera::RegisterPasses(const std::vector<std::unique_ptr<FramePipelinePass>>& passes, FrameGraph& frameGraph, const FunctionRef<void(std::size_t passIndex, FramePass& framePass, FramePipelinePassFlags flags)>& passCallback) const
{
assert(m_framePipelinePasses);
return m_framePipelinePasses->RegisterPasses(passes, frameGraph);
return m_framePipelinePasses->RegisterPasses(passes, frameGraph, passCallback);
}
void Camera::UpdateTarget(const RenderTarget* renderTarget)

View File

@ -713,7 +713,20 @@ namespace Nz
lightData->shadowData->RegisterToFrameGraph(frameGraph, viewerData.viewer);
}
viewerData.finalColorAttachment = viewerData.viewer->RegisterPasses(viewerData.passes, frameGraph);
auto framePassCallback = [this, &viewerData, renderMask](std::size_t /*passIndex*/, FramePass& framePass, FramePipelinePassFlags flags)
{
if (flags.Test(FramePipelinePassFlag::LightShadowing))
{
for (std::size_t i : m_shadowCastingLights.IterBits())
{
LightData* lightData = m_lightPool.RetrieveFromIndex(i);
if ((renderMask & lightData->renderMask) != 0)
lightData->shadowData->RegisterPassInputs(framePass, (lightData->shadowData->IsPerViewer()) ? viewerData.viewer : nullptr);
}
}
};
viewerData.finalColorAttachment = viewerData.viewer->RegisterPasses(viewerData.passes, frameGraph, framePassCallback);
}
using ViewerPair = std::pair<const RenderTarget*, const ViewerData*>;

View File

@ -390,6 +390,8 @@ namespace Nz
m_defaultPipelinePasses->SetPassOutput(forwardPass, 0, forwardColorOutput);
m_defaultPipelinePasses->SetPassDepthStencilOutput(forwardPass, forwardDepthOutput);
m_defaultPipelinePasses->EnablePassFlags(forwardPass, FramePipelinePassFlag::LightShadowing);
// Gamma correction
std::size_t gammaCorrectionOutput = m_defaultPipelinePasses->AddAttachment({
"Gamma-corrected output",

View File

@ -22,7 +22,7 @@ namespace Nz
return passes;
}
std::size_t PipelinePassList::RegisterPasses(const std::vector<std::unique_ptr<FramePipelinePass>>& passes, FrameGraph& frameGraph) const
std::size_t PipelinePassList::RegisterPasses(const std::vector<std::unique_ptr<FramePipelinePass>>& passes, FrameGraph& frameGraph, const FunctionRef<void(std::size_t passIndex, FramePass& framePass, FramePipelinePassFlags flags)>& passCallback) const
{
NazaraAssert(m_passes.size() == passes.size(), "pass vector size doesn't match passlist size");
@ -39,17 +39,17 @@ namespace Nz
return attachmentIndices[attachmentIndex];
};
for (std::size_t i = 0; i < passes.size(); ++i)
for (std::size_t passIndex = 0; passIndex < passes.size(); ++passIndex)
{
const Pass& passData = m_passes[i];
const Pass& passData = m_passes[passIndex];
std::array<std::size_t, MaxPassAttachment> inputs;
for (std::size_t j = 0; j < passData.inputs.size(); ++j)
inputs[j] = GetAttachmentIndex(passData.inputs[j]);
for (std::size_t i = 0; i < passData.inputs.size(); ++i)
inputs[i] = GetAttachmentIndex(passData.inputs[i]);
std::array<std::size_t, MaxPassAttachment> outputs;
for (std::size_t j = 0; j < passData.outputs.size(); ++j)
outputs[j] = GetAttachmentIndex(passData.outputs[j]);
for (std::size_t i = 0; i < passData.outputs.size(); ++i)
outputs[i] = GetAttachmentIndex(passData.outputs[i]);
FramePipelinePass::PassInputOuputs passInputOuputs;
passInputOuputs.depthStencilInput = GetAttachmentIndex(passData.depthStencilInput);
@ -59,7 +59,9 @@ namespace Nz
passInputOuputs.outputAttachments = outputs.data();
passInputOuputs.outputCount = passData.outputs.size();
passes[i]->RegisterToFrameGraph(frameGraph, passInputOuputs);
FramePass& framePass = passes[passIndex]->RegisterToFrameGraph(frameGraph, passInputOuputs);
if (passCallback)
passCallback(passIndex, framePass, passData.flags);
}
return GetAttachmentIndex(m_finalOutputAttachment);