Skip to content

Commit

Permalink
gh-53: impl gaussian bloom (unity)
Browse files Browse the repository at this point in the history
  • Loading branch information
EgorOrachyov committed Oct 29, 2023
1 parent b45782d commit 3722735
Show file tree
Hide file tree
Showing 62 changed files with 2,913 additions and 75 deletions.
2 changes: 2 additions & 0 deletions engine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,8 @@ add_library(wmoge STATIC
render/visibility.hpp
render/geometry/pass_gbuffer.cpp
render/geometry/pass_gbuffer.hpp
render/post_process/pass_bloom.cpp
render/post_process/pass_bloom.hpp
render/post_process/pass_tonemap.cpp
render/post_process/pass_tonemap.hpp
resource/audio_stream.cpp
Expand Down
4 changes: 4 additions & 0 deletions engine/render/deferred_pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "debug/profiler.hpp"
#include "geometry/pass_gbuffer.hpp"
#include "platform/window_manager.hpp"
#include "post_process/pass_bloom.hpp"
#include "post_process/pass_tonemap.hpp"

namespace wmoge {
Expand All @@ -42,9 +43,11 @@ namespace wmoge {
WG_AUTO_PROFILE_RENDER("DeferredPipeline::init");

m_pass_gbuffer = std::make_unique<PassGBuffer>();
m_pass_bloom = std::make_unique<PassBloom>();
m_pass_tonemap = std::make_unique<PassToneMap>();

m_stages.push_back(m_pass_gbuffer.get());
m_stages.push_back(m_pass_bloom.get());
m_stages.push_back(m_pass_tonemap.get());

for (GraphicsPipelineStage* stage : m_stages) {
Expand Down Expand Up @@ -72,6 +75,7 @@ namespace wmoge {
assert(view_idx == 0);

m_pass_gbuffer->execute(view_idx);
m_pass_bloom->execute(view_idx);
m_pass_tonemap->execute(view_idx, Engine::instance()->window_manager()->primary_window());//tmp
}
}
Expand Down
2 changes: 1 addition & 1 deletion engine/render/deferred_pipeline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ namespace wmoge {

private:
std::unique_ptr<class PassGBuffer> m_pass_gbuffer;
std::unique_ptr<class PassBloom> m_pass_bloom;
std::unique_ptr<class PassToneMap> m_pass_tonemap;
// std::unique_ptr<class PassForward> m_pass_forward;
// std::unique_ptr<class PassDeferredLighting> m_pass_deferred_lighting;
// std::unique_ptr<class PassBloop> m_pass_bloom;

std::vector<GraphicsPipelineStage*> m_stages;
};
Expand Down
72 changes: 72 additions & 0 deletions engine/render/graphics_pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,58 @@

namespace wmoge {

Status yaml_read(const YamlConstNodeRef& node, BloomSettings& settings) {
WG_YAML_READ_AS_OPT(node, "enable", settings.enable);
WG_YAML_READ_AS_OPT(node, "intensity", settings.intensity);
WG_YAML_READ_AS_OPT(node, "threshold", settings.threshold);
WG_YAML_READ_AS_OPT(node, "knee", settings.knee);
WG_YAML_READ_AS_OPT(node, "radius", settings.radius);
WG_YAML_READ_AS_OPT(node, "uspample_weight", settings.uspample_weight);
WG_YAML_READ_AS_OPT(node, "dirt_mask_intensity", settings.dirt_mask_intensity);
WG_YAML_READ_AS_OPT(node, "dirt_mask", settings.dirt_mask);
return StatusCode::Ok;
}
Status yaml_write(YamlNodeRef node, const BloomSettings& settings) {
WG_YAML_MAP(node);
WG_YAML_WRITE_AS(node, "enable", settings.enable);
WG_YAML_WRITE_AS(node, "intensity", settings.intensity);
WG_YAML_WRITE_AS(node, "threshold", settings.threshold);
WG_YAML_WRITE_AS(node, "knee", settings.knee);
WG_YAML_WRITE_AS(node, "radius", settings.radius);
WG_YAML_WRITE_AS(node, "uspample_weight", settings.uspample_weight);
WG_YAML_WRITE_AS(node, "dirt_mask_intensity", settings.dirt_mask_intensity);
WG_YAML_WRITE_AS(node, "dirt_mask", settings.dirt_mask);
return StatusCode::Ok;
}

Status yaml_read(const YamlConstNodeRef& node, TonemapSettings& settings) {
WG_YAML_READ_AS_OPT(node, "exposure", settings.exposure);
WG_YAML_READ_AS_OPT(node, "gamma", settings.gamma);
WG_YAML_READ_AS_OPT(node, "white_point", settings.white_point);
WG_YAML_READ_AS_OPT(node, "mode", settings.mode);
return StatusCode::Ok;
}
Status yaml_write(YamlNodeRef node, const TonemapSettings& settings) {
WG_YAML_MAP(node);
WG_YAML_WRITE_AS(node, "exposure", settings.exposure);
WG_YAML_WRITE_AS(node, "gamma", settings.gamma);
WG_YAML_WRITE_AS(node, "white_point", settings.white_point);
WG_YAML_WRITE_AS(node, "mode", settings.mode);
return StatusCode::Ok;
}

Status yaml_read(const YamlConstNodeRef& node, GraphicsPipelineSettings& settings) {
WG_YAML_READ_AS_OPT(node, "bloom", settings.bloom);
WG_YAML_READ_AS_OPT(node, "tonemap", settings.tonemap);
return StatusCode::Ok;
}
Status yaml_write(YamlNodeRef node, const GraphicsPipelineSettings& settings) {
WG_YAML_MAP(node);
WG_YAML_WRITE_AS(node, "bloom", settings.bloom);
WG_YAML_WRITE_AS(node, "tonemap", settings.tonemap);
return StatusCode::Ok;
}

void GraphicsPipelineTextures::resize(Size2i new_target_resoulution) {
Engine* engine = Engine::instance();
GfxDriver* gfx_driver = engine->gfx_driver();
Expand All @@ -44,6 +96,22 @@ namespace wmoge {
gbuffer[0] = gfx_driver->make_texture_2d(size.x(), size.y(), 1, GfxFormat::RGBA16F, usages, GfxMemUsage::GpuLocal, GfxTexSwizz::None, SID("gbuffer[0]"));
gbuffer[1] = gfx_driver->make_texture_2d(size.x(), size.y(), 1, GfxFormat::RGBA16F, usages, GfxMemUsage::GpuLocal, GfxTexSwizz::None, SID("gbuffer[1]"));
gbuffer[2] = gfx_driver->make_texture_2d(size.x(), size.y(), 1, GfxFormat::RGBA16F, usages, GfxMemUsage::GpuLocal, GfxTexSwizz::None, SID("gbuffer[2]"));
bloom_downsample.clear();
bloom_upsample.clear();

const int mips = Image::max_mips_count(size.x(), size.y(), 1);
const int mip_bias = 3;
const int bloom_mips = Math::max(int(0), mips - mip_bias);

for (int i = 0; i < bloom_mips; i++) {
const Size2i mip_size = Image::mip_size(i, size.x(), size.y());
const StringId name = SID("bloom mip=" + StringUtils::from_int(i));

bloom_downsample.push_back(gfx_driver->make_texture_2d(mip_size.x(), mip_size.y(), 1, GfxFormat::RGBA16F, usages, GfxMemUsage::GpuLocal, GfxTexSwizz::None, name));
bloom_upsample.push_back(gfx_driver->make_texture_2d(mip_size.x(), mip_size.y(), 1, GfxFormat::RGBA16F, usages, GfxMemUsage::GpuLocal, GfxTexSwizz::None, name));
}

color_hdr = gbuffer[0];//tmp

target_viewport = Rect2i(0, 0, new_target_resoulution.x(), new_target_resoulution.y());
}
Expand Down Expand Up @@ -87,4 +155,8 @@ namespace wmoge {
m_textures.update_viewport(m_resolution);
}

void GraphicsPipeline::set_settings(const GraphicsPipelineSettings& settings) {
m_settings = settings;
}

}// namespace wmoge
76 changes: 69 additions & 7 deletions engine/render/graphics_pipeline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,75 @@
#include "gfx/gfx_ctx.hpp"
#include "gfx/gfx_driver.hpp"
#include "gfx/gfx_texture.hpp"
#include "io/yaml.hpp"
#include "math/mat.hpp"
#include "math/vec.hpp"
#include "render/render_camera.hpp"
#include "render/render_scene.hpp"
#include "render/shader_manager.hpp"
#include "render/texture_manager.hpp"
#include "resource/resource_ref.hpp"
#include "resource/texture.hpp"

#include <string>
#include <vector>

namespace wmoge {

/**
* @class BloomSettings
* @brief Bloom effect settings
*/
struct BloomSettings {
bool enable = true;
float intensity = 0.9f;
float threshold = 0.9f;
float knee = 0.5f;
float radius = 1.0f;
float uspample_weight = 0.85f;
float dirt_mask_intensity = 2.5f;
std::optional<ResourceRefHard<Texture2d>> dirt_mask;

friend Status yaml_read(const YamlConstNodeRef& node, BloomSettings& settings);
friend Status yaml_write(YamlNodeRef node, const BloomSettings& settings);
};

/**
* @class TonemapSettings
* @brief Final HDR image tonemapping settings for composition
*/
struct TonemapSettings {

/** @brief Mode to select algo */
enum class Mode {
Exponential = 0,
Reinhard = 1,
ReinhardExtended = 2,
Asec = 3,
Uncharted2 = 4
};

float exposure = 0.8f;
float gamma = 2.2f;
float white_point = 1.0f;
Mode mode = Mode::Exponential;

friend Status yaml_read(const YamlConstNodeRef& node, TonemapSettings& settings);
friend Status yaml_write(YamlNodeRef node, const TonemapSettings& settings);
};

/**
* @class GraphicsPipelineSettings
* @brief Graphics pipeline settings for rendering scene
*/
struct GraphicsPipelineSettings {
BloomSettings bloom;
TonemapSettings tonemap;

friend Status yaml_read(const YamlConstNodeRef& node, GraphicsPipelineSettings& settings);
friend Status yaml_write(YamlNodeRef node, const GraphicsPipelineSettings& settings);
};

/** @brief Types of supported stages */
enum class GraphicsPipelineStageType {
None = 0,
Expand All @@ -64,13 +121,15 @@ namespace wmoge {
* @brief Pipeline textures used during rendering
*/
struct GraphicsPipelineTextures {
Ref<GfxTexture> depth;//< Scene geometry depth buffer
Ref<GfxTexture> primitive_id;
Ref<GfxTexture> velocity;
Ref<GfxTexture> gbuffer[3];
Ref<GfxTexture> ssao;
Ref<GfxTexture> color_hdr;
Ref<GfxTexture> color_ldr;
Ref<GfxTexture> depth; //< [full] Scene geometry depth buffer
Ref<GfxTexture> primitive_id; //< [full] Rendered primitive id for gbuffer effects and picking
Ref<GfxTexture> velocity; //< [full] Velocity buffer
Ref<GfxTexture> gbuffer[3]; //< [full] GBuffer (layout see in shader)
Ref<GfxTexture> ssao; //< [half] Screen space ambient occlusion
Ref<GfxTexture> color_hdr; //< [full] Hdr color target for lit scene
Ref<GfxTexture> color_ldr; //< [full] Ldr color target after tone mapping
std::vector<Ref<GfxTexture>> bloom_downsample;//< [full] [half] ... Bloom downsample sample chain
std::vector<Ref<GfxTexture>> bloom_upsample; //< [full] [half] ... Bloom upsample sample chain

Rect2i viewport;
Rect2i target_viewport;
Expand Down Expand Up @@ -122,13 +181,15 @@ namespace wmoge {
virtual void set_views(ArrayView<struct RenderView> views);
virtual void set_target_resolution(Size2i resolution);
virtual void set_resolution(Size2i resolution);
virtual void set_settings(const GraphicsPipelineSettings& settings);

virtual void init() = 0;
virtual void exectute() = 0;

virtual std::vector<GraphicsPipelineStage*> get_stages() = 0;
virtual std::string get_name() = 0;

[[nodiscard]] const GraphicsPipelineSettings& get_settings() { return m_settings; }
[[nodiscard]] const GraphicsPipelineTextures& get_textures() { return m_textures; }
[[nodiscard]] ArrayView<struct RenderView> get_views() const { return m_views; }
[[nodiscard]] RenderCameras* get_cameras() const { return m_cameras; }
Expand All @@ -137,6 +198,7 @@ namespace wmoge {
[[nodiscard]] const Size2i& get_resolution() const { return m_resolution; }

protected:
GraphicsPipelineSettings m_settings;
GraphicsPipelineTextures m_textures;
ArrayView<struct RenderView> m_views;
RenderCameras* m_cameras;
Expand Down
Loading

0 comments on commit 3722735

Please sign in to comment.