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 EASY_BLOCK("ssao_filter::render");
77 SBX_PROFILE_SCOPE("ssao_filter::render");
78
79 auto& graphics_module = core::engine::get_module<graphics::graphics_module>();
80
81 auto& scenes_module = core::engine::get_module<scenes::scenes_module>();
82 auto& scene = scenes_module.active_scene();
83 auto& environment = scene.environment();
84 auto& graph = scene.graph();
85
86 auto& pipeline = base::pipeline();
87 auto& descriptor_handler = base::descriptor_handler();
88
89 pipeline.bind(command_buffer);
90
91 auto& kernel = graphics_module.get_resource<graphics::storage_buffer>(_kernel);
92 auto& noise = graphics_module.get_resource<graphics::image2d>(_noise);
93
94 _push_handler.push("kernel_size", kernel_size);
95 _push_handler.push("kernel_radius", kernel_radius);
96 _push_handler.push("kernel_buffer", kernel.address());
97 _push_handler.push("bias", 0.01f);
98
99 for (const auto& [name, attachment] : _attachment_names) {
100 descriptor_handler.push(name, graphics_module.attachment(attachment));
101 }
102
103 descriptor_handler.push("noise_image", noise);
104 descriptor_handler.push("scene", environment.uniform_handler());
105
106 if (!descriptor_handler.update(pipeline)) {
107 return;
108 }
109
110 descriptor_handler.bind_descriptors(command_buffer);
111 _push_handler.bind(command_buffer);
112
113 command_buffer.draw(3, 1, 0, 0);
114 }
115
116private:
117
118 inline static constexpr auto _lerp(std::float_t a, std::float_t b, std::float_t f) -> std::float_t {
119 return a + f * (b - a);
120 }
121
122 graphics::push_handler _push_handler;
123
126
127 std::vector<std::pair<std::string, std::string>> _attachment_names;
128
129}; // class ssao_filter
130
131} // namespace sbx::post
132
133#endif // LIBSBX_POST_FILTERS_SSAO_FILTER_HPP_
Definition: command_buffer.hpp:15
Definition: image2d.hpp:52
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