mirror of
https://github.com/Kbz-8/42_vox.git
synced 2026-01-11 14:43:34 +00:00
adding post processing
This commit is contained in:
@@ -4,7 +4,6 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <map>
|
||||
|
||||
#include <Utils/NonOwningPtr.h>
|
||||
|
||||
@@ -24,11 +23,14 @@ namespace Scop
|
||||
struct SceneDescriptor
|
||||
{
|
||||
std::shared_ptr<Shader> fragment_shader;
|
||||
std::shared_ptr<Shader> post_process_shader = nullptr;
|
||||
std::shared_ptr<BaseCamera> camera;
|
||||
CullMode culling;
|
||||
std::size_t post_process_data_size = 0;
|
||||
bool render_3D_enabled = true;
|
||||
bool render_2D_enabled = true;
|
||||
bool render_skybox_enabled = true;
|
||||
bool render_post_process_enabled = false;
|
||||
};
|
||||
|
||||
class Scene
|
||||
@@ -44,6 +46,13 @@ namespace Scop
|
||||
bool wireframe = false;
|
||||
};
|
||||
|
||||
struct PostProcessData
|
||||
{
|
||||
std::shared_ptr<DescriptorSet> set;
|
||||
std::shared_ptr<UniformBuffer> data_buffer;
|
||||
CPUBuffer data;
|
||||
};
|
||||
|
||||
public:
|
||||
Scene(std::string_view name, SceneDescriptor desc);
|
||||
Scene(std::string_view name, SceneDescriptor desc, NonOwningPtr<Scene> parent);
|
||||
@@ -67,6 +76,7 @@ namespace Scop
|
||||
void SwitchToParent() const noexcept;
|
||||
|
||||
[[nodiscard]] inline ForwardData& GetForwardData() noexcept { return m_forward; }
|
||||
[[nodiscard]] inline PostProcessData& GetPostProcessData() noexcept { return m_post_process; }
|
||||
[[nodiscard]] inline const std::unordered_map<std::uint64_t, Actor>& GetActors() const noexcept { return m_actors; }
|
||||
[[nodiscard]] inline const std::unordered_map<std::uint64_t, Sprite>& GetSprites() const noexcept { return m_sprites; }
|
||||
[[nodiscard]] inline const std::string& GetName() const noexcept { return m_name; }
|
||||
@@ -88,6 +98,7 @@ namespace Scop
|
||||
private:
|
||||
GraphicPipeline m_pipeline;
|
||||
ForwardData m_forward;
|
||||
PostProcessData m_post_process;
|
||||
DepthImage m_depth;
|
||||
SceneDescriptor m_descriptor;
|
||||
std::shared_ptr<CubeTexture> p_skybox;
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace Scop
|
||||
{
|
||||
std::vector<VkFormat> candidates = { VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT };
|
||||
VkFormat format = kvfFindSupportFormatInCandidates(RenderCore::Get().GetDevice(), candidates.data(), candidates.size(), VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
||||
Image::Init(ImageType::Depth, width, height, format, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, is_multisampled, std::move(name));
|
||||
Image::Init(ImageType::Depth, width, height, format, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, is_multisampled, std::move(name));
|
||||
Image::TransitionLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
Image::CreateImageView(VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_DEPTH_BIT);
|
||||
}
|
||||
|
||||
@@ -85,6 +85,18 @@ namespace Scop
|
||||
}
|
||||
}, {}
|
||||
);
|
||||
|
||||
static const Scop::ShaderLayout PostProcessShaderLayout(
|
||||
{
|
||||
{ 0,
|
||||
Scop::ShaderSetLayout({
|
||||
{ 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER },
|
||||
{ 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER },
|
||||
{ 2, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER }
|
||||
})
|
||||
}
|
||||
}, {}
|
||||
);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <Renderer/RenderPasses/SkyboxPass.h>
|
||||
#include <Renderer/RenderPasses/ForwardPass.h>
|
||||
#include <Renderer/RenderPasses/FinalPass.h>
|
||||
#include <Renderer/RenderPasses/PostProcessPass.h>
|
||||
#include <Renderer/RenderPasses/2DPass.h>
|
||||
|
||||
namespace Scop
|
||||
@@ -21,6 +22,7 @@ namespace Scop
|
||||
private:
|
||||
SkyboxPass m_skybox;
|
||||
Render2DPass m_2Dpass;
|
||||
PostProcessPass m_post_process;
|
||||
FinalPass m_final;
|
||||
Texture m_main_render_texture;
|
||||
ForwardPass m_forward;
|
||||
|
||||
28
ScopEngine/Runtime/Includes/Renderer/RenderPasses/PostProcessPass.h
git.filemode.normal_file
28
ScopEngine/Runtime/Includes/Renderer/RenderPasses/PostProcessPass.h
git.filemode.normal_file
@@ -0,0 +1,28 @@
|
||||
#ifndef __SCOP_POST_PROCESS_PASS__
|
||||
#define __SCOP_POST_PROCESS_PASS__
|
||||
|
||||
#include <Renderer/Descriptor.h>
|
||||
#include <Renderer/Pipelines/Shader.h>
|
||||
#include <Renderer/Pipelines/Graphics.h>
|
||||
|
||||
namespace Scop
|
||||
{
|
||||
class PostProcessPass
|
||||
{
|
||||
public:
|
||||
PostProcessPass() = default;
|
||||
void Init();
|
||||
void Pass(class Scene& scene, class Renderer& renderer, class Texture& render_target);
|
||||
void Destroy();
|
||||
|
||||
[[nodiscard]] inline Texture& GetProcessTexture() noexcept { return m_render_texture; }
|
||||
~PostProcessPass() = default;
|
||||
|
||||
private:
|
||||
GraphicPipeline m_pipeline;
|
||||
Texture m_render_texture;
|
||||
std::shared_ptr<Shader> p_vertex_shader;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -26,6 +26,21 @@ namespace Scop
|
||||
return buffer;
|
||||
}
|
||||
|
||||
inline void Allocate(std::size_t size)
|
||||
{
|
||||
if(m_data != nullptr)
|
||||
FatalError("cannot allocate an already allocated CPU buffer");
|
||||
try
|
||||
{
|
||||
m_data = std::make_shared<std::uint8_t[]>(size);
|
||||
m_size = size;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
FatalError("memory allocation for a CPU buffer failed");
|
||||
}
|
||||
}
|
||||
|
||||
inline bool Empty() const { return m_size == 0; }
|
||||
|
||||
[[nodiscard]] inline std::size_t GetSize() const noexcept { return m_size; }
|
||||
|
||||
@@ -114,6 +114,7 @@ namespace Scop
|
||||
{
|
||||
m_depth.Destroy();
|
||||
m_depth.Init(renderer->GetSwapchain().GetSwapchainImages().back().GetWidth(), renderer->GetSwapchain().GetSwapchainImages().back().GetHeight(), false, m_name + "_depth");
|
||||
m_depth.CreateSampler();
|
||||
}
|
||||
|
||||
if(event.What() == Event::ResizeEventCode || event.What() == Event::SceneHasChangedEventCode)
|
||||
@@ -121,8 +122,18 @@ namespace Scop
|
||||
};
|
||||
EventBus::RegisterListener({ functor, m_name + std::to_string(reinterpret_cast<std::uintptr_t>(this)) });
|
||||
|
||||
if(m_descriptor.post_process_shader)
|
||||
{
|
||||
m_post_process.set = std::make_shared<DescriptorSet>(m_descriptor.post_process_shader->GetShaderLayout().set_layouts[0].second, m_descriptor.post_process_shader->GetPipelineLayout().set_layouts[0], ShaderType::Fragment);
|
||||
m_post_process.data_buffer = std::make_shared<UniformBuffer>();
|
||||
m_post_process.data_buffer->Init(m_descriptor.post_process_data_size, m_name + "_post_process_data_buffer");
|
||||
}
|
||||
|
||||
m_post_process.data.Allocate(m_descriptor.post_process_data_size);
|
||||
|
||||
auto vertex_shader = RenderCore::Get().GetDefaultVertexShader();
|
||||
m_depth.Init(renderer->GetSwapchain().GetSwapchainImages().back().GetWidth(), renderer->GetSwapchain().GetSwapchainImages().back().GetHeight(), false, m_name + "_depth");
|
||||
m_depth.CreateSampler();
|
||||
m_forward.matrices_buffer = std::make_shared<UniformBuffer>();
|
||||
m_forward.matrices_buffer->Init(sizeof(ViewerData), m_name + "_matrice_buffer");
|
||||
|
||||
@@ -160,7 +171,10 @@ namespace Scop
|
||||
m_sprites.clear();
|
||||
m_pipeline.Destroy();
|
||||
m_descriptor.fragment_shader.reset();
|
||||
m_descriptor.post_process_shader.reset();
|
||||
m_forward.matrices_buffer->Destroy();
|
||||
if(m_post_process.data_buffer)
|
||||
m_post_process.data_buffer->Destroy();
|
||||
for(auto& child : m_scene_children)
|
||||
child.Destroy();
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <Graphics/Scene.h>
|
||||
#include <Maths/Mat4.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace Scop
|
||||
{
|
||||
struct ModelData
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace Scop
|
||||
{
|
||||
m_skybox.Init();
|
||||
m_2Dpass.Init();
|
||||
m_post_process.Init();
|
||||
m_final.Init();
|
||||
|
||||
std::function<void(const EventBase&)> functor = [this](const EventBase& event)
|
||||
@@ -36,8 +37,13 @@ namespace Scop
|
||||
m_skybox.Pass(scene, renderer, m_main_render_texture);
|
||||
if(scene.GetDescription().render_2D_enabled)
|
||||
m_2Dpass.Pass(scene, renderer, m_main_render_texture);
|
||||
|
||||
m_final.Pass(scene, renderer, m_main_render_texture);
|
||||
if(scene.GetDescription().render_post_process_enabled && scene.GetDescription().post_process_shader)
|
||||
{
|
||||
m_post_process.Pass(scene, renderer, m_main_render_texture);
|
||||
m_final.Pass(scene, renderer, m_post_process.GetProcessTexture());
|
||||
}
|
||||
else
|
||||
m_final.Pass(scene, renderer, m_main_render_texture);
|
||||
}
|
||||
|
||||
void RenderPasses::Destroy()
|
||||
@@ -45,6 +51,7 @@ namespace Scop
|
||||
RenderCore::Get().WaitDeviceIdle();
|
||||
m_skybox.Destroy();
|
||||
m_2Dpass.Destroy();
|
||||
m_post_process.Destroy();
|
||||
m_final.Destroy();
|
||||
m_main_render_texture.Destroy();
|
||||
}
|
||||
|
||||
74
ScopEngine/Runtime/Sources/Renderer/RenderPasses/PostProcessPass.cpp
git.filemode.normal_file
74
ScopEngine/Runtime/Sources/Renderer/RenderPasses/PostProcessPass.cpp
git.filemode.normal_file
@@ -0,0 +1,74 @@
|
||||
#include <Renderer/RenderPasses/PostProcessPass.h>
|
||||
#include <Renderer/Pipelines/Graphics.h>
|
||||
#include <Renderer/Renderer.h>
|
||||
#include <Graphics/Scene.h>
|
||||
#include <Core/EventBus.h>
|
||||
#include <Core/Engine.h>
|
||||
|
||||
namespace Scop
|
||||
{
|
||||
void PostProcessPass::Init()
|
||||
{
|
||||
ShaderLayout vertex_shader_layout(
|
||||
{}, {}
|
||||
);
|
||||
p_vertex_shader = LoadShaderFromFile(ScopEngine::Get().GetAssetsPath() / "Shaders/Build/ScreenVertex.spv", ShaderType::Vertex, std::move(vertex_shader_layout));
|
||||
|
||||
std::function<void(const EventBase&)> functor = [this](const EventBase& event)
|
||||
{
|
||||
if(event.What() == Event::ResizeEventCode)
|
||||
{
|
||||
m_render_texture.Destroy();
|
||||
m_pipeline.Destroy();
|
||||
}
|
||||
};
|
||||
EventBus::RegisterListener({ functor, "__ScopPostProcessPass" });
|
||||
}
|
||||
|
||||
void PostProcessPass::Pass(Scene& scene, Renderer& renderer, Texture& render_target)
|
||||
{
|
||||
Scene::PostProcessData& data = scene.GetPostProcessData();
|
||||
|
||||
if(!m_render_texture.IsInit())
|
||||
{
|
||||
auto extent = kvfGetSwapchainImagesSize(renderer.GetSwapchain().Get());
|
||||
m_render_texture.Init({}, extent.width, extent.height, VK_FORMAT_R8G8B8A8_UNORM, false, "scop_post_process_render_texture", true);
|
||||
}
|
||||
|
||||
if(m_pipeline.GetPipeline() == VK_NULL_HANDLE)
|
||||
{
|
||||
GraphicPipelineDescriptor pipeline_descriptor;
|
||||
pipeline_descriptor.vertex_shader = p_vertex_shader;
|
||||
pipeline_descriptor.fragment_shader = scene.GetDescription().post_process_shader;
|
||||
pipeline_descriptor.color_attachments = { &m_render_texture };
|
||||
pipeline_descriptor.culling = VK_CULL_MODE_NONE;
|
||||
pipeline_descriptor.clear_color_attachments = false;
|
||||
pipeline_descriptor.no_vertex_inputs = true;
|
||||
pipeline_descriptor.name = "post_process_pass_pipeline";
|
||||
m_pipeline.Init(pipeline_descriptor);
|
||||
}
|
||||
|
||||
VkCommandBuffer cmd = renderer.GetActiveCommandBuffer();
|
||||
|
||||
data.set->SetImage(renderer.GetCurrentFrameIndex(), 0, render_target);
|
||||
data.set->SetImage(renderer.GetCurrentFrameIndex(), 1, scene.GetDepth());
|
||||
data.set->SetUniformBuffer(renderer.GetCurrentFrameIndex(), 2, data.data_buffer->Get(renderer.GetCurrentFrameIndex()));
|
||||
data.set->Update(renderer.GetCurrentFrameIndex(), cmd);
|
||||
|
||||
m_pipeline.BindPipeline(cmd, 0, {});
|
||||
VkDescriptorSet set = data.set->GetSet(renderer.GetCurrentFrameIndex());
|
||||
RenderCore::Get().vkCmdBindDescriptorSets(cmd, m_pipeline.GetPipelineBindPoint(), m_pipeline.GetPipelineLayout(), 0, 1, &set, 0, nullptr);
|
||||
RenderCore::Get().vkCmdDraw(cmd, 3, 1, 0, 0);
|
||||
renderer.GetDrawCallsCounterRef()++;
|
||||
renderer.GetPolygonDrawnCounterRef()++;
|
||||
m_pipeline.EndPipeline(cmd);
|
||||
}
|
||||
|
||||
void PostProcessPass::Destroy()
|
||||
{
|
||||
RenderCore::Get().WaitDeviceIdle();
|
||||
m_render_texture.Destroy();
|
||||
m_pipeline.Destroy();
|
||||
p_vertex_shader.reset();
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,8 @@ namespace Scop
|
||||
std::memcpy(buffer.GetData(), &data, buffer.GetSize());
|
||||
scene.GetForwardData().matrices_buffer->SetData(buffer, renderer.GetCurrentFrameIndex());
|
||||
}
|
||||
if(scene.GetDescription().render_post_process_enabled && scene.GetDescription().post_process_shader)
|
||||
scene.GetPostProcessData().data_buffer->SetData(scene.GetPostProcessData().data, renderer.GetCurrentFrameIndex());
|
||||
|
||||
m_passes.Pass(scene, renderer);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user