[Bf-blender-cvs] [a7195ad4505] temp-viewport-compositor-compiler: Viewport Compositor: Add support for domains

Omar Emara noreply at git.blender.org
Fri Mar 4 21:01:02 CET 2022


Commit: a7195ad45058a0536c4a3f2f8af4d100cf248b34
Author: Omar Emara
Date:   Fri Mar 4 21:55:27 2022 +0200
Branches: temp-viewport-compositor-compiler
https://developer.blender.org/rBa7195ad45058a0536c4a3f2f8af4d100cf248b34

Viewport Compositor: Add support for domains

This patch supports compositing of arbitrary image sizes, supports
transformation operations, and supports infinit canvase compositing.

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

A	source/blender/blenlib/BLI_transformation_2d.hh
M	source/blender/blenlib/CMakeLists.txt
M	source/blender/gpu/CMakeLists.txt
M	source/blender/gpu/GPU_shader.h
M	source/blender/gpu/intern/gpu_shader.cc
A	source/blender/gpu/shaders/compositor/compositor_realize_on_domain.glsl
A	source/blender/gpu/shaders/compositor/infos/compositor_realize_on_domain_info.hh
M	source/blender/nodes/NOD_compositor_execute.hh
M	source/blender/nodes/NOD_node_declaration.hh
M	source/blender/nodes/composite/nodes/node_composite_composite.cc
M	source/blender/nodes/composite/nodes/node_composite_transform.cc
M	source/blender/nodes/intern/node_compositor_execute.cc

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

