[Bf-blender-cvs] [40c45985a92] master: Realtime Compositor: Add basic distort nodes

Omar Emara noreply at git.blender.org
Wed Aug 10 10:31:02 CEST 2022


Commit: 40c45985a924e2e2310d5c51cf399150d557792c
Author: Omar Emara
Date:   Wed Aug 10 10:30:27 2022 +0200
Branches: master
https://developer.blender.org/rB40c45985a924e2e2310d5c51cf399150d557792c

Realtime Compositor: Add basic distort nodes

This patch implements the following nodes for the realtime compositor:

- Crop node.
- Flip node.
- Lens distort node.
- Rotate node.
- Transform node.
- Translate node.

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

Reviewed By: Clement Foucault

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

M	source/blender/gpu/CMakeLists.txt
A	source/blender/gpu/shaders/compositor/compositor_alpha_crop.glsl
A	source/blender/gpu/shaders/compositor/compositor_flip.glsl
A	source/blender/gpu/shaders/compositor/compositor_image_crop.glsl
A	source/blender/gpu/shaders/compositor/compositor_projector_lens_distortion.glsl
A	source/blender/gpu/shaders/compositor/compositor_screen_lens_distortion.glsl
A	source/blender/gpu/shaders/compositor/infos/compositor_alpha_crop_info.hh
A	source/blender/gpu/shaders/compositor/infos/compositor_flip_info.hh
A	source/blender/gpu/shaders/compositor/infos/compositor_image_crop_info.hh
A	source/blender/gpu/shaders/compositor/infos/compositor_projector_lens_distortion_info.hh
A	source/blender/gpu/shaders/compositor/infos/compositor_screen_lens_distortion_info.hh
M	source/blender/makesdna/DNA_node_types.h
M	source/blender/nodes/composite/nodes/node_composite_crop.cc
M	source/blender/nodes/composite/nodes/node_composite_flip.cc
M	source/blender/nodes/composite/nodes/node_composite_lensdist.cc
M	source/blender/nodes/composite/nodes/node_composite_rotate.cc
M	source/blender/nodes/composite/nodes/node_composite_transform.cc
M	source/blender/nodes/composite/nodes/node_composite_translate.cc

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

diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 0742ca6c9a8..ff12ae5054a 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -323,10 +323,15 @@ set(GLSL_SRC
   shaders/common/gpu_shader_common_math_utils.glsl
   shaders/common/gpu_shader_common_mix_rgb.glsl
 
+  shaders/compositor/compositor_alpha_crop.glsl
   shaders/compositor/compositor_box_mask.glsl
   shaders/compositor/compositor_convert.glsl
   shaders/compositor/compositor_ellipse_mask.glsl
+  shaders/compositor/compositor_flip.glsl
+  shaders/compositor/compositor_image_crop.glsl
+  shaders/compositor/compositor_projector_lens_distortion.glsl
   shaders/compositor/compositor_realize_on_domain.glsl
+  shaders/compositor/compositor_screen_lens_distortion.glsl
   shaders/compositor/compositor_set_alpha.glsl
   shaders/compositor/compositor_split_viewer.glsl
 
@@ -562,10 +567,15 @@ set(SRC_SHADER_CREATE_INFOS
   shaders/infos/gpu_shader_text_info.hh
   shaders/infos/gpu_srgb_to_framebuffer_space_info.hh
 
+  shaders/compositor/infos/compositor_alpha_crop_info.hh
   shaders/compositor/infos/compositor_box_mask_info.hh
   shaders/compositor/infos/compositor_convert_info.hh
   shaders/compositor/infos/compositor_ellipse_mask_info.hh
+  shaders/compositor/infos/compositor_flip_info.hh
+  shaders/compositor/infos/compositor_image_crop_info.hh
+  shaders/compositor/infos/compositor_projector_lens_distortion_info.hh
   shaders/compositor/infos/compositor_realize_on_domain_info.hh
+  shaders/compositor/infos/compositor_screen_lens_distortion_info.hh
   shaders/compositor/infos/compositor_set_alpha_info.hh
   shaders/compositor/infos/compositor_split_viewer_info.hh
 )
diff --git a/source/blender/gpu/shaders/compositor/compositor_alpha_crop.glsl b/source/blender/gpu/shaders/compositor/compositor_alpha_crop.glsl
new file mode 100644
index 00000000000..d55c8efd4c6
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/compositor_alpha_crop.glsl
@@ -0,0 +1,11 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+  ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+  /* The lower bound is inclusive and upper bound is exclusive. */
+  bool is_inside = all(greaterThanEqual(texel, lower_bound)) && all(lessThan(texel, upper_bound));
+  /* Write the pixel color if it is inside the cropping region, otherwise, write zero. */
+  vec4 color = is_inside ? texture_load(input_tx, texel) : vec4(0.0);
+  imageStore(output_img, texel, color);
+}
diff --git a/source/blender/gpu/shaders/compositor/compositor_flip.glsl b/source/blender/gpu/shaders/compositor/compositor_flip.glsl
new file mode 100644
index 00000000000..919c454ee63
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/compositor_flip.glsl
@@ -0,0 +1,15 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+  ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+  ivec2 size = texture_size(input_tx);
+  ivec2 flipped_texel = texel;
+  if (flip_x) {
+    flipped_texel.x = size.x - texel.x - 1;
+  }
+  if (flip_y) {
+    flipped_texel.y = size.y - texel.y - 1;
+  }
+  imageStore(output_img, texel, texture_load(input_tx, flipped_texel));
+}
diff --git a/source/blender/gpu/shaders/compositor/compositor_image_crop.glsl b/source/blender/gpu/shaders/compositor/compositor_image_crop.glsl
new file mode 100644
index 00000000000..f20e033dee4
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/compositor_image_crop.glsl
@@ -0,0 +1,7 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+  ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+  imageStore(output_img, texel, texture_load(input_tx, texel + lower_bound));
+}
diff --git a/source/blender/gpu/shaders/compositor/compositor_projector_lens_distortion.glsl b/source/blender/gpu/shaders/compositor/compositor_projector_lens_distortion.glsl
new file mode 100644
index 00000000000..cf961b20b34
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/compositor_projector_lens_distortion.glsl
@@ -0,0 +1,16 @@
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+void main()
+{
+  ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
+
+  /* Get the normalized coordinates of the pixel centers.  */
+  vec2 normalized_texel = (vec2(texel) + vec2(0.5)) / vec2(texture_size(input_tx));
+
+  /* Sample the red and blue channels shifted by the dispersion amount. */
+  const float red = texture(input_tx, normalized_texel + vec2(dispersion, 0.0)).r;
+  const float green = texture_load(input_tx, texel).g;
+  const float blue = texture(input_tx, normalized_texel - vec2(dispersion, 0.0)).b;
+
+  imageStore(output_img, texel, vec4(red, green, blue, 1.0));
+}
diff --git a/source/blender/gpu/shaders/compositor/compositor_screen_lens_distortion.glsl b/source/blender/gpu/shaders/compositor/compositor_screen_lens_distortion.glsl
new file mode 100644
index 00000000000..dc572ea5aaf
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/compositor_screen_lens_distortion.glsl
@@ -0,0 +1,151 @@
+#pragma BLENDER_REQUIRE(gpu_shader_common_hash.glsl)
+#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
+
+/* A model that approximates lens distortion parameterized by a distortion parameter and dependent
+ * on the squared distance to the center of the image. The distorted pixel is then computed as the
+ * scalar multiplication of the pixel coordinates with the value returned by this model. See the
+ * compute_distorted_uv function for more details. */
+float compute_distortion_scale(float distortion, float distance_squared)
+{
+  return 1.0 / (1.0 + sqrt(max(0.0, 1.0 - distortion * distance_squared)));
+}
+
+/* A vectorized version of compute_distortion_scale that is applied on the chromatic distortion
+ * parameters passed to the shader. */
+vec3 compute_chromatic_distortion_scale(float distance_squared)
+{
+  return 1.0 / (1.0 + sqrt(max(vec3(0.0), 1.0 - chromatic_distortion * distance_squared)));
+}
+
+/* Compute the image coordinates after distortion by the given distortion scale computed by the
+ * compute_distortion_scale function. Note that the function expects centered normalized UV
+ * coordinates but outputs non-centered image coordinates. */
+vec2 compute_distorted_uv(vec2 uv, float scale)
+{
+  return (uv * scale + 0.5) * texture_size(input_tx) - 0.5;
+}
+
+/* Compute the number of integration steps that should be used to approximate the distorted pixel
+ * using a heuristic, see the compute_number_of_steps function for more details. The numbers of
+ * steps is proportional to the number of pixels spanned by the distortion amount. For jitter
+ * distortion, the square root of the distortion amount plus 1 is used with a minimum of 2 steps.
+ * For non-jitter distortion, the distortion amount plus 1 is used as the number of steps */
+int compute_number_of_integration_steps_heuristic(float distortion)
+{
+#if defined(JITTER)
+  return distortion < 4.0 ? 2 : int(sqrt(distortion + 1.0));
+#else
+  return int(distortion + 1.0);
+#endif
+}
+
+/* Compute the number of integration steps that should be used to compute each channel of the
+ * distorted pixel. Each of the channels are distorted by their respective chromatic distortion
+ * amount, then the amount of distortion between each two consecutive channels is computed, this
+ * amount is then used to heuristically infer the number of needed integration steps, see the
+ * integrate_distortion function for more information. */
+ivec3 compute_number_of_integration_steps(vec2 uv, float distance_squared)
+{
+  /* Distort each channel by its respective chromatic distortion amount. */
+  vec3 distortion_scale = compute_chromatic_distortion_scale(distance_squared);
+  vec2 distorted_uv_red = compute_distorted_uv(uv, distortion_scale.r);
+  vec2 distorted_uv_green = compute_distorted_uv(uv, distortion_scale.g);
+  vec2 distorted_uv_blue = compute_distorted_uv(uv, distortion_scale.b);
+
+  /* Infer the number of needed integration steps to compute the distorted red channel starting
+   * from the green channel. */
+  float distortion_red = distance(distorted_uv_red, distorted_uv_green);
+  int steps_red = compute_number_of_integration_steps_heuristic(distortion_red);
+
+  /* Infer the number of needed integration steps to compute the distorted blue channel starting
+   * from the green channel. */
+  float distortion_blue = distance(distorted_uv_green, distorted_uv_blue);
+  int steps_blue = compute_number_of_integration_steps_heuristic(distortion_blue);
+
+  /* The number of integration steps used to compute the green channel is the sum of both the red
+   * and the blue channel steps because it is computed once with each of them. */
+  return ivec3(steps_red, steps_red + steps_blue, steps_blue);
+}
+
+/* Returns a random jitter amount, which is essentially a random value in the [0, 1] range. If
+ * jitter is not enabled, return a constant 0.5 value instead. */
+float get_jitter(int seed)
+{
+#if defined(JITTER)
+  return hash_uint3_to_float(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y, seed);
+#else
+  return 0.5;
+#endif
+}
+
+/* Each color channel may have a different distortion with the guarantee that the red will have the
+ * lowest distortion while the blue will have the highest one. If each channel is distorted
+ * independently, the image will look disintegrated, with each channel seemingly merely shifted.
+ * Consequently, the distorted pixels needs to be computed by integrating along the path of change
+ * of distortion starting from one channel to another. For instance, to compute the distorted red
+ * from the distorted green, we accumulate the color of the distorted pixel starting from the
+ * distortion of the red, taking small steps until we reach the distortion of the green. The pixel
+ * color is weighted such that it is maximum at the start distortion and zero at the end distortion
+ * in an arithmetic progression. The integration steps can be augmented with random values to
+ * simulate lens jitter. Finally, it should be noted that this function integrates both the start
+ * and end channels in reverse directions for more efficient computation. */
+vec3 in

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list