aboutsummaryrefslogtreecommitdiff
path: root/src/client/render
diff options
context:
space:
mode:
authorx2048 <codeforsmile@gmail.com>2022-11-02 09:09:48 +0100
committerGitHub <noreply@github.com>2022-11-02 09:09:48 +0100
commit9b24041394ecf8210514845372d965f8d65302c9 (patch)
treebdd8f6beea3ae775e3d2dbafa452257bd8f01ff9 /src/client/render
parentfb3085a2c593e0671e3322fe0e7d0914a052acef (diff)
downloadminetest-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.h5
-rw-r--r--src/client/render/secondstage.cpp61
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);