diff --git a/source/blender/blenlib/BLI_transformation_2d.hh b/source/blender/blenlib/BLI_transformation_2d.hh
new file mode 100644
index 00000000000..28127432888
--- /dev/null
+++ b/source/blender/blenlib/BLI_transformation_2d.hh
@@ -0,0 +1,175 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include <cmath>
+#include <cstdint>
+
+#include "BLI_assert.h"
+#include "BLI_math_base.h"
+#include "BLI_math_matrix.h"
+#include "BLI_math_vec_types.hh"
+
+namespace blender {
+
+/* A 2D affine transformation stored in a transformation matrix in homogeneous coordinates form.
+ * The stores matrix is stored column major order. */
+struct Transformation2D {
+ private:
+  float matrix_[3][3];
+
+ public:
+  static Transformation2D zero()
+  {
+    Transformation2D result;
+    result.matrix_[0][0] = 0.0f;
+    result.matrix_[0][1] = 0.0f;
+    result.matrix_[0][2] = 0.0f;
+    result.matrix_[1][0] = 0.0f;
+    result.matrix_[1][1] = 0.0f;
+    result.matrix_[1][2] = 0.0f;
+    result.matrix_[2][0] = 0.0f;
+    result.matrix_[2][1] = 0.0f;
+    result.matrix_[2][2] = 0.0f;
+    return result;
+  }
+
+  static Transformation2D identity()
+  {
+    Transformation2D result = zero();
+    result.matrix_[0][0] = 1.0f;
+    result.matrix_[1][1] = 1.0f;
+    result.matrix_[2][2] = 1.0f;
+    return result;
+  }
+
+  static Transformation2D from_translation(const float2 translation)
+  {
+    Transformation2D result = identity();
+    result.matrix_[2][0] = translation.x;
+    result.matrix_[2][1] = translation.y;
+    return result;
+  }
+
+  static Transformation2D from_rotation(float rotation)
+  {
+    Transformation2D result = zero();
+    const float cosine = std::cos(rotation);
+    const float sine = std::sin(rotation);
+    result.matrix_[0][0] = cosine;
+    result.matrix_[0][1] = sine;
+    result.matrix_[1][0] = -sine;
+    result.matrix_[1][1] = cosine;
+    result.matrix_[2][2] = 1.0f;
+    return result;
+  }
+
+  static Transformation2D from_translation_rotation_scale(const float2 translation,
+                                                          float rotation,
+                                                          const float2 scale)
+  {
+    Transformation2D result;
+    const float cosine = std::cos(rotation);
+    const float sine = std::sin(rotation);
+    result.matrix_[0][0] = scale.x * cosine;
+    result.matrix_[0][1] = scale.y * sine;
+    result.matrix_[0][2] = 0.0f;
+    result.matrix_[1][0] = scale.x * -sine;
+    result.matrix_[1][1] = scale.y * cosine;
+    result.matrix_[1][2] = 0.0f;
+    result.matrix_[2][0] = translation.x;
+    result.matrix_[2][1] = translation.y;
+    result.matrix_[2][2] = 1.0f;
+    return result;
+  }
+
+  static Transformation2D from_normalized_axes(const float2 translation,
+                                               const float2 horizontal,
+                                               const float2 vertical)
+  {
+    BLI_ASSERT_UNIT_V2(horizontal);
+    BLI_ASSERT_UNIT_V2(vertical);
+
+    Transformation2D result;
+    result.matrix_[0][0] = horizontal.x;
+    result.matrix_[0][1] = horizontal.y;
+    result.matrix_[0][2] = 0.0f;
+    result.matrix_[1][0] = vertical.x;
+    result.matrix_[1][1] = vertical.y;
+    result.matrix_[1][2] = 0.0f;
+    result.matrix_[2][0] = translation.x;
+    result.matrix_[2][1] = translation.y;
+    result.matrix_[2][2] = 1.0f;
+    return result;
+  }
+
+  friend Transformation2D operator*(const Transformation2D &a, const Transformation2D &b)
+  {
+    Transformation2D result;
+    mul_m3_m3m3(result.matrix_, a.matrix_, b.matrix_);
+    return result;
+  }
+
+  void operator*=(const Transformation2D &other)
+  {
+    mul_m3_m3_post(matrix_, other.matrix_);
+  }
+
+  friend float2 operator*(const Transformation2D &transformation, const float2 &vector)
+  {
+    float2 result;
+    mul_v2_m3v2(result, transformation.matrix_, vector);
+    return result;
+  }
+
+  friend float2 operator*(const Transformation2D &transformation, const float (*vector)[2])
+  {
+    return transformation * float2(vector);
+  }
+
+  Transformation2D transposed() const
+  {
+    Transformation2D result;
+    transpose_m3_m3(result.matrix_, matrix_);
+    return result;
+  }
+
+  Transformation2D inverted() const
+  {
+    Transformation2D result;
+    invert_m3_m3(result.matrix_, matrix_);
+    return result;
+  }
+
+  Transformation2D set_pivot(float2 pivot) const
+  {
+    return from_translation(pivot) * *this * from_translation(-pivot);
+  }
+
+  using matrix_array = float[3][3];
+  const matrix_array &matrix() const
+  {
+    return matrix_;
+  }
+
+  friend bool operator==(const Transformation2D &a, const Transformation2D &b)
+  {
+    return equals_m3m3(a.matrix_, b.matrix_);
+  }
+};
+
+}  // namespace blender
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index 31e550379f1..2f4ba846cd2 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -303,6 +303,7 @@ set(SRC
   BLI_threads.h
   BLI_timecode.h
   BLI_timeit.hh
+  BLI_transformation_2d.hh
   BLI_timer.h
   BLI_user_counter.hh
   BLI_utildefines.h
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 69013660f23..924cf5a1c8f 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -313,6 +313,7 @@ set(GLSL_SRC
   shaders/compositor/compositor_convert_vector_to_color.glsl
   shaders/compositor/compositor_image.glsl
   shaders/compositor/compositor_image_alpha.glsl
+  shaders/compositor/compositor_realize_on_domain.glsl
 
   shaders/material/gpu_shader_material_add_shader.glsl
   shaders/material/gpu_shader_material_ambient_occlusion.glsl
@@ -499,6 +500,7 @@ set(SHADER_CREATE_INFOS
   shaders/compositor/infos/compositor_convert_vector_to_color_info.hh
   shaders/compositor/infos/compositor_image_info.hh
   shaders/compositor/infos/compositor_image_alpha_info.hh
+  shaders/compositor/infos/compositor_realize_on_domain_info.hh
 )
 
 set(SHADER_CREATE_INFOS_CONTENT "")
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index 846bda07127..0b5f5fd8242 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -200,6 +200,7 @@ void GPU_shader_uniform_4f(GPUShader *sh, const char *name, float x, float y, fl
 void GPU_shader_uniform_2fv(GPUShader *sh, const char *name, const float data[2]);
 void GPU_shader_uniform_3fv(GPUShader *sh, const char *name, const float data[3]);
 void GPU_shader_uniform_4fv(GPUShader *sh, const char *name, const float data[4]);
+void GPU_shader_uniform_mat3(GPUShader *sh, const char *name, const float data[3][3]);
 void GPU_shader_uniform_mat4(GPUShader *sh, const char *name, const float data[4][4]);
 void GPU_shader_uniform_2fv_array(GPUShader *sh, const char *name, int len, const float (*val)[2]);
 void GPU_shader_uniform_4fv_array(GPUShader *sh, const char *name, int len, const float (*val)[4]);
diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc
index b670b240a03..645c17a3b27 100644
--- a/source/blender/gpu/intern/gpu_shader.cc
+++ b/source/blender/gpu/intern/gpu_shader.cc
@@ -716,6 +716,12 @@ void GPU_shader_uniform_4fv(GPUShader *sh, const char *name, const float data[4]
   GPU_shader_uniform_vector(sh, loc, 4, 1, data);
 }
 
+void GPU_shader_uniform_mat3(GPUShader *sh, const char *name, const float data[3][3])
+{
+  const int loc = GPU_shader_get_uniform(sh, name);
+  GPU_shader_uniform_vector(sh, loc, 9, 1, (const float *)data);
+}
+
 void GPU_shader_uniform_mat4(GPUShader *sh, const char *name, const float data[4][4])
 {
   const int loc = GPU_shader_get_uniform(sh, name);
diff --git a/source/blender/gpu/shaders/compositor/compositor_realize_on_domain.glsl b/source/blender/gpu/shaders/compositor/compositor_realize_on_domain.glsl
new file mode 100644
index 00000000000..89edd87f5fa
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/compositor_realize_on_domain.glsl
@@ -0,0 +1,23 @@
+void main()
+{
+  ivec2 xy = ivec2(gl_GlobalInvocationID.xy);
+
+  /* First, transform the input image by transforming the domain coordinates with the inverse of
+   * input image's transformation. The inverse transformation is an affine matrix and thus the
+   * coordinates should be in homogeneous coordinates.  */
+  vec2 coordinates = (inverse_transformation * vec3(xy, 1.0)).xy;
+
+  /* Since an input image with an identity transformation is supposed to be centered in the domain,
+   * we subtract the offset between the lower left corners of the input image and the domain, which
+   * is half the difference between their sizes, because the difference in size is on both sides of
+   * the centered image. */
+  ivec2 domain_size = imageSize(domain);
+  ivec2 input_size = textureSize(input_sampler, 0);
+  vec2 offset = (domain_size - input_size) / 2.0;
+
+  /* Subtract the offset and divide by the input image size to get the relevant coordinates into
+   * the sampler's expected [0, 1] range. */
+  vec2 normalized_coordinates = (coordinates - offset) / input_size;
+
+  imageStore(domain, xy, texture(input_sampler, normalized_coordinates));
+}
diff --git a/source/blender/gpu/shaders/compositor/infos/compositor_realize_on_domain_info.hh b/source/blender/gpu/shaders/compositor/infos/compositor_realize_on_domain_info.hh
new file mode 100644
index 00000000000..4701d0bc2f6
--- /dev/null
+++ b/source/blender/gpu/shaders/compositor/infos/compositor_realize_on_domain_in

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list