Skip to content

Commit

Permalink
new bloom render tasks, setup util and hdr bloom code example
Browse files Browse the repository at this point in the history
  • Loading branch information
Green-Sky committed Mar 28, 2022
1 parent 8f44e09 commit 5e58a61
Show file tree
Hide file tree
Showing 14 changed files with 1,148 additions and 72 deletions.
58 changes: 58 additions & 0 deletions framework/opengl_renderer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,49 @@ target_link_libraries(blur_render_task
engine
)

############# bloom_extraction render task ###########

add_library(bloom_extraction_render_task
src/mm/opengl/render_tasks/bloom_extraction.hpp
src/mm/opengl/render_tasks/bloom_extraction.cpp
)

target_include_directories(bloom_extraction_render_task PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/src")

target_link_libraries(bloom_extraction_render_task
opengl_renderer_s
engine
)

############# bloom_combine render task ###########

add_library(bloom_combine_render_task
src/mm/opengl/render_tasks/bloom_combine.hpp
src/mm/opengl/render_tasks/bloom_combine.cpp
)

target_include_directories(bloom_combine_render_task PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/src")

target_link_libraries(bloom_combine_render_task
opengl_renderer_s
engine
)

############# composition render task ###########
# intendet for bloom compositing and tonemapping

add_library(composition_render_task
src/mm/opengl/render_tasks/composition.hpp
src/mm/opengl/render_tasks/composition.cpp
)

target_include_directories(composition_render_task PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/src")

target_link_libraries(composition_render_task
opengl_renderer_s
engine
)

############# tilemap renderer ###########

add_library(tilemap_render_task
Expand Down Expand Up @@ -210,6 +253,21 @@ target_link_libraries(fast_sky_render_task
engine
)

############# bloom ###########

add_library(bloom
src/mm/opengl/bloom.hpp
src/mm/opengl/bloom.cpp
)

target_include_directories(bloom PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/src")

target_link_libraries(bloom
bloom_extraction_render_task
blur_render_task
bloom_combine_render_task
)

########################

if (BUILD_TESTING)
Expand Down
158 changes: 158 additions & 0 deletions framework/opengl_renderer/src/mm/opengl/bloom.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
#include "./bloom.hpp"

#include <mm/opengl/render_tasks/bloom_extraction.hpp>
#include <mm/opengl/render_tasks/blur.hpp>
#include <mm/opengl/render_tasks/bloom_combine.hpp>

#include <mm/opengl/fbo_builder.hpp>
#include <mm/opengl/texture_loader.hpp>

namespace MM::OpenGL {

using namespace entt::literals;

void setup_bloom(
MM::Engine& engine,
const std::string color_src_tex,
const size_t bloom_phases,
const float bloom_in_scale,
const float bloom_phase_scale
) {
assert(bloom_phases > 1);
auto& rs = engine.getService<MM::Services::OpenGLRenderer>();
auto& rm_t = MM::ResourceManager<MM::OpenGL::Texture>::ref();
auto [w, h] = engine.getService<MM::Services::SDLService>().getWindowSize();

#ifdef MM_OPENGL_3_GLES
#if 0 // NOPE!!
// TODO: caps at 1, invest in half float?
const auto bloom_internal_format = GL_RGB565; // prolly fine
const auto bloom_format_type = GL_UNSIGNED_BYTE;
#else
const auto bloom_internal_format = GL_RGB16F;
const auto bloom_format_type = GL_FLOAT;
#endif
#else
const auto bloom_internal_format = GL_RGB16F;
const auto bloom_format_type = GL_FLOAT;
#endif

{ // bloom in (bloom extraction)
rm_t.reload<MM::OpenGL::TextureLoaderEmpty>(
"bloom_in",
bloom_internal_format,
w * bloom_in_scale, h * bloom_in_scale,
GL_RGB, bloom_format_type
);
{ // filter
rm_t.get("bloom_in"_hs)->bind(0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}

rs.targets["bloom_extraction"] = MM::OpenGL::FBOBuilder::start()
.attachTexture(rm_t.get("bloom_in"_hs), GL_COLOR_ATTACHMENT0)
.setResizeFactors(bloom_in_scale, bloom_in_scale)
.setResize(true)
.finish();
assert(rs.targets["bloom_extraction"]);
}

// blur textures and fbos
for (size_t i = 1; i <= bloom_phases; i++) {
// TODO: further dedup
std::string tex_out_name {"blur_out" + std::to_string(i)};
auto tex_out_id = entt::hashed_string::value(tex_out_name.c_str());
rm_t.reload<MM::OpenGL::TextureLoaderEmpty>(
tex_out_id,
bloom_internal_format,
w * bloom_in_scale * glm::pow(bloom_phase_scale, i), h * bloom_in_scale * glm::pow(bloom_phase_scale, i),
GL_RGB, bloom_format_type
);
{ // filter
rm_t.get(tex_out_id)->bind(0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}

std::string tex_tmp_name {"blur_tmp" + std::to_string(i)};
auto tex_tmp_id = entt::hashed_string::value(tex_tmp_name.c_str());
rm_t.reload<MM::OpenGL::TextureLoaderEmpty>(
tex_tmp_id,
bloom_internal_format,
w * bloom_in_scale * glm::pow(bloom_phase_scale, i), h * bloom_in_scale * glm::pow(bloom_phase_scale, i),
GL_RGB, bloom_format_type
);
{ // filter
rm_t.get(tex_tmp_id)->bind(0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}

rs.targets[tex_out_name] = MM::OpenGL::FBOBuilder::start()
.attachTexture(rm_t.get(tex_out_id), GL_COLOR_ATTACHMENT0)
.setResizeFactors(bloom_in_scale * glm::pow(bloom_phase_scale, i), bloom_in_scale * glm::pow(bloom_phase_scale, i))
.setResize(true)
.finish();
assert(rs.targets[tex_out_name]);

rs.targets[tex_tmp_name] = MM::OpenGL::FBOBuilder::start()
.attachTexture(rm_t.get(tex_tmp_id), GL_COLOR_ATTACHMENT0)
.setResizeFactors(bloom_in_scale * glm::pow(bloom_phase_scale, i), bloom_in_scale * glm::pow(bloom_phase_scale, i))
.setResize(true)
.finish();
assert(rs.targets[tex_tmp_name]);
}

{ // render tasks
auto& extraction = rs.addRenderTask<MM::OpenGL::RenderTasks::BloomExtraction>(engine);
extraction.src_tex = color_src_tex;
extraction.target_fbo = "bloom_extraction";

const glm::vec2 blur_factor {1.f, 1.f};

{ // blur rt
std::string prev_out_tex = "bloom_in";
for (size_t i = 1; i <= bloom_phases; i++) {
auto& blur = rs.addRenderTask<MM::OpenGL::RenderTasks::Blur>(engine);
// h
blur.in_tex = prev_out_tex;
blur.temp_fbo = "blur_tmp" + std::to_string(i);
// v
blur.temp_tex = "blur_tmp" + std::to_string(i);
blur.out_fbo = "blur_out" + std::to_string(i);
blur.out_tex = "blur_out" + std::to_string(i);
blur.tex_offset_factor = blur_factor * glm::vec2{2.f, 1.f}; // the input texture is double the size

// old blur:
//blur.tex_offset = {1.f/(w * bloom_in_scale * bloom_in_scale), 1.f/(h * bloom_in_scale * bloom_in_scale)};

prev_out_tex = blur.out_tex;
}
}

// combine passes
for (size_t i = bloom_phases; i > 1; i--) {
auto& combine = rs.addRenderTask<MM::OpenGL::RenderTasks::BloomCombine>(engine);
if (i == bloom_phases) {
combine.tex0 = "blur_out" + std::to_string(i);
} else {
combine.tex0 = "blur_tmp" + std::to_string(i);
}
combine.tex1 = "blur_out" + std::to_string(i-1);
combine.target_fbo = "blur_tmp" + std::to_string(i-1); // -> blur_tmpi-1
}
}
}

} // MM::OpenGL

27 changes: 27 additions & 0 deletions framework/opengl_renderer/src/mm/opengl/bloom.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#pragma once

#include <string>

#include "./render_task.hpp"

namespace MM::OpenGL {

// helper function to setup a bloom blur and recombine chain
// creates (texture) rendertarget, fbos and rendertasks
// outputs blur to "blur_tmp1" texture
//
// you still need to add the Composition rendertask (or eqv) your self, eg:
// auto& comp = rs.addRenderTask<MM::OpenGL::RenderTasks::Composition>(engine);
// comp.color_tex = "hdr_color";
// comp.bloom_tex = "blur_tmp1";
// comp.target_fbo = "display";
void setup_bloom(
MM::Engine& engine,
const std::string color_src_tex = "hdr_color", // texture to extract color from
const size_t bloom_phases = 5, // number of downsampled blurs (4 prob fine for 720, 5 for 1080)
const float bloom_in_scale = 0.5f, // scale of bloom extraction layer (1 - 0.5 best, lower for more perf)
const float bloom_phase_scale = 0.5f // ammount of scaling per downsampling
);

} // MM::OpenGL

2 changes: 1 addition & 1 deletion framework/opengl_renderer/src/mm/opengl/render_task.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@ namespace MM::OpenGL {
//virtual void reload(void) {} // TODO: remove
//virtual std::vector<const char*> getShaderPaths(void) {return {};} // TODO: remove
};
}
} // MM:OpenGL

Loading

0 comments on commit 5e58a61

Please sign in to comment.