]> git.lizzy.rs Git - minetest.git/blobdiff - src/client/render/secondstage.cpp
Clear exposure compensation state textures on creation (#13151)
[minetest.git] / src / client / render / secondstage.cpp
index 860b277bd8b09857d774efca8c7c6f7e803f4721..1575cfb1fff4c7eec2a54cab300e02efc50bd364 100644 (file)
@@ -115,50 +115,96 @@ 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_EXPOSURE_1 = 3;
+       static const u8 TEXTURE_EXPOSURE_2 = 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_EXPOSURE_1, core::dimension2du(1,1), "exposure_1", color_format, /*clear:*/ true);
+       buffer->setTexture(TEXTURE_EXPOSURE_2, core::dimension2du(1,1), "exposure_2", color_format, /*clear:*/ true);
        buffer->setTexture(TEXTURE_DEPTH, scale, "3d_depthmap", depth_format);
 
        // attach buffer to the previous step
        previousStep->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, std::vector<u8> { TEXTURE_COLOR }, TEXTURE_DEPTH));
 
+       // shared variables
+       u32 shader_id;
+
+       // Number of mipmap levels of the bloom downsampling texture
+       const u8 MIPMAP_LEVELS = 4;
+
+       const bool enable_bloom = g_settings->getBool("enable_bloom");
+       const bool enable_auto_exposure = g_settings->getBool("enable_auto_exposure");
+
        // 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;
+
+       u8 source = TEXTURE_COLOR;
+
+       // common downsampling step for bloom or autoexposure
+       if (enable_bloom || enable_auto_exposure) {
+
+               v2f downscale = scale * 0.5;
+               for (u8 i = 0; i < MIPMAP_LEVELS; i++) {
+                       buffer->setTexture(TEXTURE_BLOOM_DOWN + i, downscale, std::string("downsample") + std::to_string(i), color_format);
+                       if (enable_bloom)
+                               buffer->setTexture(TEXTURE_BLOOM_UP + i, downscale, std::string("upsample") + std::to_string(i), color_format);
+                       downscale *= 0.5;
+               }
+
+               if (enable_bloom) {
+                       buffer->setTexture(TEXTURE_BLOOM, scale, "bloom", color_format);
+
+                       // 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, TEXTURE_EXPOSURE_1 });
+                       extract_bloom->setRenderSource(buffer);
+                       extract_bloom->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, TEXTURE_BLOOM));
+                       source = TEXTURE_BLOOM;
                }
 
-               // 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));
+               // downsample
+               shader_id = client->getShaderSource()->getShader("bloom_downsample", TILE_MATERIAL_PLAIN, NDT_MESH);
+               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;
+               }
+       }
+
+       if (enable_bloom) {
+               // 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;
+               }
+       }
+
+       if (enable_auto_exposure) {
+               shader_id = client->getShaderSource()->getShader("update_exposure", TILE_MATERIAL_PLAIN, NDT_MESH);
+               auto update_exposure = pipeline->addStep<PostProcessingStep>(shader_id, std::vector<u8> { TEXTURE_EXPOSURE_1, u8(TEXTURE_BLOOM_DOWN + MIPMAP_LEVELS - 1) });
+               update_exposure->setBilinearFilter(1, true);
+               update_exposure->setRenderSource(buffer);
+               update_exposure->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, TEXTURE_EXPOSURE_2));
        }
 
        // 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, TEXTURE_EXPOSURE_2 });
        pipeline->addStep(effect);
        effect->setBilinearFilter(1, true); // apply filter to the bloom
        effect->setRenderSource(buffer);
+
+       if (enable_auto_exposure) {
+               pipeline->addStep<SwapTexturesStep>(buffer, TEXTURE_EXPOSURE_1, TEXTURE_EXPOSURE_2);
+       }
+
        return effect;
 }