sandbox
Loading...
Searching...
No Matches
resolve_filter.hpp
1// SPDX-License-Identifier: MIT
2#ifndef LIBSBX_POST_FILTERS_RESOLVE_FILTER_HPP_
3#define LIBSBX_POST_FILTERS_RESOLVE_FILTER_HPP_
4
5#include <string>
6#include <unordered_map>
7
8#include <libsbx/scenes/components/transform.hpp>
9
10#include <libsbx/graphics/graphics_module.hpp>
11#include <libsbx/graphics/buffers/uniform_buffer.hpp>
12#include <libsbx/graphics/buffers/push_handler.hpp>
13
14#include <libsbx/scenes/scenes_module.hpp>
15#include <libsbx/scenes/scene.hpp>
16#include <libsbx/scenes/node.hpp>
17#include <libsbx/scenes/components/camera.hpp>
18#include <libsbx/scenes/components/directional_light.hpp>
19#include <libsbx/scenes/components/point_light.hpp>
20#include <libsbx/scenes/components/static_mesh.hpp>
21#include <libsbx/scenes/components/skybox.hpp>
22
23#include <libsbx/post/filter.hpp>
24
25namespace sbx::post {
26
27template<bool Transparent>
28class resolve_filter final : public filter {
29
30 using base = filter;
31
32 inline static constexpr auto max_point_lights = std::size_t{32};
33 inline static constexpr auto max_directional_lights = std::size_t{4};
34
35 struct point_light_data {
36 alignas(16) math::vector4 position;
37 alignas(16) math::color color;
38 }; // struct point_light_data
39
40 struct directional_light_data {
41 alignas(16) math::vector4 direction;
42 alignas(16) math::color color;
43 }; // struct directional_light_data
44
45 inline static const auto pipeline_definition = graphics::pipeline_definition{
46 .depth = graphics::depth::disabled,
47 .uses_transparency = Transparent,
48 .rasterization_state = graphics::rasterization_state{
49 .polygon_mode = graphics::polygon_mode::fill,
50 .cull_mode = graphics::cull_mode::none,
51 .front_face = graphics::front_face::counter_clockwise
52 }
53 };
54
55 static constexpr auto _default_shader_path() -> std::string_view {
56 if constexpr (Transparent) {
57 return "engine://shaders/resolve_transparent";
58 } else {
59 return "engine://shaders/resolve_opaque";
60 }
61 }
62
63public:
64
65 resolve_filter(const std::vector<graphics::attachment_description>& attachments, std::vector<std::pair<std::string, std::string>>&& attachment_names, const std::filesystem::path& path = _default_shader_path())
66 : base{attachments, path, pipeline_definition},
67 _push_handler{base::pipeline()},
68 _point_lights_storage_handler{},
69 _directional_lights_storage_handler{},
70 _attachment_names{std::move(attachment_names)} { }
71
72 ~resolve_filter() override = default;
73
74 auto render(graphics::command_buffer& command_buffer) -> void override {
75 SBX_PROFILE_SCOPE("resolve_filter::render");
76
77 auto& graphics_module = core::engine::get_module<graphics::graphics_module>();
78
79 auto& scenes_module = core::engine::get_module<scenes::scenes_module>();
80
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 point_light_nodes = graph.query<scenes::point_light>();
91
92 auto point_lights = std::vector<point_light_data>{};
93 point_lights.reserve(max_point_lights);
94 auto point_light_count = std::uint32_t{0};
95
96 for (const auto& node : point_light_nodes) {
97 const auto model = graph.world_transform(node);
98
99 const auto& light = graph.get_component<scenes::point_light>(node);
100
101 const auto position = math::vector3{model[3]};
102
103 point_lights.push_back(point_light_data{math::vector4{position, light.radius()}, light.color()});
104
105 ++point_light_count;
106
107 if (point_light_count >= max_point_lights) {
108 break;
109 }
110 }
111
112 auto directional_light_nodes = graph.query<scenes::directional_light>();
113
114 auto directional_lights = std::vector<directional_light_data>{};
115 directional_lights.reserve(max_directional_lights);
116 auto directional_light_count = std::uint32_t{0};
117
118 for (const auto& node : directional_light_nodes) {
119 const auto& light = graph.get_component<scenes::directional_light>(node);
120 const auto& transform = graph.get_component<scenes::transform>(node);
121
122 const auto direction = -transform.up();
123
124 directional_lights.push_back(directional_light_data{math::vector4{direction, 0.0f}, light.color()});
125
126 ++directional_light_count;
127
128 if (directional_light_count >= max_directional_lights) {
129 break;
130 }
131 }
132
133 if constexpr (!Transparent) {
134 _point_lights_storage_handler.push(std::span<const point_light_data>{point_lights.data(), point_light_count});
135 _directional_lights_storage_handler.push(std::span<const directional_light_data>{directional_lights.data(), directional_light_count});
136
137 _push_handler.push("point_light_count", point_light_count);
138 _push_handler.push("directional_light_count", directional_light_count);
139
140 descriptor_handler.push("scene", environment.uniform_handler());
141 descriptor_handler.push("buffer_point_lights", _point_lights_storage_handler);
142 descriptor_handler.push("buffer_directional_lights", _directional_lights_storage_handler);
143 }
144
145 for (const auto& [name, attachment] : _attachment_names) {
146 descriptor_handler.push(name, graphics_module.attachment(attachment));
147 }
148
149 if constexpr (!Transparent) {
150 auto camera_node = environment.camera();
151
152 const auto& skybox = graph.get_component<scenes::skybox>(camera_node);
153
154 descriptor_handler.push("brdf_image", graphics_module.get_resource<graphics::image2d>(skybox.brdf_image));
155 descriptor_handler.push("irradiance_image", graphics_module.get_resource<graphics::cube_image>(skybox.irradiance_image));
156 descriptor_handler.push("prefiltered_image", graphics_module.get_resource<graphics::cube_image>(skybox.prefiltered_image));
157 }
158
159 if (!descriptor_handler.update(pipeline)) {
160 return;
161 }
162
163 descriptor_handler.bind_descriptors(command_buffer);
164
165 if constexpr (!Transparent) {
166 _push_handler.bind(command_buffer);
167 }
168
169 command_buffer.draw(3, 1, 0, 0);
170 }
171
172private:
173
174
175 graphics::push_handler _push_handler;
176 graphics::storage_handler _point_lights_storage_handler;
177 graphics::storage_handler _directional_lights_storage_handler;
178 std::vector<std::pair<std::string, std::string>> _attachment_names;
179
180}; // class resolve_filter
181
183
185
186} // namespace sbx::post
187
188#endif // LIBSBX_POST_FILTERS_RESOLVE_FILTER_HPP_
Definition: tests.cpp:6
Definition: command_buffer.hpp:15
Definition: cube_image.hpp:21
Definition: image2d.hpp:53
Definition: push_handler.hpp:18
Definition: storage_handler.hpp:17
Definition: vector3.hpp:23
Definition: vector4.hpp:24
RGBA color value type.
Definition: color.hpp:48
Definition: filter.hpp:19
Definition: resolve_filter.hpp:28
Definition: directional_light.hpp:10
Definition: point_light.hpp:9
Definition: transform.hpp:16
Definition: graphics_pipeline.hpp:106
Definition: graphics_pipeline.hpp:67
Definition: skybox.hpp:13