[Bf-blender-cvs] [6a22de3927a] temp-viewport-compositor-compiler: Viewport Compositor: Add domain repetition support

Omar Emara noreply at git.blender.org
Thu Apr 7 10:31:13 CEST 2022


Commit: 6a22de3927a7596d110eed1b72b377862d0dd92e
Author: Omar Emara
Date:   Thu Apr 7 10:25:43 2022 +0200
Branches: temp-viewport-compositor-compiler
https://developer.blender.org/rB6a22de3927a7596d110eed1b72b377862d0dd92e

Viewport Compositor: Add domain repetition support

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

M	source/blender/nodes/NOD_compositor_execute.hh
M	source/blender/nodes/composite/nodes/node_composite_rotate.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/nodes/NOD_compositor_execute.hh b/source/blender/nodes/NOD_compositor_execute.hh
index 5709dc9b4cf..4463db979cc 100644
--- a/source/blender/nodes/NOD_compositor_execute.hh
+++ b/source/blender/nodes/NOD_compositor_execute.hh
@@ -110,17 +110,41 @@ class Context {
 };
 
 /* --------------------------------------------------------------------
- * Domain.
+ * Realization Options.
  */
 
-/* Possible interpolations to use when realizing an input of some domain on another domain. See the
- * Domain class for more information. */
+/* Possible interpolations to use when realizing an input result of some domain on another domain.
+ * See the RealizationOptions class for more information. */
 enum class Interpolation : uint8_t {
   Nearest,
   Bilinear,
   Bicubic,
 };
 
+/* The options that describe how an input result prefer to be realized on some other domain. This
+ * is used by the RealizeOnDomainProcessorOperation to identify the appropriate method of
+ * realization. See the Domain class for more information. */
+class RealizationOptions {
+ public:
+  /* The interpolation method that should be used when performing realization. Since realizing a
+   * result involves projecting it on a different domain, which in turn, involves sampling the
+   * result at arbitrary locations, the interpolation identifies the method used for computing the
+   * value at those arbitrary locations. */
+  Interpolation interpolation = Interpolation::Nearest;
+  /* If true, the result will be repeated infinitely along the horizontal axis when realizing the
+   * result. If false, regions outside of bounds of the result along the horizontal axis will be
+   * filled with zeros. */
+  bool repeat_x = false;
+  /* If true, the result will be repeated infinitely along the vertical axis when realizing the
+   * result. If false, regions outside of bounds of the result along the vertical axis will be
+   * filled with zeros. */
+  bool repeat_y = false;
+};
+
+/* --------------------------------------------------------------------
+ * Domain.
+ */
+
 /* A domain is a rectangular area of a certain size in pixels that is transformed by a certain
  * transformation in pixel space relative to some reference space.
  *
@@ -138,10 +162,11 @@ enum class Interpolation : uint8_t {
  * RealizeOnDomainProcessorOperation, except inputs whose descriptor sets skip_realization or
  * expects_single_value, see InputDescriptor for more information. The realization process simply
  * projects the input domain on the operation domain, copies the area of input that intersects the
- * operation domain, and fill the rest with zeros. The realization happens using the interpolation
- * method defined set in the realization_interpolation member. This process is illustrated below.
- * It follows that operations should expect all their inputs to have the same domain and
- * consequently size, except for inputs that explicitly skip realization.
+ * operation domain, and fill the rest with zeros or repetitions of the input domain; depending on
+ * the realization_options, see the RealizationOptions class for more information. This process is
+ * illustrated below, assuming no repetition in either directions. It follows that operations
+ * should expect all their inputs to have the same domain and consequently size, except for inputs
+ * that explicitly skip realization.
  *
  *                                   Realized Result
  *             +-------------+       +-------------+
@@ -187,9 +212,9 @@ class Domain {
   /* The 2D transformation of the domain defining its translation in pixels, rotation, and scale in
    * 2D space. */
   Transformation2D transformation;
-  /* The interpolation method that should be used when realizing the input whose domain is this
-   * one. */
-  Interpolation realization_interpolation = Interpolation::Nearest;
+  /* The options that describe how this domain prefer to be realized on some other domain. See the
+   * RealizationOptions for more information. */
+  RealizationOptions realization_options;
 
  public:
   /* A size only constructor that sets the transformation to identity. */
