[Bf-blender-cvs] [153b45037f5] master: Compositor: Full frame matte nodes

Manuel Castilla noreply at git.blender.org
Mon Aug 23 17:18:43 CEST 2021


Commit: 153b45037f5d27cf125d56ebb9aa77aca53d0981
Author: Manuel Castilla
Date:   Mon Aug 23 15:30:46 2021 +0200
Branches: master
https://developer.blender.org/rB153b45037f5d27cf125d56ebb9aa77aca53d0981

Compositor: Full frame matte nodes

Adds full frame implementation to Channel Key, Chroma Key, Color Key,
Color Spill, Cryptomatte, Difference Key, Distance Key, Keying,
Keying Screen and Luminance Key nodes. The other nodes
in "Matte" sub-menu are submitted separately.

No functional changes.

Part of T88150.

Reviewed By: jbakker

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

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

M	source/blender/compositor/operations/COM_ChannelMatteOperation.cc
M	source/blender/compositor/operations/COM_ChannelMatteOperation.h
M	source/blender/compositor/operations/COM_ChromaMatteOperation.cc
M	source/blender/compositor/operations/COM_ChromaMatteOperation.h
M	source/blender/compositor/operations/COM_ColorMatteOperation.cc
M	source/blender/compositor/operations/COM_ColorMatteOperation.h
M	source/blender/compositor/operations/COM_ColorSpillOperation.cc
M	source/blender/compositor/operations/COM_ColorSpillOperation.h
M	source/blender/compositor/operations/COM_CryptomatteOperation.cc
M	source/blender/compositor/operations/COM_CryptomatteOperation.h
M	source/blender/compositor/operations/COM_DifferenceMatteOperation.cc
M	source/blender/compositor/operations/COM_DifferenceMatteOperation.h
M	source/blender/compositor/operations/COM_DistanceRGBMatteOperation.cc
M	source/blender/compositor/operations/COM_DistanceRGBMatteOperation.h
M	source/blender/compositor/operations/COM_DistanceYCCMatteOperation.cc
M	source/blender/compositor/operations/COM_DistanceYCCMatteOperation.h
M	source/blender/compositor/operations/COM_KeyingBlurOperation.cc
M	source/blender/compositor/operations/COM_KeyingBlurOperation.h
M	source/blender/compositor/operations/COM_KeyingClipOperation.cc
M	source/blender/compositor/operations/COM_KeyingClipOperation.h
M	source/blender/compositor/operations/COM_KeyingDespillOperation.cc
M	source/blender/compositor/operations/COM_KeyingDespillOperation.h
M	source/blender/compositor/operations/COM_KeyingOperation.cc
M	source/blender/compositor/operations/COM_KeyingOperation.h
M	source/blender/compositor/operations/COM_KeyingScreenOperation.cc
M	source/blender/compositor/operations/COM_KeyingScreenOperation.h
M	source/blender/compositor/operations/COM_LuminanceMatteOperation.cc
M	source/blender/compositor/operations/COM_LuminanceMatteOperation.h

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

diff --git a/source/blender/compositor/operations/COM_ChannelMatteOperation.cc b/source/blender/compositor/operations/COM_ChannelMatteOperation.cc
index ec4331dc231..65742d0cfcc 100644
--- a/source/blender/compositor/operations/COM_ChannelMatteOperation.cc
+++ b/source/blender/compositor/operations/COM_ChannelMatteOperation.cc
@@ -27,6 +27,7 @@ ChannelMatteOperation::ChannelMatteOperation()
   addOutputSocket(DataType::Value);
 
   this->m_inputImageProgram = nullptr;
+  flags.can_be_constant = true;
 }
 
 void ChannelMatteOperation::initExecution()
@@ -121,4 +122,37 @@ void ChannelMatteOperation::executePixelSampled(float output[4],
   output[0] = MIN2(alpha, inColor[3]);
 }
 
+void ChannelMatteOperation::update_memory_buffer_partial(MemoryBuffer *output,
+                                                         const rcti &area,
+                                                         Span<MemoryBuffer *> inputs)
+{
+  for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) {
+    const float *color = it.in(0);
+
+    /* Matte operation. */
+    float alpha = color[this->m_ids[0]] - MAX2(color[this->m_ids[1]], color[this->m_ids[2]]);
+
+    /* Flip because 0.0 is transparent, not 1.0. */
+    alpha = 1.0f - alpha;
+
+    /* Test range. */
+    if (alpha > m_limit_max) {
+      alpha = color[3]; /* Whatever it was prior. */
+    }
+    else if (alpha < m_limit_min) {
+      alpha = 0.0f;
+    }
+    else { /* Blend. */
+      alpha = (alpha - m_limit_min) / m_limit_range;
+    }
+
+    /* Store matte(alpha) value in [0] to go with
+     * COM_SetAlphaMultiplyOperation and the Value output.
+     */
+
+    /* Don't make something that was more transparent less transparent. */
+    *it.out = MIN2(alpha, color[3]);
+  }
+}
+
 }  // namespace blender::compositor
