[Bf-blender-cvs] [a87428f5330] temp-viewport-compositor-compiler: Viewport Compositor: Support realization interpolations

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


Commit: a87428f533009dd7045e7134fc2295905b4ba7b0
Author: Omar Emara
Date:   Fri Apr 1 17:09:30 2022 +0200
Branches: temp-viewport-compositor-compiler
https://developer.blender.org/rBa87428f533009dd7045e7134fc2295905b4ba7b0

Viewport Compositor: Support realization interpolations

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

M	source/blender/nodes/NOD_compositor_execute.hh
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 b61618e6725..5709dc9b4cf 100644
--- a/source/blender/nodes/NOD_compositor_execute.hh
+++ b/source/blender/nodes/NOD_compositor_execute.hh
@@ -113,6 +113,14 @@ class Context {
  * Domain.
  */
 
+/* Possible interpolations to use when realizing an input of some domain on another domain. See the
+ * Domain class for more information. */
+enum class Interpolation : uint8_t {
+  Nearest,
+  Bilinear,
+  Bicubic,
+};
+
 /* 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.
  *
@@ -130,9 +138,10 @@ class Context {
  * 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. 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. 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.
  *
  *                                   Realized Result
  *             +-------------+       +-------------+
@@ -152,7 +161,7 @@ class Context {
  * from it. The domain input is determined to be the non-single value input that have the highest
  * domain priority, a zero value being the highest priority. If all inputs are single values, then
  * the operation domain is irrelevant and an identity domain is set. See
- * NodeOperation::compute_domain.
+ * NodeOperation::compute_domain for more information.
  *
  * The aforementioned logic for operation domain computation is only a default that works for most
  * cases, but an operation can override the compute_domain method to implement a different logic.
@@ -178,6 +187,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;
 
  public:
   /* A size only constructor that sets the transformation to identity. */
@@ -290,6 +302,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);
+
   /* If the result is a single value result of type float, return its float value. Otherwise, an
    * uninitialized value is returned. */
   float get_float_value() const;
@@ -350,7 +365,7 @@ class Result {
    * reference count of the master result is returned instead. */
   int reference_count() const;
 
-  /* Returns the domain of the result. See the Domain class. */
+  /* Returns a reference to the domain of the result. See the Domain class. */
   const Domain &domain() const;
 };
 
diff --git a/source/blender/nodes/composite/nodes/node_composite_transform.cc b/source/blender/nodes/composite/nodes/node_composite_transform.cc
index d6f2734b54d..0d314a4d20e 100644
--- a/source/blender/nodes/composite/nodes/node_composite_transform.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_transform.cc
@@ -21,6 +21,7 @@
  * \ingroup cmpnodes
  */
 
+#include "BLI_assert.h"
 #include "BLI_math_vector.h"
 
 #include "UI_interface.h"
@@ -87,6 +88,22 @@ class TransformOperation : public NodeOperation {
         translation, rotation, scale);
 
     result.transform(transformation);
+    result.set_realization_interpolation(get_interpolation());
+  }
+
+  Interpolation get_interpolation()
+  {
+    switch (node().custom1) {
+      case 0:
+        return Interpolation::Nearest;
+      case 1:
+        return Interpolation::Bilinear;
+      case 2:
+        return Interpolation::Bicubic;
+    }
+
+    BLI_assert_unreachable();
+    return Interpolation::Nearest;
   }
 };
 
diff --git a/source/blender/nodes/intern/node_compositor_execute.cc b/source/blender/nodes/intern/node_compositor_execute.cc
index 94acfcd2c46..f2753e3e9fb 100644
--- a/source/blender/nodes/intern/node_compositor_execute.cc
+++ b/source/blender/nodes/intern/node_compositor_execute.cc
@@ -129,6 +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. */
 bool operator==(const Domain &a, const Domain &b)
 {
   return a.size == b.size && a.transformation == b.transformation;
@@ -223,6 +225,11 @@ void Result::transform(const Transformation2D &transformation)
   domain_.transform(transformation);
 }
 
+void Result::set_realization_interpolation(Interpolation interpolation)
+{
+  domain_.realization_interpolation = interpolation;
+}
+
 float Result::get_float_value() const
 {
   return *value_;
@@ -984,6 +991,10 @@ void RealizeOnDomainProcessorOperation::execute()
   /* 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;
+  GPU_texture_filter_mode(input.texture(), use_bilinear);
+
   input.bind_as_texture(shader, "input_sampler");
   result.bind_as_image(shader, "domain");



More information about the Bf-blender-cvs mailing list