[Bf-blender-cvs] [fa27a5d066a] master: Realtime Compositor: Implement Ghost Glare node

Omar Emara noreply at git.blender.org
Fri Dec 9 15:55:33 CET 2022


Commit: fa27a5d066a1d6b04e77bfa4088dca83644bceaf
Author: Omar Emara
Date:   Fri Dec 9 16:50:52 2022 +0200
Branches: master
https://developer.blender.org/rBfa27a5d066a1d6b04e77bfa4088dca83644bceaf

Realtime Compositor: Implement Ghost Glare node

This patch implements the Ghost Glare node. It is implemented using
direct convolution as opposed to a recursive one, which produces
slightly different results---more accurate ones, however, since the
ghosts are attenuated where it matters, the difference is barely
visible and is acceptable as far as I can tell.

A possible performance improvement is to implement all passes in a
single shader dispatch, where an array of all scales and color
modulators is computed recursively on the host then used in the shader
to add all ghosts, avoiding usage of global memory and unnecessary
copies. This optimization will be implemented separately.

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

Reviewed By: Clement Foucault

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

M	source/blender/compositor/realtime_compositor/CMakeLists.txt
M	source/blender/compositor/realtime_compositor/COM_result.hh
A	source/blender/compositor/realtime_compositor/algorithms/COM_algorithm_symmetric_separable_blur.hh
A	source/blender/compositor/realtime_compositor/algorithms/intern/symmetric_separable_blur.cc
M	source/blender/compositor/realtime_compositor/intern/result.cc
A	source/blender/compositor/realtime_compositor/shaders/compositor_glare_ghost_accumulate.glsl
A	source/blender/compositor/realtime_compositor/shaders/compositor_glare_ghost_base.glsl
A	source/blender/compositor/realtime_compositor/shaders/compositor_glare_highlights.glsl
A	source/blender/compositor/realtime_compositor/shaders/compositor_glare_mix.glsl
A	source/blender/compositor/realtime_compositor/shaders/infos/compositor_glare_info.hh
M	source/blender/makesdna/DNA_node_types.h
M	source/blender/nodes/composite/nodes/node_composite_blur.cc
M	source/blender/nodes/composite/nodes/node_composite_glare.cc

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