diff --git a/source/blender/compositor/operations/COM_ChannelMatteOperation.h b/source/blender/compositor/operations/COM_ChannelMatteOperation.h
index 6e9dcccd36e..ba50105dd3b 100644
--- a/source/blender/compositor/operations/COM_ChannelMatteOperation.h
+++ b/source/blender/compositor/operations/COM_ChannelMatteOperation.h
@@ -18,7 +18,7 @@
 
 #pragma once
 
-#include "COM_MixOperation.h"
+#include "COM_MultiThreadedOperation.h"
 
 namespace blender::compositor {
 
@@ -26,7 +26,7 @@ namespace blender::compositor {
  * this program converts an input color to an output value.
  * it assumes we are in sRGB color space.
  */
-class ChannelMatteOperation : public NodeOperation {
+class ChannelMatteOperation : public MultiThreadedOperation {
  private:
   SocketReader *m_inputImageProgram;
 
@@ -71,6 +71,10 @@ class ChannelMatteOperation : public NodeOperation {
     this->m_limit_channel = nodeChroma->channel;
     this->m_matte_channel = custom2;
   }
+
+  void update_memory_buffer_partial(MemoryBuffer *output,
+                                    const rcti &area,
+                                    Span<MemoryBuffer *> inputs) override;
 };
 
 }  // namespace blender::compositor
diff --git a/source/blender/compositor/operations/COM_ChromaMatteOperation.cc b/source/blender/compositor/operations/COM_ChromaMatteOperation.cc
index b7fec5f07e5..0784f266b19 100644
--- a/source/blender/compositor/operations/COM_ChromaMatteOperation.cc
+++ b/source/blender/compositor/operations/COM_ChromaMatteOperation.cc
@@ -29,6 +29,7 @@ ChromaMatteOperation::ChromaMatteOperation()
 
   this->m_inputImageProgram = nullptr;
   this->m_inputKeyProgram = nullptr;
+  flags.can_be_constant = true;
 }
 
 void ChromaMatteOperation::initExecution()
@@ -110,4 +111,58 @@ void ChromaMatteOperation::executePixelSampled(float output[4],
   }
 }
 
+void ChromaMatteOperation::update_memory_buffer_partial(MemoryBuffer *output,
+                                                        const rcti &area,
+                                                        Span<MemoryBuffer *> inputs)
+{
+  const float acceptance = this->m_settings->t1; /* In radians. */
+  const float cutoff = this->m_settings->t2;     /* In radians. */
+  const float gain = this->m_settings->fstrength;
+  for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) {
+    const float *in_image = it.in(0);
+    const float *in_key = it.in(1);
+
+    /* Store matte(alpha) value in [0] to go with
+     * #COM_SetAlphaMultiplyOperation and the Value output. */
+
+    /* Algorithm from book "Video Demystified", does not include the spill reduction part. */
+    /* Find theta, the angle that the color space should be rotated based on key. */
+
+    /* Rescale to `-1.0..1.0`. */
+    // const float image_Y = (in_image[0] * 2.0f) - 1.0f;  // UNUSED
+    const float image_cb = (in_image[1] * 2.0f) - 1.0f;
+    const float image_cr = (in_image[2] * 2.0f) - 1.0f;
+
+    // const float key_Y = (in_key[0] * 2.0f) - 1.0f;  // UNUSED
+    const float key_cb = (in_key[1] * 2.0f) - 1.0f;
+    const float key_cr = (in_key[2] * 2.0f) - 1.0f;
+
+    const float theta = atan2(key_cr, key_cb);
+
+    /* Rotate the cb and cr into x/z space. */
+    const float x_angle = image_cb * cosf(theta) + image_cr * sinf(theta);
+    const float z_angle = image_cr * cosf(theta) - image_cb * sinf(theta);
+
+    /* If within the acceptance angle. */
+    /* If kfg is <0 then the pixel is outside of the key color. */
+    const float kfg = x_angle - (fabsf(z_angle) / tanf(acceptance / 2.0f));
+
+    if (kfg > 0.0f) { /* Found a pixel that is within key color. */
+      const float beta = atan2(z_angle, x_angle);
+      float alpha = 1.0f - (kfg / gain);
+
+      /* Ff beta is within the cutoff angle. */
+      if (fabsf(beta) < (cutoff / 2.0f)) {
+        alpha = 0.0f;
+      }
+
+      /* Don't make something that was more transparent less transparent. */
+      it.out[0] = alpha < in_image[3] ? alpha : in_image[3];
+    }
+    else {                     /* Pixel is outside key color. */
+      it.out[0] = in_image[3]; /* Make pixel just as transparent as it was before. */
+    }
+  }
+}
+
 }  // namespace blender::compositor
