Browse Source

Improve bloom

master
C. J. Howard 1 year ago
parent
commit
ee0cef6162
9 changed files with 299 additions and 138 deletions
  1. +0
    -2
      src/game/context.hpp
  2. +3
    -23
      src/game/graphics.cpp
  3. +6
    -5
      src/game/state/boot.cpp
  4. +2
    -2
      src/game/state/nest-selection.cpp
  5. +197
    -82
      src/render/passes/bloom-pass.cpp
  6. +75
    -20
      src/render/passes/bloom-pass.hpp
  7. +11
    -2
      src/render/passes/final-pass.cpp
  8. +4
    -1
      src/render/passes/final-pass.hpp
  9. +1
    -1
      src/render/passes/sky-pass.cpp

+ 0
- 2
src/game/context.hpp View File

@ -185,8 +185,6 @@ struct context
gl::texture_2d* hdr_color_texture;
gl::texture_2d* hdr_depth_texture;
gl::framebuffer* hdr_framebuffer;
gl::texture_2d* bloom_color_texture;
gl::framebuffer* bloom_framebuffer;
gl::texture_2d* shadow_map_depth_texture;
gl::framebuffer* shadow_map_framebuffer;

+ 3
- 23
src/game/graphics.cpp View File

@ -18,6 +18,7 @@
*/
#include "game/graphics.hpp"
#include "render/passes/bloom-pass.hpp"
#include "gl/framebuffer.hpp"
#include "gl/texture-2d.hpp"
#include "gl/texture-wrapping.hpp"
@ -61,17 +62,6 @@ void create_framebuffers(game::context& ctx)
ctx.hdr_framebuffer->attach(gl::framebuffer_attachment_type::depth, ctx.hdr_depth_texture);
ctx.hdr_framebuffer->attach(gl::framebuffer_attachment_type::stencil, ctx.hdr_depth_texture);
// Calculate bloom resolution
int2 bloom_resolution = ctx.render_resolution / 2;
// Create bloom framebuffer (16F color, no depth)
ctx.bloom_color_texture = new gl::texture_2d(bloom_resolution.x(), bloom_resolution.y(), gl::pixel_type::float_16, gl::pixel_format::rgb);
ctx.bloom_color_texture->set_wrapping(gl::texture_wrapping::extend, gl::texture_wrapping::extend);
ctx.bloom_color_texture->set_filters(gl::texture_min_filter::linear, gl::texture_mag_filter::linear);
ctx.bloom_color_texture->set_max_anisotropy(0.0f);
ctx.bloom_framebuffer = new gl::framebuffer(bloom_resolution.x(), bloom_resolution.y());
ctx.bloom_framebuffer->attach(gl::framebuffer_attachment_type::color, ctx.bloom_color_texture);
// Load shadow map resolution from config
int shadow_map_resolution = 4096;
if (ctx.config->contains("shadow_map_resolution"))
@ -100,12 +90,6 @@ void destroy_framebuffers(game::context& ctx)
delete ctx.hdr_depth_texture;
ctx.hdr_depth_texture = nullptr;
// Delete bloom framebuffer and its attachments
delete ctx.bloom_framebuffer;
ctx.bloom_framebuffer = nullptr;
delete ctx.bloom_color_texture;
ctx.bloom_color_texture = nullptr;
// Delete shadow map framebuffer and its attachments
delete ctx.shadow_map_framebuffer;
ctx.shadow_map_framebuffer = nullptr;
@ -131,12 +115,8 @@ void change_render_resolution(game::context& ctx, float scale)
resize_framebuffer_attachment(*ctx.hdr_color_texture, ctx.render_resolution);
resize_framebuffer_attachment(*ctx.hdr_depth_texture, ctx.render_resolution);
// Recalculate bloom resolution
int2 bloom_resolution = ctx.render_resolution / 2;
// Resize bloom framebuffer and attachments
ctx.bloom_framebuffer->resize({bloom_resolution.x(), bloom_resolution.y()});
resize_framebuffer_attachment(*ctx.bloom_color_texture, bloom_resolution);
// Resize bloom render pass
ctx.common_bloom_pass->resize();
ctx.logger->pop_task(EXIT_SUCCESS);
}

