diff options
| author | x2048 <codeforsmile@gmail.com> | 2022-11-02 09:09:48 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-11-02 09:09:48 +0100 |
| commit | 9b24041394ecf8210514845372d965f8d65302c9 (patch) | |
| tree | bdd8f6beea3ae775e3d2dbafa452257bd8f01ff9 /src/client/render | |
| parent | fb3085a2c593e0671e3322fe0e7d0914a052acef (diff) | |
| download | minetest-9b24041394ecf8210514845372d965f8d65302c9.tar.xz | |
Improve bloom effect (#12916)
* Remove the built-in exposure factor of 2.5
* Add physics-based bloom (https://learnopengl.com/Guest-Articles/2022/Phys.-Based-Bloom)
* Add luminance scaling for bloom layer to simulate HDR
* Add setting to control bloom strength
Diffstat (limited to 'src/client/render')
| -rw-r--r-- | src/client/render/pipeline.h | 5 | ||||
| -rw-r--r-- | src/client/render/secondstage.cpp | 61 |
2 files changed, 42 insertions, 24 deletions
diff --git a/src/client/render/pipeline.h b/src/client/render/pipeline.h index 771c6f1d5..354624102 100644 --- a/src/client/render/pipeline.h +++ b/src/client/render/pipeline.h @@ -390,9 +390,10 @@ public: * @return RenderStep* Pointer to the created step for further configuration. */ template<typename T, typename... Args> - RenderStep *addStep(Args&&... args) { + T *addStep(Args&&... args) { T* result = own(std::make_unique<T>(std::forward<Args>(args)...)); - return addStep(result); + addStep(result); + return result; } RenderSource *getInput(); diff --git a/src/client/render/secondstage.cpp b/src/client/render/secondstage.cpp index 860b277bd..ebc7e7411 100644 --- a/src/client/render/secondstage.cpp +++ b/src/client/render/secondstage.cpp @@ -115,8 +115,8 @@ RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep static const u8 TEXTURE_COLOR = 0; static const u8 TEXTURE_DEPTH = 1; static const u8 TEXTURE_BLOOM = 2; - static const u8 TEXTURE_BLUR = 3; - static const u8 TEXTURE_BLUR_SECONDARY = 4; + static const u8 TEXTURE_BLOOM_DOWN = 10; + static const u8 TEXTURE_BLOOM_UP = 20; buffer->setTexture(TEXTURE_COLOR, scale, "3d_render", color_format); buffer->setTexture(TEXTURE_DEPTH, scale, "3d_depthmap", depth_format); @@ -124,39 +124,56 @@ RenderStep *addPostProcessing(RenderPipeline *pipeline, RenderStep *previousStep // attach buffer to the previous step previousStep->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, std::vector<u8> { TEXTURE_COLOR }, TEXTURE_DEPTH)); + // shared variables + u32 shader_id; + // post-processing stage // set up bloom if (g_settings->getBool("enable_bloom")) { - buffer->setTexture(TEXTURE_BLUR, scale * 0.5, "blur", color_format); - buffer->setTexture(TEXTURE_BLOOM, scale * 0.5, "bloom", color_format); - u8 bloom_input_texture = TEXTURE_BLOOM; - - if (g_settings->getBool("enable_bloom_dedicated_texture")) { - buffer->setTexture(TEXTURE_BLUR_SECONDARY, scale * 0.5, "blur2", color_format); - bloom_input_texture = TEXTURE_BLUR_SECONDARY; + + buffer->setTexture(TEXTURE_BLOOM, scale, "bloom", color_format); + + const u8 MIPMAP_LEVELS = 4; + v2f downscale = scale * 0.5; + for (u8 i = 0; i < MIPMAP_LEVELS; i++) { + buffer->setTexture(TEXTURE_BLOOM_DOWN + i, downscale, std::string("bloom_down") + std::to_string(i), color_format); + buffer->setTexture(TEXTURE_BLOOM_UP + i, downscale, std::string("bloom_up") + std::to_string(i), color_format); + downscale *= 0.5; } // get bright spots u32 shader_id = client->getShaderSource()->getShader("extract_bloom", TILE_MATERIAL_PLAIN, NDT_MESH); RenderStep *extract_bloom = pipeline->addStep<PostProcessingStep>(shader_id, std::vector<u8> { TEXTURE_COLOR }); extract_bloom->setRenderSource(buffer); - extract_bloom->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, bloom_input_texture)); - // horizontal blur - shader_id = client->getShaderSource()->getShader("blur_h", TILE_MATERIAL_PLAIN, NDT_MESH); - RenderStep *blur_h = pipeline->addStep<PostProcessingStep>(shader_id, std::vector<u8> { bloom_input_texture }); - blur_h->setRenderSource(buffer); - blur_h->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, TEXTURE_BLUR)); - // vertical blur - shader_id = client->getShaderSource()->getShader("blur_v", TILE_MATERIAL_PLAIN, NDT_MESH); - RenderStep *blur_v = pipeline->addStep<PostProcessingStep>(shader_id, std::vector<u8> { TEXTURE_BLUR }); - blur_v->setRenderSource(buffer); - blur_v->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, TEXTURE_BLOOM)); + extract_bloom->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, TEXTURE_BLOOM)); + + // downsample + shader_id = client->getShaderSource()->getShader("bloom_downsample", TILE_MATERIAL_PLAIN, NDT_MESH); + u8 source = TEXTURE_BLOOM; + for (u8 i = 0; i < MIPMAP_LEVELS; i++) { + auto step = pipeline->addStep<PostProcessingStep>(shader_id, std::vector<u8> { source }); + step->setRenderSource(buffer); + step->setBilinearFilter(0, true); + step->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, TEXTURE_BLOOM_DOWN + i)); + source = TEXTURE_BLOOM_DOWN + i; + } + + // upsample + shader_id = client->getShaderSource()->getShader("bloom_upsample", TILE_MATERIAL_PLAIN, NDT_MESH); + for (u8 i = MIPMAP_LEVELS - 1; i > 0; i--) { + auto step = pipeline->addStep<PostProcessingStep>(shader_id, std::vector<u8> { u8(TEXTURE_BLOOM_DOWN + i - 1), source }); + step->setRenderSource(buffer); + step->setBilinearFilter(0, true); + step->setBilinearFilter(1, true); + step->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, u8(TEXTURE_BLOOM_UP + i - 1))); + source = TEXTURE_BLOOM_UP + i - 1; + } } // final post-processing - u32 shader_id = client->getShaderSource()->getShader("second_stage", TILE_MATERIAL_PLAIN, NDT_MESH); - PostProcessingStep *effect = pipeline->createOwned<PostProcessingStep>(shader_id, std::vector<u8> { TEXTURE_COLOR, TEXTURE_BLOOM }); + shader_id = client->getShaderSource()->getShader("second_stage", TILE_MATERIAL_PLAIN, NDT_MESH); + PostProcessingStep *effect = pipeline->createOwned<PostProcessingStep>(shader_id, std::vector<u8> { TEXTURE_COLOR, TEXTURE_BLOOM_UP }); pipeline->addStep(effect); effect->setBilinearFilter(1, true); // apply filter to the bloom effect->setRenderSource(buffer); |