diff --git a/source/blender/compositor/operations/COM_ChromaMatteOperation.h b/source/blender/compositor/operations/COM_ChromaMatteOperation.h
index 48c3a785011..065349910a7 100644
--- a/source/blender/compositor/operations/COM_ChromaMatteOperation.h
+++ b/source/blender/compositor/operations/COM_ChromaMatteOperation.h
@@ -18,7 +18,7 @@
 
 #pragma once
 
-#include "COM_MixOperation.h"
+#include "COM_MultiThreadedOperation.h"
 
 namespace blender::compositor {
 
@@ -26,7 +26,7 @@ namespace blender::compositor {
  * this program converts an input color to an output value.
  * it assumes we are in sRGB color space.
  */
-class ChromaMatteOperation : public NodeOperation {
+class ChromaMatteOperation : public MultiThreadedOperation {
  private:
   NodeChroma *m_settings;
   SocketReader *m_inputImageProgram;
@@ -50,6 +50,10 @@ class ChromaMatteOperation : public NodeOperation {
   {
     this->m_settings = nodeChroma;
   }
+
+  void update_memory_buffer_partial(MemoryBuffer *output,
+                                    const rcti &area,
+                                    Span<MemoryBuffer *> inputs) override;
 };
 
 }  // namespace blender::compositor
diff --git a/source/blender/compositor/operations/COM_ColorMatteOperation.cc b/source/blender/compositor/operations/COM_ColorMatteOperation.cc
index ddfbf415d9c..dec6571f217 100644
--- a/source/blender/compositor/operations/COM_ColorMatteOperation.cc
+++ b/source/blender/compositor/operations/COM_ColorMatteOperation.cc
@@ -29,6 +29,7 @@ ColorMatteOperation::ColorMatteOperation()
 
   this->m_inputImageProgram = nullptr;
   this->m_inputKeyProgram = nullptr;
+  flags.can_be_constant = true;
 }
 
 void ColorMatteOperation::initExecution()
@@ -82,4 +83,40 @@ void ColorMatteOperation::executePixelSampled(float output[4],
   }
 }
 
+void ColorMatteOperation::update_memory_buffer_partial(MemoryBuffer *output,
+                                                       const rcti &area,
+                                                       Span<MemoryBuffer *> inputs)
+{
+  const float hue = m_settings->t1;
+  const float sat = m_settings->t2;
+  const float val = m_settings->t3;
+  for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) {
+    const float *in_color = it.in(0);
+    const float *in_key = it.in(1);
+
+    /* Store matte(alpha) value in [0] to go with
+     * COM_SetAlphaMultiplyOperation and the Value output.
+     */
+
+    float h_wrap;
+    if (
+        /* Do hue last because it needs to wrap, and does some more checks. */
+
+        /* #sat */ (fabsf(in_color[1] - in_key[1]) < sat) &&
+        /* #val */ (fabsf(in_color[2] - in_key[2]) < val) &&
+
+        /* Multiply by 2 because it wraps on both sides of the hue,
+         * otherwise 0.5 would key all hue's. */
+
+        /* #hue */
+        ((h_wrap = 2.0f * fabsf(in_color[0] - in_key[0])) < hue || (2.0f - h_wrap) < hue)) {
+      it.out[0] = 0.0f; /* Make transparent. */
+    }
+
+    else {                     /* Pixel is outside key color. */
+      it.out[0] = in_color[3]; /* Make pixel just as transparent as it was before. */
+    }
+  }
+}
+
 }  // namespace blender::compositor
diff --git a/source/blender/compositor/operations/COM_ColorMatteOperation.h b/source/blender/compositor/operations/COM_ColorMatteOperation.h
index 439a3b0741d..49d06e62e65 100644
--- a/source/blender/compositor/operations/COM_ColorMatteOperation.h
+++ b/source/blender/compositor/operations/COM_ColorMatteOperation.h
@@ -18,7 +18,7 @@
 
 #pragma once
 
-#include "COM_MixOperation.h"
+#include "COM_MultiThreadedOperation.h"
 
 namespace blender::compositor {
 
@@ -26,7 +26,7 @@ namespace blender::compositor {
  * this program converts an input color to an output value.
  * it assumes we are in sRGB color space.
  */
-class ColorMatteOperation : public NodeOperation {
+class ColorMatteOperation : public MultiThreadedOperation {
  private:
   NodeChroma *m_settings;
   SocketReader *m_inputImageProgram;
@@ -50,6 +50,10 @@ class ColorMatteOperation : public NodeOperation {
   {
     this->m_settings = nodeChroma;
   }
+
+  void update_memory_buffer_partial(MemoryBuffer *output,
+                 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list