+ 6
- 5
src/game/state/boot.cpp View File

@ -447,14 +447,15 @@ void boot::setup_rendering()
// Setup common render passes
{
ctx.common_bloom_pass = new render::bloom_pass(ctx.rasterizer, ctx.bloom_framebuffer, ctx.resource_manager);
ctx.common_bloom_pass = new render::bloom_pass(ctx.rasterizer, ctx.resource_manager);
ctx.common_bloom_pass->set_source_texture(ctx.hdr_color_texture);
ctx.common_bloom_pass->set_brightness_threshold(1.0f);
ctx.common_bloom_pass->set_blur_iterations(5);
ctx.common_bloom_pass->set_mip_chain_length(6);
ctx.common_bloom_pass->set_filter_radius(0.005f);
ctx.common_final_pass = new render::final_pass(ctx.rasterizer, &ctx.rasterizer->get_default_framebuffer(), ctx.resource_manager);
ctx.common_final_pass->set_color_texture(ctx.hdr_color_texture);
ctx.common_final_pass->set_bloom_texture(ctx.bloom_color_texture);
ctx.common_final_pass->set_bloom_texture(ctx.common_bloom_pass->get_bloom_texture());
ctx.common_final_pass->set_bloom_weight(0.04f);
ctx.common_final_pass->set_blue_noise_texture(blue_noise_map);
}
@ -526,7 +527,7 @@ void boot::setup_rendering()
ctx.surface_compositor->add_pass(ctx.ground_pass);
ctx.surface_compositor->add_pass(ctx.surface_material_pass);
//ctx.surface_compositor->add_pass(ctx.surface_outline_pass);
//ctx.surface_compositor->add_pass(ctx.common_bloom_pass);
ctx.surface_compositor->add_pass(ctx.common_bloom_pass);
ctx.surface_compositor->add_pass(ctx.common_final_pass);
}

+ 2
- 2
src/game/state/nest-selection.cpp View File

@ -714,7 +714,7 @@ void nest_selection::enable_controls()
[&ctx = this->ctx](float)
{
//ctx.astronomy_system->set_exposure_offset(ctx.astronomy_system->get_exposure_offset() - 1.0f);
ctx.surface_camera->set_exposure(ctx.surface_camera->get_exposure() + 0.5f * static_cast<float>(ctx.loop.get_update_period()));
ctx.surface_camera->set_exposure(ctx.surface_camera->get_exposure() + 2.0f * static_cast<float>(ctx.loop.get_update_period()));
ctx.logger->log("EV100: " + std::to_string(ctx.surface_camera->get_exposure()));
}
);
@ -724,7 +724,7 @@ void nest_selection::enable_controls()
[&ctx = this->ctx](float)
{
//ctx.astronomy_system->set_exposure_offset(ctx.astronomy_system->get_exposure_offset() + 1.0f);
ctx.surface_camera->set_exposure(ctx.surface_camera->get_exposure() - 0.5f * static_cast<float>(ctx.loop.get_update_period()));
ctx.surface_camera->set_exposure(ctx.surface_camera->get_exposure() - 2.0f * static_cast<float>(ctx.loop.get_update_period()));
ctx.logger->log("EV100: " + std::to_string(ctx.surface_camera->get_exposure()));
}
);

+ 197
- 82
src/render/passes/bloom-pass.cpp View File

