2#ifndef LIBSBX_POST_FILTERS_RESOLVE_FILTER_HPP_
3#define LIBSBX_POST_FILTERS_RESOLVE_FILTER_HPP_
6#include <unordered_map>
8#include <libsbx/scenes/components/transform.hpp>
10#include <libsbx/graphics/graphics_module.hpp>
11#include <libsbx/graphics/buffers/uniform_buffer.hpp>
12#include <libsbx/graphics/buffers/push_handler.hpp>
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>
23#include <libsbx/post/filter.hpp>
27template<
bool Transparent>
32 inline static constexpr auto max_point_lights = std::size_t{32};
33 inline static constexpr auto max_directional_lights = std::size_t{4};
35 struct point_light_data {
40 struct directional_light_data {
46 .depth = graphics::depth::disabled,
47 .uses_transparency = Transparent,
49 .polygon_mode = graphics::polygon_mode::fill,
50 .cull_mode = graphics::cull_mode::none,
51 .front_face = graphics::front_face::counter_clockwise
55 static constexpr auto _default_shader_path() -> std::string_view {
56 if constexpr (Transparent) {
57 return "engine://shaders/resolve_transparent";
59 return "engine://shaders/resolve_opaque";
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)} { }
75 SBX_PROFILE_SCOPE(
"resolve_filter::render");
77 auto& graphics_module = core::engine::get_module<graphics::graphics_module>();
79 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();
85 auto& pipeline = base::pipeline();
86 auto& descriptor_handler = base::descriptor_handler();
88 pipeline.bind(command_buffer);
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};
96 for (
const auto&
node : point_light_nodes) {
97 const auto model = graph.world_transform(
node);
103 point_lights.push_back(point_light_data{
math::vector4{position, light.radius()}, light.color()});
107 if (point_light_count >= max_point_lights) {
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};
118 for (
const auto&
node : directional_light_nodes) {
122 const auto direction = -transform.up();
124 directional_lights.push_back(directional_light_data{
math::vector4{direction, 0.0f}, light.color()});
126 ++directional_light_count;
128 if (directional_light_count >= max_directional_lights) {
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});
137 _push_handler.push(
"point_light_count", point_light_count);
138 _push_handler.push(
"directional_light_count", directional_light_count);
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);
145 for (
const auto& [name, attachment] : _attachment_names) {
146 descriptor_handler.push(name, graphics_module.attachment(attachment));
149 if constexpr (!Transparent) {
150 auto camera_node = environment.camera();
152 const auto& skybox = graph.get_component<
scenes::skybox>(camera_node);
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));
159 if (!descriptor_handler.update(pipeline)) {
163 descriptor_handler.bind_descriptors(command_buffer);
165 if constexpr (!Transparent) {
166 _push_handler.bind(command_buffer);
169 command_buffer.draw(3, 1, 0, 0);
178 std::vector<std::pair<std::string, std::string>> _attachment_names;
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: graphics_pipeline.hpp:106
Definition: graphics_pipeline.hpp:67
Definition: skybox.hpp:13