[Bf-blender-cvs] [885e7abed13] master: Realtime Compositor: Implement bilateral blur node

Omar Emara noreply at git.blender.org
Thu Aug 18 17:16:20 CEST 2022


Commit: 885e7abed13b204a701466a203f6d96773de902a
Author: Omar Emara
Date:   Thu Aug 18 17:14:29 2022 +0200
Branches: master
https://developer.blender.org/rB885e7abed13b204a701466a203f6d96773de902a

Realtime Compositor: Implement bilateral blur node

This patch implements the bilateral blur node for the realtime compositor.

Differential Revision: https://developer.blender.org/D15674

Reviewed By: Clement Foucault

===================================================================

M	source/blender/gpu/CMakeLists.txt
A	source/blender/gpu/shaders/compositor/compositor_bilateral_blur.glsl
A	source/blender/gpu/shaders/compositor/infos/compositor_bilateral_blur_info.hh
M	source/blender/nodes/composite/nodes/node_composite_bilateralblur.cc

===================================================================

diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 40ede29eab6..9469db1d842 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -315,6 +315,7 @@ set(GLSL_SRC
   shaders/common/gpu_shader_common_mix_rgb.glsl
 
   shaders/compositor/compositor_alpha_crop.glsl
+  shaders/compositor/compositor_bilateral_blur.glsl
   shaders/compositor/compositor_bokeh_image.glsl
   shaders/compositor/compositor_box_mask.glsl
   shaders/compositor/compositor_convert.glsl
@@ -566,6 +567,7 @@ set(SRC_SHADER_CREATE_INFOS
   shaders/infos/gpu_srgb_to_framebuffer_space_info.hh
 
   shaders/compositor/infos/compositor_alpha_crop_info.hh
+  shaders/compositor/infos/compositor_bilateral_blur_info.hh
   shaders/compositor/infos/compositor_bokeh_image_info.hh
   shaders/compositor/infos/compositor_box_mask_info.hh
   shaders/compositor/infos/compositor_convert_info.hh
diff --git a/source/blender/gpu/shaders/compositor/compositor_bilateral_blur.glsl b/source/blender/gpu/shaders/compositor/compositor_bilateral_blur.glsl
new file mode 100644
index 00000000000..c7c5ada7a9f
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/compositor_bilateral_blur.glsl
@@ -0,0 +1,31 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+  ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+  vec4 center_determinator = texture_load(determinator_tx, texel);
+
+  /* Go over the pixels in the blur window of the specified radius around the center pixel, and for
+   * pixels whose determinator is close enough to the determinator of the center pixel, accumulate
+   * their color as well as their weights. */
+  float accumulated_weight = 0.0;
+  vec4 accumulated_color = vec4(0.0);
+  for (int y = -radius; y <= radius; y++) {
+    for (int x = -radius; x <= radius; x++) {
+      vec4 determinator = texture_load(determinator_tx, texel + ivec2(x, y));
+      float difference = dot(abs(center_determinator - determinator).rgb, vec3(1.0));
+
+      if (difference < threshold) {
+        accumulated_weight += 1.0;
+        accumulated_color += texture_load(input_tx, texel + ivec2(x, y));
+      }
+    }
+  }
+
+  /* Write the accumulated color divided by the accumulated weight if any pixel in the window was
+   * accumulated, otherwise, write a fallback black color. */
+  vec4 fallback = vec4(vec3(0.0), 1.0);
+  vec4 color = (accumulated_weight != 0.0) ? (accumulated_color / accumulated_weight) : fallback;
+  imageStore(output_img, texel, color);
+}
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_bilateral_blur_info.hh b/source/blender/gpu/shaders/compositor/infos/compositor_bilateral_blur_info.hh
new file mode 100644
index 00000000000..301cd6acd9e
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/infos/compositor_bilateral_blur_info.hh
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(compositor_bilateral_blur)
+    .local_group_size(16, 16)
+    .push_constant(Type::INT, "radius")
+    .push_constant(Type::FLOAT, "threshold")
+    .sampler(0, ImageType::FLOAT_2D, "input_tx")
+    .sampler(1, ImageType::FLOAT_2D, "determinator_tx")
+    .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
+    .compute_source("compositor_bilateral_blur.glsl")
+    .do_static_compilation(true);
diff --git a/source/blender/nodes/composite/nodes/node_composite_bilateralblur.cc b/source/blender/nodes/composite/nodes/node_composite_bilateralblur.cc
index 66a321eb088..355ec42f221 100644
--- a/source/blender/nodes/composite/nodes/node_composite_bilateralblur.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_bilateralblur.cc
@@ -5,10 +5,15 @@
  * \ingroup cmpnodes
  */
 
+#include "BLI_math_base.hh"
+
 #include "UI_interface.h"
 #include "UI_resources.h"
 
+#include "GPU_shader.h"
+
 #include "COM_node_operation.hh"
+#include "COM_utilities.hh"
 
 #include "node_composite_util.hh"
 
@@ -52,7 +57,51 @@ class BilateralBlurOperation : public NodeOperation {
 
   void execute() override
   {
-    get_input("Image").pass_through(get_result("Image"));
+    const Result &input_image = get_input("Image");
+    /* Single value inputs can't be blurred and are returned as is. */
+    if (input_image.is_single_value()) {
+      get_input("Image").pass_through(get_result("Image"));
+      return;
+    }
+
+    GPUShader *shader = shader_manager().get("compositor_bilateral_blur");
+    GPU_shader_bind(shader);
+
+    GPU_shader_uniform_1i(shader, "radius", get_blur_radius());
+    GPU_shader_uniform_1f(shader, "threshold", get_threshold());
+
+    input_image.bind_as_texture(shader, "input_tx");
+
+    const Result &determinator_image = get_input("Determinator");
+    determinator_image.bind_as_texture(shader, "determinator_tx");
+
+    const Domain domain = compute_domain();
+    Result &output_image = get_result("Image");
+    output_image.allocate_texture(domain);
+    output_image.bind_as_image(shader, "output_img");
+
+    compute_dispatch_threads_at_least(shader, domain.size);
+
+    GPU_shader_unbind();
+    output_image.unbind_as_image();
+    input_image.unbind_as_texture();
+    determinator_image.unbind_as_texture();
+  }
+
+  int get_blur_radius()
+  {
+    return math::ceil(get_node_bilateral_blur_data().iter +
+                      get_node_bilateral_blur_data().sigma_space);
+  }
+
+  float get_threshold()
+  {
+    return get_node_bilateral_blur_data().sigma_color;
+  }
+
+  NodeBilateralBlurData &get_node_bilateral_blur_data()
+  {
+    return *static_cast<NodeBilateralBlurData *>(bnode().storage);
   }
 };



More information about the Bf-blender-cvs mailing list