@ -32,63 +32,47 @@
#include "gl/texture-filter.hpp"
#include "render/vertex-attribute.hpp"
#include "render/context.hpp"
#include <algorithm>
#include <cmath>
#include <glad/glad.h>
#include <iostream>
namespace render {
bloom_pass::bloom_pass(gl::rasterizer* rasterizer, const gl::framebuffer* framebuffer, resource_manager* resource_manager):
pass(rasterizer, framebuffer),
bloom_pass::bloom_pass(gl::rasterizer* rasterizer, resource_manager* resource_manager):
pass(rasterizer, nullptr),
source_texture(nullptr),
brightness_threshold(1.0f),
blur_iterations(1)
source_texel_size{1.0f, 1.0f},
mip_chain_length(0),
filter_radius(0.005f),
corrected_filter_radius{filter_radius, filter_radius}
{
// Create clone of framebuffer texture
const gl::texture_2d* framebuffer_texture = framebuffer->get_color_attachment();
auto dimensions = framebuffer_texture->get_dimensions();
auto pixel_type = framebuffer_texture->get_pixel_type();
auto pixel_format = framebuffer_texture->get_pixel_format();
auto wrapping = framebuffer_texture->get_wrapping();
auto filters = framebuffer_texture->get_filters();
float max_anisotropy = framebuffer_texture->get_max_anisotropy();
cloned_framebuffer_texture = new gl::texture_2d(std::get<0>(dimensions), std::get<1>(dimensions), pixel_type, pixel_format);
cloned_framebuffer_texture->set_wrapping(std::get<0>(wrapping), std::get<1>(wrapping));
cloned_framebuffer_texture->set_filters(std::get<0>(filters), std::get<1>(filters));
cloned_framebuffer_texture->set_max_anisotropy(max_anisotropy);
// Load downsample with Karis average shader
downsample_karis_shader = resource_manager->load<gl::shader_program>("bloom-downsample-karis.glsl");
downsample_karis_source_texture_input = downsample_karis_shader->get_input("source_texture");
downsample_karis_texel_size_input = downsample_karis_shader->get_input("texel_size");
// Create clone of framebuffer
cloned_framebuffer = new gl::framebuffer(std::get<0>(dimensions), std::get<1>(dimensions));
cloned_framebuffer->attach(gl::framebuffer_attachment_type::color, cloned_framebuffer_texture);
// Load downsample shader
downsample_shader = resource_manager->load<gl::shader_program>("bloom-downsample.glsl");
downsample_source_texture_input = downsample_shader->get_input("source_texture");
downsample_texel_size_input = downsample_shader->get_input("texel_size");
// Setup pingponging
pingpong_textures[0] = framebuffer_texture;
pingpong_textures[1] = cloned_framebuffer_texture;
pingpong_framebuffers[0] = framebuffer;
pingpong_framebuffers[1] = cloned_framebuffer;
// Load brightness threshold shader
threshold_shader = resource_manager->load<gl::shader_program>("brightness-threshold.glsl");
threshold_shader_image_input = threshold_shader->get_input("image");
threshold_shader_resolution_input = threshold_shader->get_input("resolution");
threshold_shader_threshold_input = threshold_shader->get_input("threshold");
// Load blur shader
blur_shader = resource_manager->load<gl::shader_program>("blur.glsl");
blur_shader_image_input = blur_shader->get_input("image");
blur_shader_resolution_input = blur_shader->get_input("resolution");
blur_shader_direction_input = blur_shader->get_input("direction");
// Load upsample shader
upsample_shader = resource_manager->load<gl::shader_program>("bloom-upsample.glsl");
upsample_source_texture_input = upsample_shader->get_input("source_texture");
upsample_filter_radius_input = upsample_shader->get_input("filter_radius");
const float vertex_data[] =
{
-1.0f, 1.0f, 0.0f,
-1.0f, -1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f
-1.0f, 1.0f,
-1.0f, -1.0f,
1.0f, 1.0f,
1.0f, 1.0f,
-1.0f, -1.0f,
1.0f, -1.0f
};
std::size_t vertex_size = 3;
std::size_t vertex_size = 2;
std::size_t vertex_stride = sizeof(float) * vertex_size;
std::size_t vertex_count = 6;
@ -101,7 +85,7 @@ bloom_pass::bloom_pass(gl::rasterizer* rasterizer, const gl::framebuffer* frameb
position_attribute.offset = 0;
position_attribute.stride = vertex_stride;
position_attribute.type = gl::vertex_attribute_type::float_32;
position_attribute.components = 3;
position_attribute.components = 2;
// Bind vertex attributes to VAO
quad_vao->bind(render::vertex_attribute::position, position_attribute);
@ -109,67 +93,198 @@ bloom_pass::bloom_pass(gl::rasterizer* rasterizer, const gl::framebuffer* frameb
bloom_pass::~bloom_pass()
{
delete cloned_framebuffer;
delete cloned_framebuffer_texture;
delete quad_vao;
delete quad_vbo;
set_mip_chain_length(0);
}
void bloom_pass::render(const render::context& ctx, render::queue& queue) const
{
glDisable(GL_BLEND);
{
if (!source_texture || !mip_chain_length)
return;
// Disable depth testing
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
// Enable back-face culling
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
// Determine viewport based on framebuffer resolution
auto viewport = framebuffer->get_dimensions();
rasterizer->set_viewport(0, 0, std::get<0>(viewport), std::get<1>(viewport));
float2 resolution = {std::get<0>(viewport), std::get<1>(viewport)};
// Perform brightness threshold subpass, rendering to the first pingpong fbo
rasterizer->use_framebuffer(*pingpong_framebuffers[0]);
rasterizer->use_program(*threshold_shader);
threshold_shader_image_input->upload(source_texture);
threshold_shader_resolution_input->upload(resolution);
threshold_shader_threshold_input->upload(brightness_threshold);
rasterizer->draw_arrays(*quad_vao, gl::drawing_mode::triangles, 0, 6);
// Disable blending
glDisable(GL_BLEND);
// Perform iterative blur subpass
const float2 direction_horizontal = {1, 0};
const float2 direction_vertical = {0, 1};
rasterizer->use_program(*blur_shader);
blur_shader_resolution_input->upload(resolution);
for (int i = 0; i < blur_iterations; ++i)
// Downsample first mip with Karis average
{
// Perform horizontal blur
rasterizer->use_framebuffer(*pingpong_framebuffers[1]);
blur_shader_image_input->upload(pingpong_textures[0]);
blur_shader_direction_input->upload(direction_horizontal);
rasterizer->use_program(*downsample_karis_shader);
downsample_karis_source_texture_input->upload(source_texture);
downsample_karis_texel_size_input->upload(source_texel_size);
rasterizer->use_framebuffer(*framebuffers[0]);
rasterizer->set_viewport(0, 0, textures[0]->get_width(), textures[0]->get_height());
rasterizer->draw_arrays(*quad_vao, gl::drawing_mode::triangles, 0, 6);
}
// Downsample remaining mips
rasterizer->use_program(*downsample_shader);
for (int i = 1; i < static_cast<int>(mip_chain_length); ++i)
{
rasterizer->use_framebuffer(*framebuffers[i]);
rasterizer->set_viewport(0, 0, textures[i]->get_width(), textures[i]->get_height());
// Use previous downsample texture as downsample source
downsample_source_texture_input->upload(textures[i - 1]);
downsample_texel_size_input->upload(texel_sizes[i - 1]);
rasterizer->draw_arrays(*quad_vao, gl::drawing_mode::triangles, 0, 6);
}
// Enable additive blending
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
glBlendEquation(GL_FUNC_ADD);
// Upsample
rasterizer->use_program(*upsample_shader);
upsample_filter_radius_input->upload(corrected_filter_radius);
for (int i = static_cast<int>(mip_chain_length) - 1; i > 0; --i)
{
const int j = i - 1;
rasterizer->use_framebuffer(*framebuffers[j]);
rasterizer->set_viewport(0, 0, textures[j]->get_width(), textures[j]->get_height());
upsample_source_texture_input->upload(textures[i]);
// Perform vertical blur
rasterizer->use_framebuffer(*pingpong_framebuffers[0]);
blur_shader_image_input->upload(pingpong_textures[1]);
blur_shader_direction_input->upload(direction_vertical);
rasterizer->draw_arrays(*quad_vao, gl::drawing_mode::triangles, 0, 6);
}
}
void bloom_pass::resize()
{
unsigned int source_width = 0;
unsigned int source_height = 0;
source_texel_size = {0.0f, 0.0f};
if (source_texture)
{
// Get source texture dimensions
source_width = source_texture->get_width();
source_height = source_texture->get_height();
// Update source texel size
source_texel_size.x() = 1.0f / static_cast<float>(source_texture->get_width());
source_texel_size.y() = 1.0f / static_cast<float>(source_texture->get_height());
// Correct filter radius according to source texture aspect ratio
corrected_filter_radius = {filter_radius * (source_texel_size.x() / source_texel_size.y()), filter_radius};
}
// Resize mip chain
for (unsigned int i = 0; i < mip_chain_length; ++i)
{
// Calculate mip dimensions
unsigned int mip_width = std::max<unsigned int>(1, source_width >> (i + 1));
unsigned int mip_height = std::max<unsigned int>(1, source_height >> (i + 1));
// Resize mip texture
textures[i]->resize(mip_width, mip_height, nullptr);
// Resize mip framebuffer
framebuffers[i]->resize({(int)mip_width, (int)mip_height});
// Update mip texel size
texel_sizes[i] = 1.0f / float2{static_cast<float>(mip_width), static_cast<float>(mip_height)};
}
}
void bloom_pass::set_source_texture(const gl::texture_2d* texture)
{
this->source_texture = texture;
if (texture != source_texture)
{
if (texture)
{
if (source_texture)
{
if (texture->get_width() != source_texture->get_width() || texture->get_height() != source_texture->get_height())
{
source_texture = texture;
resize();
}
else
{
source_texture = texture;
}
}
else
{
source_texture = texture;
resize();
}
}
else
{
source_texture = texture;
}
}
}
void bloom_pass::set_brightness_threshold(float threshold)
void bloom_pass::set_mip_chain_length(unsigned int length)
{
this->brightness_threshold = threshold;
unsigned int source_width = 0;
unsigned int source_height = 0;
if (source_texture)
{
// Get source texture dimensions
source_width = source_texture->get_width();
source_height = source_texture->get_height();
}
if (length > mip_chain_length)
{
// Generate additional framebuffers
for (unsigned int i = mip_chain_length; i < length; ++i)
{
// Calculate mip resolution
unsigned int mip_width = std::max<unsigned int>(1, source_width >> (i + 1));
unsigned int mip_height = std::max<unsigned int>(1, source_height >> (i + 1));
// Generate mip texture
gl::texture_2d* texture = new gl::texture_2d(mip_width, mip_height, gl::pixel_type::float_16, gl::pixel_format::rgb);
texture->set_wrapping(gl::texture_wrapping::extend, gl::texture_wrapping::extend);
texture->set_filters(gl::texture_min_filter::linear, gl::texture_mag_filter::linear);
texture->set_max_anisotropy(0.0f);
textures.push_back(texture);
// Generate mip framebuffer
gl::framebuffer* framebuffer = new gl::framebuffer(mip_width, mip_height);
framebuffer->attach(gl::framebuffer_attachment_type::color, texture);
framebuffers.push_back(framebuffer);
// Calculate mip texel size
texel_sizes.push_back(1.0f / float2{static_cast<float>(mip_width), static_cast<float>(mip_height)});
}
}
else if (length < mip_chain_length)
{
// Free excess framebuffers
while (framebuffers.size() > length)
{
delete framebuffers.back();
framebuffers.pop_back();
delete textures.back();
textures.pop_back();
texel_sizes.pop_back();
}
}
// Update mip chain length
mip_chain_length = length;
}
void bloom_pass::set_blur_iterations(int iterations)
void bloom_pass::set_filter_radius(float radius) noexcept
{
this->blur_iterations = iterations;
filter_radius = radius;
corrected_filter_radius = {filter_radius * (source_texel_size.x() / source_texel_size.y()), filter_radius};
}
} // namespace render

+ 75
- 20
src/render/passes/bloom-pass.hpp View File

@ -32,43 +32,98 @@ class resource_manager;
namespace render {
/**
* Physically-based bloom render pass.
*
* @see Jimenez, J. (2014). Next generation post processing in call of duty advanced warfare. SIGGRAPH Advances in Real-Time Rendering.
* @see https://learnopengl.com/Guest-Articles/2022/Phys.-Based-Bloom
*/
class bloom_pass: public pass
{
public:
bloom_pass(gl::rasterizer* rasterizer, const gl::framebuffer* framebuffer, resource_manager* resource_manager);
/**
* Constructs a bloom pass.
*
* @param rasterizer Rasterizer.
* @param resource_manager Resource manager.
*/
bloom_pass(gl::rasterizer* rasterizer, resource_manager* resource_manager);
/**
* Destructs a bloom pass.
*/
virtual ~bloom_pass();
/**
* Renders a bloom texture.
*
* @param ctx Render context.
* @param queue Render queue.
*/
virtual void render(const render::context& ctx, render::queue& queue) const final;
/**
* Resizes the mip chain resolution according to the resolution of the source texture.
*/
void resize();
/**
* Sets the bloom source texture.
*
* @param texture Bloom source texture.
*/
void set_source_texture(const gl::texture_2d* texture);
void set_brightness_threshold(float threshold);
void set_blur_iterations(int iterations);
/**
* Sets the mip chain length. A length of `1` indicates a single stage bloom.
*
* @param length Mip chain length.
*/
void set_mip_chain_length(unsigned int length);
/**
* Sets the upsample filter radius.
*
* @param radius Upsample filter radius, in texture coordinates.
*/
void set_filter_radius(float radius) noexcept;
/**
* Returns the texture containing the bloom result.
*/
const gl::texture_2d* get_bloom_texture() const;
private:
gl::vertex_buffer* quad_vbo;
gl::vertex_array* quad_vao;
const gl::texture_2d* source_texture;
float2 source_texel_size;
const gl::framebuffer* pingpong_framebuffers[2];
const gl::texture_2d* pingpong_textures[2];
gl::texture_2d* cloned_framebuffer_texture;
gl::framebuffer* cloned_framebuffer;
gl::shader_program* downsample_karis_shader;
const gl::shader_input* downsample_karis_source_texture_input;
const gl::shader_input* downsample_karis_texel_size_input;
gl::shader_program* threshold_shader;
const gl::shader_input* threshold_shader_image_input;
const gl::shader_input* threshold_shader_resolution_input;
const gl::shader_input* threshold_shader_threshold_input;
gl::shader_program* downsample_shader;
const gl::shader_input* downsample_source_texture_input;
const gl::shader_input* downsample_texel_size_input;
gl::shader_program* blur_shader;
const gl::shader_input* blur_shader_image_input;
const gl::shader_input* blur_shader_resolution_input;
const gl::shader_input* blur_shader_direction_input;
gl::shader_program* upsample_shader;
const gl::shader_input* upsample_source_texture_input;
const gl::shader_input* upsample_filter_radius_input;
const gl::texture_2d* source_texture;
float brightness_threshold;
int blur_iterations;
gl::vertex_buffer* quad_vbo;
gl::vertex_array* quad_vao;
unsigned int mip_chain_length;
std::vector<gl::framebuffer*> framebuffers;
std::vector<gl::texture_2d*> textures;
std::vector<float2> texel_sizes;
float filter_radius;
float2 corrected_filter_radius;
};
inline const gl::texture_2d* bloom_pass::get_bloom_texture() const
{
return textures.empty() ? nullptr : textures.front();
}
} // namespace render
#endif // ANTKEEPER_RENDER_BLOOM_PASS_HPP

+ 11
- 2
src/render/passes/final-pass.cpp View File

@ -41,12 +41,14 @@ final_pass::final_pass(gl::rasterizer* rasterizer, const gl::framebuffer* frameb
pass(rasterizer, framebuffer),
color_texture(nullptr),
bloom_texture(nullptr),
bloom_weight(0.04f),
blue_noise_texture(nullptr),
blue_noise_scale(1.0)
blue_noise_scale(1.0f)
{
shader_program = resource_manager->load<gl::shader_program>("final.glsl");
color_texture_input = shader_program->get_input("color_texture");
bloom_texture_input = shader_program->get_input("bloom_texture");
bloom_weight_input = shader_program->get_input("bloom_weight");
blue_noise_texture_input = shader_program->get_input("blue_noise_texture");
blue_noise_scale_input = shader_program->get_input("blue_noise_scale");
resolution_input = shader_program->get_input("resolution");
@ -109,6 +111,8 @@ void final_pass::render(const render::context& ctx, render::queue& queue) const
color_texture_input->upload(color_texture);
if (bloom_texture && bloom_texture_input)
bloom_texture_input->upload(bloom_texture);
if (bloom_weight_input)
bloom_weight_input->upload(bloom_weight);
if (blue_noise_texture && blue_noise_texture_input)
blue_noise_texture_input->upload(blue_noise_texture);
if (blue_noise_scale_input)
@ -127,11 +131,16 @@ void final_pass::set_color_texture(const gl::texture_2d* texture)
this->color_texture = texture;
}
void final_pass::set_bloom_texture(const gl::texture_2d* texture)
void final_pass::set_bloom_texture(const gl::texture_2d* texture) noexcept
{
this->bloom_texture = texture;
}
void final_pass::set_bloom_weight(float weight) noexcept
{
this->bloom_weight = weight;
}
void final_pass::set_blue_noise_texture(const gl::texture_2d* texture)
{
this->blue_noise_texture = texture;

+ 4
- 1
src/render/passes/final-pass.hpp View File

@ -42,13 +42,15 @@ public:
virtual void render(const render::context& ctx, render::queue& queue) const final;
void set_color_texture(const gl::texture_2d* texture);
void set_bloom_texture(const gl::texture_2d* texture);
void set_bloom_texture(const gl::texture_2d* texture) noexcept;
void set_bloom_weight(float weight) noexcept;
void set_blue_noise_texture(const gl::texture_2d* texture);
private:
gl::shader_program* shader_program;
const gl::shader_input* color_texture_input;
const gl::shader_input* bloom_texture_input;
const gl::shader_input* bloom_weight_input;
const gl::shader_input* blue_noise_texture_input;
const gl::shader_input* blue_noise_scale_input;
const gl::shader_input* resolution_input;
@ -58,6 +60,7 @@ private:
const gl::texture_2d* color_texture;
const gl::texture_2d* bloom_texture;
float bloom_weight;
const gl::texture_2d* blue_noise_texture;
float blue_noise_scale;
};

+ 1
- 1
src/render/passes/sky-pass.cpp View File

@ -215,8 +215,8 @@ void sky_pass::render(const render::context& ctx, render::queue& queue) const
float3 sun_direction = math::normalize(sun_position);
// Interpolate and expose sun luminance and illuminance
float3 sun_luminance = sun_luminance_tween.interpolate(ctx.alpha) * ctx.exposure;
float3 sun_illuminance = sun_illuminance_tween.interpolate(ctx.alpha) * ctx.exposure;
float3 sun_luminance = sun_luminance_tween.interpolate(ctx.alpha) * ctx.exposure;
float3 moon_position = moon_position_tween.interpolate(ctx.alpha);
float3 moon_direction = math::normalize(moon_position);

Loading…
Cancel
Save