diff --git a/source/blender/compositor/realtime_compositor/CMakeLists.txt b/source/blender/compositor/realtime_compositor/CMakeLists.txt
index b4352248b5b..7d7448a448f 100644
--- a/source/blender/compositor/realtime_compositor/CMakeLists.txt
+++ b/source/blender/compositor/realtime_compositor/CMakeLists.txt
@@ -60,8 +60,10 @@ set(SRC
   COM_utilities.hh
 
   algorithms/intern/algorithm_parallel_reduction.cc
+  algorithms/intern/symmetric_separable_blur.cc
 
   algorithms/COM_algorithm_parallel_reduction.hh
+  algorithms/COM_algorithm_symmetric_separable_blur.hh
 
   cached_resources/intern/morphological_distance_feather_weights.cc
   cached_resources/intern/symmetric_blur_weights.cc
@@ -96,6 +98,10 @@ set(GLSL_SRC
   shaders/compositor_ellipse_mask.glsl
   shaders/compositor_filter.glsl
   shaders/compositor_flip.glsl
+  shaders/compositor_glare_ghost_accumulate.glsl
+  shaders/compositor_glare_ghost_base.glsl
+  shaders/compositor_glare_highlights.glsl
+  shaders/compositor_glare_mix.glsl
   shaders/compositor_image_crop.glsl
   shaders/compositor_morphological_distance.glsl
   shaders/compositor_morphological_distance_feather.glsl
@@ -181,6 +187,7 @@ set(SRC_SHADER_CREATE_INFOS
   shaders/infos/compositor_ellipse_mask_info.hh
   shaders/infos/compositor_filter_info.hh
   shaders/infos/compositor_flip_info.hh
+  shaders/infos/compositor_glare_info.hh
   shaders/infos/compositor_image_crop_info.hh
   shaders/infos/compositor_morphological_distance_feather_info.hh
   shaders/infos/compositor_morphological_distance_info.hh
diff --git a/source/blender/compositor/realtime_compositor/COM_result.hh b/source/blender/compositor/realtime_compositor/COM_result.hh
index f5ecc4c2112..3f8378bc4c2 100644
--- a/source/blender/compositor/realtime_compositor/COM_result.hh
+++ b/source/blender/compositor/realtime_compositor/COM_result.hh
@@ -105,6 +105,11 @@ class Result {
    * and release the result's texture. */
   Result(ResultType type, TexturePool &texture_pool);
 
+  /* Identical to the standard constructor but initializes the reference count to 1. This is useful
+   * to construct temporary results that are created and released by the developer manually, which
+   * are typically used in operations that need temporary intermediate results. */
+  static Result Temporary(ResultType type, TexturePool &texture_pool);
+
   /* Declare the result to be a texture result, allocate a texture of an appropriate type with
    * the size of the given domain from the result's texture pool, and set the domain of the result
    * to the given domain. */
@@ -125,8 +130,9 @@ class Result {
   void bind_as_texture(GPUShader *shader, const char *texture_name) const;
 
   /* Bind the texture of the result to the image unit with the given name in the currently bound
-   * given shader. */
-  void bind_as_image(GPUShader *shader, const char *image_name) const;
+   * given shader. If read is true, a memory barrier will be inserted for image reads to ensure any
+   * prior writes to the images are reflected before reading from it. */
+  void bind_as_image(GPUShader *shader, const char *image_name, bool read = false) const;
 
   /* Unbind the texture which was previously bound using bind_as_texture. */
   void unbind_as_texture() const;
diff --git a/source/blender/compositor/realtime_compositor/algorithms/COM_algorithm_symmetric_separable_blur.hh b/source/blender/compositor/realtime_compositor/algorithms/COM_algorithm_symmetric_separable_blur.hh
new file mode 100644
index 00000000000..317ce2ab522
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/algorithms/COM_algorithm_symmetric_separable_blur.hh
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#pragma once
+
+#include "BLI_math_vec_types.hh"
+
+#include "COM_context.hh"
+#include "COM_result.hh"
+
+namespace blender::realtime_compositor {
+
+/* Blur the input using a horizontal and a vertical separable blur passes given a certain radius
+ * and filter type using SymmetricSeparableBlurWeights. The output is written to the given output
+ * result, which will be allocated internally and is thus expected not to be previously allocated.
+ * If extend_bounds is true, the output will have an extra radius amount of pixels on the boundary
+ * of the image, where blurring can take place assuming a fully transparent out of bound values. If
+ * gamma_correct is true, the input will be gamma corrected before blurring and then uncorrected
+ * after blurring, using a gamma coefficient of 2. */
+void symmetric_separable_blur(Context &context,
+                              Result &input,
+                              Result &output,
+                              float2 radius,
+                              int filter_type,
+                              bool extend_bounds,
+                              bool gamma_correct);
+
+}  // namespace blender::realtime_compositor
diff --git a/source/blender/compositor/realtime_compositor/algorithms/intern/symmetric_separable_blur.cc b/source/blender/compositor/realtime_compositor/algorithms/intern/symmetric_separable_blur.cc
new file mode 100644
index 00000000000..e450abdc203
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/algorithms/intern/symmetric_separable_blur.cc
@@ -0,0 +1,132 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "BLI_math_base.hh"
+#include "BLI_math_vec_types.hh"
+#include "BLI_math_vector.hh"
+
+#include "GPU_shader.h"
+#include "GPU_texture.h"
+
+#include "COM_context.hh"
+#include "COM_utilities.hh"
+
+#include "COM_algorithm_symmetric_separable_blur.hh"
+
+#include "COM_symmetric_separable_blur_weights.hh"
+
+namespace blender::realtime_compositor {
+
+static Result horizontal_pass(Context &context,
+                              Result &input,
+                              float radius,
+                              int filter_type,
+                              bool extend_bounds,
+                              bool gamma_correct)
+{
+  GPUShader *shader = context.shader_manager().get("compositor_symmetric_separable_blur");
+  GPU_shader_bind(shader);
+
+  GPU_shader_uniform_1b(shader, "extend_bounds", extend_bounds);
+  GPU_shader_uniform_1b(shader, "gamma_correct_input", gamma_correct);
+  GPU_shader_uniform_1b(shader, "gamma_uncorrect_output", false);
+
+  input.bind_as_texture(shader, "input_tx");
+
+  const SymmetricSeparableBlurWeights &weights =
+      context.cache_manager().get_symmetric_separable_blur_weights(filter_type, radius);
+  weights.bind_as_texture(shader, "weights_tx");
+
+  Domain domain = input.domain();
+  if (extend_bounds) {
+    domain.size.x += int(math::ceil(radius)) * 2;
+  }
+
+  /* We allocate an output image of a transposed size, that is, with a height equivalent to the
+   * width of the input and vice versa. This is done as a performance optimization. The shader
+   * will blur the image horizontally and write it to the intermediate output transposed. Then
+   * the vertical pass will execute the same horizontal blur shader, but since its input is
+   * transposed, it will effectively do a vertical blur and write to the output transposed,
+   * effectively undoing the transposition in the horizontal pass. This is done to improve
+   * spatial cache locality in the shader and to avoid having two separate shaders for each blur
+   * pass. */
+  const int2 transposed_domain = int2(domain.size.y, domain.size.x);
+
+  Result output = Result::Temporary(ResultType::Color, context.texture_pool());
+  output.allocate_texture(transposed_domain);
+  output.bind_as_image(shader, "output_img");
+
+  compute_dispatch_threads_at_least(shader, domain.size);
+
+  GPU_shader_unbind();
+  input.unbind_as_texture();
+  weights.unbind_as_texture();
+  output.unbind_as_image();
+
+  return output;
+}
+
+static void vertical_pass(Context &context,
+                          Result &original_input,
+                          Result &horizontal_pass_result,
+                          Result &output,
+                          float2 radius,
+                          int filter_type,
+                          bool extend_bounds,
+                          bool gamma_correct)
+{
+  GPUShader *shader = context.shader_manager().get("compositor_symmetric_separable_blur");
+  GPU_shader_bind(shader);
+
+  GPU_shader_uniform_1b(shader, "extend_bounds", extend_bounds);
+  GPU_shader_uniform_1b(shader, "gamma_correct_input", false);
+  GPU_shader_uniform_1b(shader, "gamma_uncorrect_output", gamma_correct);
+
+  horizontal_pass_result.bind_as_texture(shader, "input_tx");
+
+  const SymmetricSeparableBlurWeights &weights =
+      context.cache_manager().get_symmetric_separable_blur_weights(filter_type, radius.y);
+  weights.bind_as_texture(shader, "weights_tx");
+
+  Domain domain = original_input.domain();
+  if (extend_bounds) {
+    /* Add a radius amount of pixels in both sides of the image, hence the multiply by 2. */
+    domain.size += int2(math::ceil(radius)) * 2;
+  }
+
+  output.allocate_texture(domain);
+  output.bind_as_image(shader, "output_img");
+
+  /* Notice that the domain is transposed, see the note on the horizontal pass method for more
+   * information on the reasoning behind this. */
+  compute_dispatch_threads_at_least(shader, int2(domain.size.y, domain.size.x));
+
+  GPU_shader_unbind();
+  horizontal_pass_result.unbind_as_texture();
+  output.unbind_as_image();
+  weights.unbind_as_texture();
+}
+
+void symmetric_separable_blur(Context &context,
+                              Result &input,
+                              Result &output,
+                              float2 radius,
+                              int filter_type,
+                              bool extend_bounds,
+                              bool gamma_correct)
+{
+  Result horizontal_pass_result = horizontal_pass(
+      context, input, radius.x, filter_type, extend_bounds, gamma_correct);
+
+  vertical_pass(context,
+                input,
+                horizontal_pass_result,
+                output,
+                radius,
+                filter_type,
+                extend_bounds,
+                gamma_correct);
+
+  horizontal_pass_result.release();
+}
+
+}  // namespace blender::realtime_composito

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list