[Bf-blender-cvs] [5ee116d4489] master: Realtime Compositor: Implement Simple Star Glare node

Omar Emara noreply at git.blender.org
Fri Dec 9 16:05:34 CET 2022


Commit: 5ee116d4489ae9d6cbef4acec75f5bf12a5adcd7
Author: Omar Emara
Date:   Fri Dec 9 17:04:34 2022 +0200
Branches: master
https://developer.blender.org/rB5ee116d4489ae9d6cbef4acec75f5bf12a5adcd7

Realtime Compositor: Implement Simple Star Glare node

This patch implements the Simple Star Glare node. This is only an approximation
of the existing implementation in the CPU compositor, an approximation that
removes the row-column dependency in the original algorithm, yielding an order
of magnitude faster computations. The difference due to the approximation is
readily visible in artificial test cases, but is less visible in actual use
cases, so it was agreed that this approximation is worthwhile.

For the future, we can look into approximating this further using a closed form
IIR recursive filter with parallel interconnection and block-based parallelism.
Which is expected to yield another order of magnitude faster computations.

The different passes can potentially be combined into a single shader with some
preprocessor tricks, but doing that complicated that code in a way that makes
it difficult to experiment with future optimizations, so I decided to leave it
as is for now.

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

Reviewed By: Clement Foucault

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