@@ -302,8 +327,9 @@ class Result {
    * transformation by the current transformation of the domain of the result. */
   void transform(const Transformation2D &transformation);
 
-  /* Set the interpolation method that will be used when realizing this result if needed. */
-  void set_realization_interpolation(Interpolation interpolation);
+  /* Get a reference to the realization options of this result. See the RealizationOptions class
+   * for more information. */
+  RealizationOptions &get_realization_options();
 
   /* If the result is a single value result of type float, return its float value. Otherwise, an
    * uninitialized value is returned. */
diff --git a/source/blender/nodes/composite/nodes/node_composite_rotate.cc b/source/blender/nodes/composite/nodes/node_composite_rotate.cc
index efa74b7fe72..f261acbaaf3 100644
--- a/source/blender/nodes/composite/nodes/node_composite_rotate.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_rotate.cc
@@ -76,7 +76,7 @@ class RotateOperation : public NodeOperation {
     const Transformation2D transformation = Transformation2D::from_rotation(rotation);
 
     result.transform(transformation);
-    result.set_realization_interpolation(get_interpolation());
+    result.get_realization_options().interpolation = get_interpolation();
   }
 
   Interpolation get_interpolation()
diff --git a/source/blender/nodes/composite/nodes/node_composite_transform.cc b/source/blender/nodes/composite/nodes/node_composite_transform.cc
index 001ad932fbc..befc44f4676 100644
--- a/source/blender/nodes/composite/nodes/node_composite_transform.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_transform.cc
@@ -91,7 +91,7 @@ class TransformOperation : public NodeOperation {
         translation, rotation, scale);
 
     result.transform(transformation);
-    result.set_realization_interpolation(get_interpolation());
+    result.get_realization_options().interpolation = get_interpolation();
   }
 
   Interpolation get_interpolation()
diff --git a/source/blender/nodes/intern/node_compositor_execute.cc b/source/blender/nodes/intern/node_compositor_execute.cc
index f2753e3e9fb..3d1cb671486 100644
--- a/source/blender/nodes/intern/node_compositor_execute.cc
+++ b/source/blender/nodes/intern/node_compositor_execute.cc
@@ -129,8 +129,8 @@ Domain Domain::identity()
   return Domain(int2(1), Transformation2D::identity());
 }
 
-/* Only compare the size and transformation members, as other members only describe the method of
- * realization on another domain, which is not technically a proprty of the domain. */
+/* Do not compare realization_options as it only describe the method of realization on another
+ * domain, which is not technically a proprty of the domain itself. */
 bool operator==(const Domain &a, const Domain &b)
 {
   return a.size == b.size && a.transformation == b.transformation;
@@ -225,9 +225,9 @@ void Result::transform(const Transformation2D &transformation)
   domain_.transform(transformation);
 }
 
-void Result::set_realization_interpolation(Interpolation interpolation)
+RealizationOptions &Result::get_realization_options()
 {
-  domain_.realization_interpolation = interpolation;
+  return domain_.realization_options;
 }
 
 float Result::get_float_value() const
@@ -988,13 +988,20 @@ void RealizeOnDomainProcessorOperation::execute()
   /* Set the inverse of the transform to the shader. */
   GPU_shader_uniform_mat3(shader, "inverse_transformation", inverse_transformation.matrix());
 
-  /* Make out-of-bound texture access return zero. */
-  GPU_texture_wrap_mode(input.texture(), false, false);
-
-  /* Set the approperiate sampler interpolation. */
-  const bool use_bilinear = input.domain().realization_interpolation != Interpolation::Nearest;
+  /* The texture sampler should use bilinear interpolation for both the bilinear and bicubic
+   * cases, as the logic used by the bicubic realization shader expects textures to use bilinear
+   * interpolation. */
+  const bool use_bilinear = ELEM(input.get_realization_options().interpolation,
+                                 Interpolation::Bilinear,
+                                 Interpolation::Bicubic);
   GPU_texture_filter_mode(input.texture(), use_bilinear);
 
+  /* Make out-of-bound texture access return zero by clamping to border color. And make texture
+   * wrap appropriately if the input repeats. */
+  const bool repeats = input.get_realization_options().repeat_x ||
+                       input.get_realization_options().repeat_y;
+  GPU_texture_wrap_mode(input.texture(), repeats, false);
+
   input.bind_as_texture(shader, "input_sampler");
   result.bind_as_image(shader, "domain");



More information about the Bf-blender-cvs mailing list