sandbox
Loading...
Searching...
No Matches
ssao_filter.hpp
1// SPDX-License-Identifier: MIT
2#ifndef LIBSBX_POST_FILTERS_SSAO_FILTER_HPP_
3#define LIBSBX_POST_FILTERS_SSAO_FILTER_HPP_
4
5#include <libsbx/utility/enum.hpp>
6
7#include <libsbx/math/vector2.hpp>
8#include <libsbx/math/vector3.hpp>
9#include <libsbx/math/vector4.hpp>
10#include <libsbx/math/random.hpp>
11
12#include <libsbx/graphics/buffers/storage_buffer.hpp>
13#include <libsbx/graphics/graphics_module.hpp>
14
15#include <libsbx/post/filter.hpp>
16
17namespace sbx::post {
18
19
20class ssao_filter final : public filter {
21
22 using base = filter;
23
24public:
25
26 inline static constexpr auto kernel_size = std::uint32_t{32u};
27 inline static constexpr auto kernel_radius = std::float_t{0.5f};
28 inline static constexpr auto noise_dimension = std::uint32_t{8u};
29
30 ssao_filter(const std::vector<graphics::attachment_description>& attachments, const std::filesystem::path& path, std::vector<std::pair<std::string, std::string>>&& attachment_names)
31 : base{attachments, path, base::default_pipeline_definition},
32 _push_handler{base::pipeline()},
33 _attachment_names{attachment_names} {
34 auto& graphics_module = core::engine::get_module<graphics::graphics_module>();
35
36 auto kernel = std::vector<math::vector3>{};
37 kernel.resize(kernel_size);
38
39 for (auto i = 0u; i < kernel.size(); ++i) {
40 auto sample = math::vector3{
41 math::random::next<std::float_t>(0.0f, 1.0f) * 2.0f - 1.0f,
42 math::random::next<std::float_t>(0.0f, 1.0f) * 2.0f - 1.0f,
43 math::random::next<std::float_t>(0.0f, 1.0f)
44 };
45 sample = math::vector3::normalized(sample);
46 sample *= math::random::next<std::float_t>(0.0f, 1.0f);
47
48 auto t = static_cast<std::float_t>(i) / static_cast<std::float_t>(kernel.size());
49 auto scale = 0.1f + 0.9f * (t * t);
50
51 kernel[i] = sample * scale;
52 }
53
54 _kernel = graphics_module.add_resource<graphics::storage_buffer>(kernel.size() * sizeof(math::vector3), VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, kernel.data());
55
56 auto noise = std::vector<math::vector4>{};
57 noise.resize(noise_dimension * noise_dimension);
58
59 for (auto i = 0u; i < noise.size(); ++i) {
60 auto n = math::vector4{
61 math::random::next<std::float_t>(0.0f, 1.0f) * 2.0f - 1.0f,
62 math::random::next<std::float_t>(0.0f, 1.0f) * 2.0f - 1.0f,
63 0.0f,
64 0.0f
65 };
66
67 noise[i] = math::vector4::normalized(n);
68 }
69
70 _noise = graphics_module.add_resource<graphics::image2d>(math::vector2u{noise_dimension, noise_dimension}, graphics::format::r8g8b8a8_unorm, graphics::filter::nearest, reinterpret_cast<const std::uint8_t*>(noise.data()));
71 }
72
73 ~ssao_filter() override = default;
74
75 auto render(graphics::command_buffer& command_buffer) -> void override {
76 SBX_PROFILE_SCOPE("ssao_filter::render");
77
78 auto& graphics_module = core::engine::get_module<graphics::graphics_module>();
79
80 auto& scenes_module = core::engine::get_module<scenes::scenes_module>();
81 auto& scene = scenes_module.active_scene();
82 auto& environment = scene.environment();
83 auto& graph = scene.graph();
84
85 auto& pipeline = base::pipeline();
86 auto& descriptor_handler = base::descriptor_handler();
87
88 pipeline.bind(command_buffer);
89
90 auto& kernel = graphics_module.get_resource<graphics::storage_buffer>(_kernel);
91 auto& noise = graphics_module.get_resource<graphics::image2d>(_noise);
92
93 _push_handler.push("kernel_size", kernel_size);
94 _push_handler.push("kernel_radius", kernel_radius);
95 _push_handler.push("kernel_buffer", kernel.address());
96 _push_handler.push("bias", 0.01f);
97
98 for (const auto& [name, attachment] : _attachment_names) {
99 descriptor_handler.push(name, graphics_module.attachment(attachment));
100 }
101
102 descriptor_handler.push("noise_image", noise);
103 descriptor_handler.push("scene", environment.uniform_handler());
104
105 if (!descriptor_handler.update(pipeline)) {
106 return;
107 }
108
109 descriptor_handler.bind_descriptors(command_buffer);
110 _push_handler.bind(command_buffer);
111
112 command_buffer.draw(3, 1, 0, 0);
113 }
114
115private:
116
117 inline static constexpr auto _lerp(std::float_t a, std::float_t b, std::float_t f) -> std::float_t {
118 return a + f * (b - a);
119 }
120
121 graphics::push_handler _push_handler;
122
125
126 std::vector<std::pair<std::string, std::string>> _attachment_names;
127
128}; // class ssao_filter
129
130} // namespace sbx::post
131
132#endif // LIBSBX_POST_FILTERS_SSAO_FILTER_HPP_
Definition: command_buffer.hpp:15
Definition: image2d.hpp:53
Definition: push_handler.hpp:18
Definition: resource_storage.hpp:18
Definition: storage_buffer.hpp:17
A vector in two-dimensional space.
Definition: vector2.hpp:28
Definition: vector3.hpp:23
Definition: vector4.hpp:24
Definition: filter.hpp:19
Definition: ssao_filter.hpp:20