2#ifndef LIBSBX_POST_FILTERS_SSAO_FILTER_HPP_
3#define LIBSBX_POST_FILTERS_SSAO_FILTER_HPP_
5#include <libsbx/utility/enum.hpp>
7#include <libsbx/math/vector2.hpp>
8#include <libsbx/math/vector3.hpp>
9#include <libsbx/math/vector4.hpp>
10#include <libsbx/math/random.hpp>
12#include <libsbx/graphics/buffers/storage_buffer.hpp>
13#include <libsbx/graphics/graphics_module.hpp>
15#include <libsbx/post/filter.hpp>
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};
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>();
36 auto kernel = std::vector<math::vector3>{};
37 kernel.resize(kernel_size);
39 for (
auto i = 0u; i < kernel.size(); ++i) {
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)
45 sample = math::vector3::normalized(sample);
46 sample *= math::random::next<std::float_t>(0.0f, 1.0f);
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);
51 kernel[i] = sample * scale;
56 auto noise = std::vector<math::vector4>{};
57 noise.resize(noise_dimension * noise_dimension);
59 for (
auto i = 0u; i < noise.size(); ++i) {
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,
67 noise[i] = math::vector4::normalized(n);
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()));
76 EASY_BLOCK(
"ssao_filter::render");
77 SBX_PROFILE_SCOPE(
"ssao_filter::render");
79 auto& graphics_module = core::engine::get_module<graphics::graphics_module>();
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();
86 auto& pipeline = base::pipeline();
87 auto& descriptor_handler = base::descriptor_handler();
89 pipeline.bind(command_buffer);
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);
99 for (
const auto& [name, attachment] : _attachment_names) {
100 descriptor_handler.push(name, graphics_module.attachment(attachment));
103 descriptor_handler.push(
"noise_image", noise);
104 descriptor_handler.push(
"scene", environment.uniform_handler());
106 if (!descriptor_handler.update(pipeline)) {
110 descriptor_handler.bind_descriptors(command_buffer);
111 _push_handler.bind(command_buffer);
113 command_buffer.draw(3, 1, 0, 0);
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);
127 std::vector<std::pair<std::string, std::string>> _attachment_names;
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