M	source/blender/compositor/realtime_compositor/CMakeLists.txt
A	source/blender/compositor/realtime_compositor/shaders/compositor_glare_simple_star_anti_diagonal_pass.glsl
A	source/blender/compositor/realtime_compositor/shaders/compositor_glare_simple_star_diagonal_pass.glsl
A	source/blender/compositor/realtime_compositor/shaders/compositor_glare_simple_star_horizontal_pass.glsl
A	source/blender/compositor/realtime_compositor/shaders/compositor_glare_simple_star_vertical_pass.glsl
M	source/blender/compositor/realtime_compositor/shaders/infos/compositor_glare_info.hh
A	source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_image_diagonals.glsl
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 7d7448a448f..0881982c6d3 100644
--- a/source/blender/compositor/realtime_compositor/CMakeLists.txt
+++ b/source/blender/compositor/realtime_compositor/CMakeLists.txt
@@ -102,6 +102,10 @@ set(GLSL_SRC
   shaders/compositor_glare_ghost_base.glsl
   shaders/compositor_glare_highlights.glsl
   shaders/compositor_glare_mix.glsl
+  shaders/compositor_glare_simple_star_anti_diagonal_pass.glsl
+  shaders/compositor_glare_simple_star_diagonal_pass.glsl
+  shaders/compositor_glare_simple_star_horizontal_pass.glsl
+  shaders/compositor_glare_simple_star_vertical_pass.glsl
   shaders/compositor_image_crop.glsl
   shaders/compositor_morphological_distance.glsl
   shaders/compositor_morphological_distance_feather.glsl
@@ -135,6 +139,7 @@ set(GLSL_SRC
   shaders/library/gpu_shader_compositor_gamma.glsl
   shaders/library/gpu_shader_compositor_hue_correct.glsl
   shaders/library/gpu_shader_compositor_hue_saturation_value.glsl
+  shaders/library/gpu_shader_compositor_image_diagonals.glsl
   shaders/library/gpu_shader_compositor_invert.glsl
   shaders/library/gpu_shader_compositor_luminance_matte.glsl
   shaders/library/gpu_shader_compositor_main.glsl
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_glare_simple_star_anti_diagonal_pass.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_glare_simple_star_anti_diagonal_pass.glsl
new file mode 100644
index 00000000000..7cfec6c4d95
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_glare_simple_star_anti_diagonal_pass.glsl
@@ -0,0 +1,55 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_image_diagonals.glsl)
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+  ivec2 size = imageSize(anti_diagonal_img);
+  int index = int(gl_GlobalInvocationID.x);
+  int anti_diagonal_length = compute_anti_diagonal_length(size, index);
+  ivec2 start = compute_anti_diagonal_start(size, index);
+  ivec2 direction = get_anti_diagonal_direction();
+  ivec2 end = start + (anti_diagonal_length - 1) * direction;
+
+  /* For each iteration, apply a causal filter followed by a non causal filters along the anti
+   * diagonal mapped to the current thread invocation. */
+  for (int i = 0; i < iterations; i++) {
+    /* Causal Pass:
+     * Sequentially apply a causal filter running from the start of the anti diagonal to its end by
+     * mixing the value of the pixel in the anti diagonal with the average value of the previous
+     * output and next input in the same anti diagonal. */
+    for (int j = 0; j < anti_diagonal_length; j++) {
+      ivec2 texel = start + j * direction;
+      vec4 previous_output = imageLoad(anti_diagonal_img, texel - i * direction);
+      vec4 current_input = imageLoad(anti_diagonal_img, texel);
+      vec4 next_input = imageLoad(anti_diagonal_img, texel + i * direction);
+
+      vec4 neighbour_average = (previous_output + next_input) / 2.0;
+      vec4 causal_output = mix(current_input, neighbour_average, fade_factor);
+      imageStore(anti_diagonal_img, texel, causal_output);
+    }
+
+    /* Non Causal Pass:
+     * Sequentially apply a non causal filter running from the end of the diagonal to its start by
+     * mixing the value of the pixel in the diagonal with the average value of the previous output
+     * and next input in the same diagonal. */
+    for (int j = 0; j < anti_diagonal_length; j++) {
+      ivec2 texel = end - j * direction;
+      vec4 previous_output = imageLoad(anti_diagonal_img, texel + i * direction);
+      vec4 current_input = imageLoad(anti_diagonal_img, texel);
+      vec4 next_input = imageLoad(anti_diagonal_img, texel - i * direction);
+
+      vec4 neighbour_average = (previous_output + next_input) / 2.0;
+      vec4 non_causal_output = mix(current_input, neighbour_average, fade_factor);
+      imageStore(anti_diagonal_img, texel, non_causal_output);
+    }
+  }
+
+  /* For each pixel in the anti diagonal mapped to the current invocation thread, add the result of
+   * the diagonal pass to the vertical pass. */
+  for (int j = 0; j < anti_diagonal_length; j++) {
+    ivec2 texel = start + j * direction;
+    vec4 horizontal = texture_load(diagonal_tx, texel);
+    vec4 vertical = imageLoad(anti_diagonal_img, texel);
+    imageStore(anti_diagonal_img, texel, horizontal + vertical);
+  }
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_glare_simple_star_diagonal_pass.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_glare_simple_star_diagonal_pass.glsl
new file mode 100644
index 00000000000..c8a703ae67c
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_glare_simple_star_diagonal_pass.glsl
@@ -0,0 +1,45 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_image_diagonals.glsl)
+
+void main()
+{
+  ivec2 size = imageSize(diagonal_img);
+  int index = int(gl_GlobalInvocationID.x);
+  int diagonal_length = compute_diagonal_length(size, index);
+  ivec2 start = compute_diagonal_start(size, index);
+  ivec2 direction = get_diagonal_direction();
+  ivec2 end = start + (diagonal_length - 1) * direction;
+
+  /* For each iteration, apply a causal filter followed by a non causal filters along the diagonal
+   * mapped to the current thread invocation. */
+  for (int i = 0; i < iterations; i++) {
+    /* Causal Pass:
+     * Sequentially apply a causal filter running from the start of the diagonal to its end by
+     * mixing the value of the pixel in the diagonal with the average value of the previous output
+     * and next input in the same diagonal. */
+    for (int j = 0; j < diagonal_length; j++) {
+      ivec2 texel = start + j * direction;
+      vec4 previous_output = imageLoad(diagonal_img, texel - i * direction);
+      vec4 current_input = imageLoad(diagonal_img, texel);
+      vec4 next_input = imageLoad(diagonal_img, texel + i * direction);
+
+      vec4 neighbour_average = (previous_output + next_input) / 2.0;
+      vec4 causal_output = mix(current_input, neighbour_average, fade_factor);
+      imageStore(diagonal_img, texel, causal_output);
+    }
+
+    /* Non Causal Pass:
+     * Sequentially apply a non causal filter running from the end of the diagonal to its start by
+     * mixing the value of the pixel in the diagonal with the average value of the previous output
+     * and next input in the same diagonal. */
+    for (int j = 0; j < diagonal_length; j++) {
+      ivec2 texel = end - j * direction;
+      vec4 previous_output = imageLoad(diagonal_img, texel + i * direction);
+      vec4 current_input = imageLoad(diagonal_img, texel);
+      vec4 next_input = imageLoad(diagonal_img, texel - i * direction);
+
+      vec4 neighbour_average = (previous_output + next_input) / 2.0;
+      vec4 non_causal_output = mix(current_input, neighbour_average, fade_factor);
+      imageStore(diagonal_img, texel, non_causal_output);
+    }
+  }
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_glare_simple_star_horizontal_pass.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_glare_simple_star_horizontal_pass.glsl
new file mode 100644
index 00000000000..94d935a4c1d
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_glare_simple_star_horizontal_pass.glsl
@@ -0,0 +1,38 @@
+void main()
+{
+  int width = imageSize(horizontal_img).x;
+
+  /* For each iteration, apply a causal filter followed by a non causal filters along the row
+   * mapped to the current thread invocation. */
+  for (int i = 0; i < iterations; i++) {
+    /* Causal Pass:
+     * Sequentially apply a causal filter running from left to right by mixing the value of the
+     * pixel in the row with the average value of the previous output and next input in the same
+     * row. */
+    for (int x = 0; x < width; x++) {
+      ivec2 texel = ivec2(x, gl_GlobalInvocationID.x);
+      vec4 previous_output = imageLoad(horizontal_img, texel - ivec2(i, 0));
+      vec4 current_input = imageLoad(horizontal_img, texel);
+      vec4 next_input = imageLoad(horizontal_img, texel + ivec2(i, 0));
+
+      vec4 neighbour_average = (previous_output + next_input) / 2.0;
+      vec4 causal_output = mix(current_input, neighbour_average, fade_factor);
+      imageStore(horizontal_img, texel, causal_output);
+    }
+
+    /* Non Causal Pass:
+     * Sequentially apply a non causal filter running from right to left by mixing the value of the
+     * pixel in the row with the average value of the previous output and next input in the same
+     * row. */
+    for (int x = width - 1; x >= 0; x--) {
+      ivec2 texel = ivec2(x, gl_GlobalInvocationID.x);
+      vec4 previous_output = imageLoad(horizontal_img, texel + ivec2(i, 0));
+      vec4 current_input = imageLoad(horizontal_img, texel);
+      vec4 next_input = imageLoad(horizontal_img, texel - ivec2(i, 0));
+
+      vec4 neighbour_average = (previous_output + next_input) / 2.0;
+      vec4 non_causal_output = mix(current_input, neighbour_average, fade_factor);
+      imageStore(horizontal_img, texel, non_causal_output);
+    }
+  }
+}
diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_glare_simple_star_vertical_pass.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_glare_simple_star_vertical_pass.glsl
new file mode 100644
index 00000000000..abc92883c17
--- /dev/null
+++ b/source/blender/compositor/realtime_compositor/shaders/compositor_glare_simple_star_vertical_pass.glsl
@@ -0,0 +1,49 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+  int height = imageSize(vertical_img).y;
+
+  /* For each iteration, apply a causal filter followed by a non causal filters along the column
+   * mapped to the current thread invocation. */
+  for (int i = 0; i < iterations; i++) {
+    /* Causal Pass:
+     * Sequentially apply a causal filter running from bottom to top by mixing the value of the
+     * pixel in the column with the average value of the previous output and next input 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list