37 pass(pipeline, nullptr)
43 m_downsample_karis_shader = downsample_shader_template->build
46 {
"KARIS_AVERAGE", std::string()}
51 m_downsample_shader = downsample_shader_template->build();
57 m_upsample_shader = upsample_shader_template->build();
60 m_sampler = std::make_shared<gl::sampler>
70 m_vertex_array = std::make_unique<gl::vertex_array>();
76 for (
const auto&
command: m_command_buffer)
84 if (m_source_texture != texture)
86 m_source_texture = texture;
89 correct_filter_radius();
90 rebuild_command_buffer();
96 m_mip_chain_length =
length;
98 rebuild_command_buffer();
103 m_filter_radius = radius;
104 correct_filter_radius();
107 void bloom_pass::rebuild_mip_chain()
109 if (m_source_texture && m_mip_chain_length)
112 m_target_image = std::make_shared<gl::image_2d>
115 m_source_texture->get_image_view()->get_image()->get_dimensions()[0],
116 m_source_texture->get_image_view()->get_image()->get_dimensions()[1],
120 m_target_textures.resize(m_mip_chain_length);
121 m_target_framebuffers.resize(m_mip_chain_length);
122 for (
unsigned int i = 0; i < m_mip_chain_length; ++i)
125 m_target_textures[i] = std::make_shared<gl::texture_2d>
127 std::make_shared<gl::image_view_2d>
130 m_target_image->get_format(),
141 m_target_textures[i]->get_image_view(),
144 m_target_framebuffers[
i] = std::make_shared<gl::framebuffer>
147 m_target_image->get_dimensions()[0] >> i,
148 m_target_image->get_dimensions()[1] >> i
154 m_target_image =
nullptr;
155 m_target_textures.clear();
156 m_target_framebuffers.clear();
160 void bloom_pass::correct_filter_radius()
163 float aspect_ratio = 1.0f;
166 aspect_ratio =
static_cast<float>(m_target_image->get_dimensions()[1]) /
167 static_cast<float>(m_target_image->get_dimensions()[0]);
171 m_corrected_filter_radius = {m_filter_radius * aspect_ratio, m_filter_radius};
174 void bloom_pass::rebuild_command_buffer()
176 m_command_buffer.clear();
178 if (!m_source_texture ||
179 !m_mip_chain_length ||
180 !m_downsample_karis_shader ||
181 !m_downsample_shader ||
188 m_command_buffer.emplace_back
201 if (
auto source_texture_var = m_downsample_karis_shader->variable(
"source_texture"))
203 m_command_buffer.emplace_back
205 [&, source_texture_var]()
210 const auto& target_dimensions = m_target_image->get_dimensions();
211 const gl::viewport viewport[1] = {{0.0f, 0.0f, static_cast<float>(target_dimensions[0]), static_cast<float>(target_dimensions[1])}};
214 source_texture_var->update(*m_source_texture);
223 if (m_mip_chain_length > 1)
225 if (
auto source_texture_var = m_downsample_shader->variable(
"source_texture"))
227 m_command_buffer.emplace_back([&](){m_pipeline->bind_shader_program(m_downsample_shader.get());});
229 for (
int i = 1; i < static_cast<int>(m_mip_chain_length); ++
i)
231 m_command_buffer.emplace_back
233 [&, source_texture_var, i]()
235 m_pipeline->bind_framebuffer(m_target_framebuffers[i].
get());
237 const auto& target_dimensions = m_target_image->get_dimensions();
238 const gl::viewport viewport[1] = {{0.0f, 0.0f,
static_cast<float>(target_dimensions[0] >>
i),
static_cast<float>(target_dimensions[1] >> i)}};
239 m_pipeline->set_viewport(0, viewport);
242 source_texture_var->update(*m_target_textures[i - 1]);
245 m_pipeline->draw(3, 1, 0, 0);
253 m_command_buffer.emplace_back
258 m_pipeline->set_color_blend_enabled(
true);
259 m_pipeline->set_color_blend_equation
270 m_pipeline->bind_shader_program(m_upsample_shader.get());
275 if (
auto filter_radius_var = m_upsample_shader->variable(
"filter_radius"))
277 m_command_buffer.emplace_back([&, filter_radius_var](){filter_radius_var->update(m_corrected_filter_radius);});
281 if (
auto source_texture_var = m_upsample_shader->variable(
"source_texture"))
283 for (
int i =
static_cast<int>(m_mip_chain_length) - 1;
i > 0; --
i)
287 m_command_buffer.emplace_back
289 [&, source_texture_var, i, j]()
291 m_pipeline->bind_framebuffer(m_target_framebuffers[j].
get());
293 const auto& target_dimensions = m_target_image->get_dimensions();
294 const gl::viewport viewport[1] = {{0.0f, 0.0f,
static_cast<float>(target_dimensions[0] >>
j),
static_cast<float>(target_dimensions[1] >> j)}};
295 m_pipeline->set_viewport(0, viewport);
297 source_texture_var->update(*m_target_textures[i]);
300 m_pipeline->draw(3, 1, 0, 0);
Graphics pipeline interface.
void set_primitive_topology(primitive_topology topology)
Sets the primitive topology to use for drawing.
void bind_shader_program(const gl::shader_program *shader_program)
Sets the vertex input.
void bind_framebuffer(const gl::framebuffer *framebuffer)
Sets the vertex input.
void set_color_blend_enabled(bool enabled)
Controls whether blending is enabled for the corresponding color attachment.
void set_cull_mode(cull_mode mode)
Sets the triangle culling mode.
void set_viewport(std::uint32_t first_viewport, std::span< const viewport > viewports)
Sets one or more viewports.
void draw(std::uint32_t vertex_count, std::uint32_t instance_count, std::uint32_t first_vertex, std::uint32_t first_instance)
Draws primitives.
void set_depth_test_enabled(bool enabled)
Controls whether depth testing is enabled.
void bind_vertex_array(const vertex_array *array)
Binds a vertex array.
Template used to for generating one or more shader variants from a single source.
void set_mip_chain_length(unsigned int length)
Sets the mip chain length.
void set_filter_radius(float radius)
Sets the upsample filter radius.
void render(render::context &ctx) override
Renders a bloom texture.
void set_source_texture(std::shared_ptr< gl::texture_2d > texture)
Sets the bloom source texture.
bloom_pass(gl::pipeline *pipeline, resource_manager *resource_manager)
Constructs a bloom pass.
gl::pipeline * m_pipeline
Manages the loading, caching, and saving of resources.
std::shared_ptr< T > load(const std::filesystem::path &path)
Loads and caches a resource.
Commands which operate on entity::id components.
@ clamp_to_edge
Clamp to edge wrap mode.
@ color_attachment_bit
Framebuffer color attachment.
@ back
Back-facing triangles are discarded.
@ linear
Linear filtering.
@ linear
Linear filtering.
@ triangle_list
Separate triangle primitives.
T length(const quaternion< T > &q)
Calculates the length of a quaternion.
constexpr matrix< T, N, M >::column_vector_type & get(matrix< T, N, M > &m) noexcept
Extracts the Ith column from a matrix.
Viewport position, dimensions, and depth range.