[Bf-blender-cvs] [9b027543830] compositor-full-frame: Compositor: Full frame Displace node

Manuel Castilla noreply at git.blender.org
Thu Jul 29 22:36:41 CEST 2021


Commit: 9b0275438306bbf1c3e1123864562ec891854fd4
Author: Manuel Castilla
Date:   Thu Jul 29 19:45:36 2021 +0200
Branches: compositor-full-frame
https://developer.blender.org/rB9b0275438306bbf1c3e1123864562ec891854fd4

Compositor: Full frame Displace node

Adds full frame implementation to this node operation.
No functional changes.

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

M	source/blender/compositor/operations/COM_DisplaceOperation.cc
M	source/blender/compositor/operations/COM_DisplaceOperation.h
M	source/blender/compositor/operations/COM_DisplaceSimpleOperation.cc
M	source/blender/compositor/operations/COM_DisplaceSimpleOperation.h

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

diff --git a/source/blender/compositor/operations/COM_DisplaceOperation.cc b/source/blender/compositor/operations/COM_DisplaceOperation.cc
index 9f3f5cfe489..a4c01fda7ca 100644
--- a/source/blender/compositor/operations/COM_DisplaceOperation.cc
+++ b/source/blender/compositor/operations/COM_DisplaceOperation.cc
@@ -32,20 +32,30 @@ DisplaceOperation::DisplaceOperation()
   this->flags.complex = true;
 
   this->m_inputColorProgram = nullptr;
-  this->m_inputVectorProgram = nullptr;
-  this->m_inputScaleXProgram = nullptr;
-  this->m_inputScaleYProgram = nullptr;
 }
 
 void DisplaceOperation::initExecution()
 {
   this->m_inputColorProgram = this->getInputSocketReader(0);
-  this->m_inputVectorProgram = this->getInputSocketReader(1);
-  this->m_inputScaleXProgram = this->getInputSocketReader(2);
-  this->m_inputScaleYProgram = this->getInputSocketReader(3);
+  NodeOperation *vector = this->getInputSocketReader(1);
+  NodeOperation *scale_x = this->getInputSocketReader(2);
+  NodeOperation *scale_y = this->getInputSocketReader(3);
+  if (execution_model_ == eExecutionModel::Tiled) {
+    vector_read_fn_ = [=](float x, float y, float *out) {
+      vector->readSampled(out, x, y, PixelSampler::Bilinear);
+    };
+    scale_x_read_fn_ = [=](float x, float y, float *out) {
+      scale_x->readSampled(out, x, y, PixelSampler::Nearest);
+    };
+    scale_y_read_fn_ = [=](float x, float y, float *out) {
+      scale_y->readSampled(out, x, y, PixelSampler::Nearest);
+    };
+  }
 
   this->m_width_x4 = this->getWidth() * 4;
   this->m_height_x4 = this->getHeight() * 4;
+  input_vector_width_ = vector->getWidth();
+  input_vector_height_ = vector->getHeight();
 }
 
 void DisplaceOperation::executePixelSampled(float output[4],
@@ -69,8 +79,8 @@ void DisplaceOperation::executePixelSampled(float output[4],
 bool DisplaceOperation::read_displacement(
     float x, float y, float xscale, float yscale, const float origin[2], float &r_u, float &r_v)
 {
-  float width = m_inputVectorProgram->getWidth();
-  float height = m_inputVectorProgram->getHeight();
+  float width = input_vector_width_;
+  float height = input_vector_height_;
   if (x < 0.0f || x >= width || y < 0.0f || y >= height) {
     r_u = 0.0f;
     r_v = 0.0f;
@@ -78,7 +88,7 @@ bool DisplaceOperation::read_displacement(
   }
 
   float col[4];
-  m_inputVectorProgram->readSampled(col, x, y, PixelSampler::Bilinear);
+  vector_read_fn_(x, y, col);
   r_u = origin[0] - col[0] * xscale;
   r_v = origin[1] - col[1] * yscale;
   return true;
@@ -90,9 +100,9 @@ void DisplaceOperation::pixelTransform(const float xy[2], float r_uv[2], float r
   float uv[2]; /* temporary variables for derivative estimation */
   int num;
 
-  m_inputScaleXProgram->readSampled(col, xy[0], xy[1], PixelSampler::Nearest);
+  scale_x_read_fn_(xy[0], xy[1], col);
   float xs = col[0];
-  m_inputScaleYProgram->readSampled(col, xy[0], xy[1], PixelSampler::Nearest);
+  scale_y_read_fn_(xy[0], xy[1], col);
   float ys = col[0];
   /* clamp x and y displacement to triple image resolution -
    * to prevent hangs from huge values mistakenly plugged in eg. z buffers */
@@ -146,9 +156,9 @@ void DisplaceOperation::pixelTransform(const float xy[2], float r_uv[2], float r
 void DisplaceOperation::deinitExecution()
 {
   this->m_inputColorProgram = nullptr;
-  this->m_inputVectorProgram = nullptr;
-  this->m_inputScaleXProgram = nullptr;
-  this->m_inputScaleYProgram = nullptr;
+  vector_read_fn_ = nullptr;
+  scale_x_read_fn_ = nullptr;
+  scale_y_read_fn_ = nullptr;
 }
 
 bool DisplaceOperation::determineDependingAreaOfInterest(rcti *input,
@@ -195,4 +205,61 @@ bool DisplaceOperation::determineDependingAreaOfInterest(rcti *input,
   return false;
 }
 
+void DisplaceOperation::get_area_of_interest(const int input_idx,
+                                             const rcti &output_area,
+                                             rcti &r_input_area)
+{
+  switch (input_idx) {
+    case 0: {
+      r_input_area.xmin = 0;
+      r_input_area.ymin = 0;
+      r_input_area.xmax = getInputOperation(input_idx)->getWidth();
+      r_input_area.ymax = getInputOperation(input_idx)->getHeight();
+      break;
+    }
+    case 1: {
+      r_input_area = output_area;
+      expand_area_for_sampler(r_input_area, PixelSampler::Bilinear);
+      break;
+    }
+    default: {
+      r_input_area = output_area;
+      break;
+    }
+  }
+}
+
+void DisplaceOperation::update_memory_buffer_started(MemoryBuffer *UNUSED(output),
+                                                     const rcti &UNUSED(area),
+                                                     Span<MemoryBuffer *> inputs)
+{
+  MemoryBuffer *vector = inputs[1];
+  MemoryBuffer *scale_x = inputs[2];
+  MemoryBuffer *scale_y = inputs[3];
+  vector_read_fn_ = [=](float x, float y, float *out) { vector->read_elem_bilinear(x, y, out); };
+  scale_x_read_fn_ = [=](float x, float y, float *out) { scale_x->read_elem_checked(x, y, out); };
+  scale_y_read_fn_ = [=](float x, float y, float *out) { scale_y->read_elem_checked(x, y, out); };
+}
+
+void DisplaceOperation::update_memory_buffer_partial(MemoryBuffer *output,
+                                                     const rcti &area,
+                                                     Span<MemoryBuffer *> inputs)
+{
+  const MemoryBuffer *input_color = inputs[0];
+  for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) {
+    const float xy[2] = {(float)it.x, (float)it.y};
+    float uv[2];
+    float deriv[2][2];
+
+    pixelTransform(xy, uv, deriv);
+    if (is_zero_v2(deriv[0]) && is_zero_v2(deriv[1])) {
+      input_color->read_elem_bilinear(uv[0], uv[1], it.out);
+    }
+    else {
+      /* EWA filtering (without nearest it gets blurry with NO distortion). */
+      input_color->read_elem_filtered(uv[0], uv[1], deriv[0], deriv[1], it.out);
+    }
+  }
+}
+
 }  // namespace blender::compositor
diff --git a/source/blender/compositor/operations/COM_DisplaceOperation.h b/source/blender/compositor/operations/COM_DisplaceOperation.h
index fd82692f687..5be914ab672 100644
--- a/source/blender/compositor/operations/COM_DisplaceOperation.h
+++ b/source/blender/compositor/operations/COM_DisplaceOperation.h
@@ -18,23 +18,27 @@
 
 #pragma once
 
-#include "COM_NodeOperation.h"
+#include "COM_MultiThreadedOperation.h"
 
 namespace blender::compositor {
 
-class DisplaceOperation : public NodeOperation {
+class DisplaceOperation : public MultiThreadedOperation {
  private:
   /**
    * Cached reference to the inputProgram
    */
   SocketReader *m_inputColorProgram;
-  SocketReader *m_inputVectorProgram;
-  SocketReader *m_inputScaleXProgram;
-  SocketReader *m_inputScaleYProgram;
 
   float m_width_x4;
   float m_height_x4;
 
+  int input_vector_width_;
+  int input_vector_height_;
+
+  std::function<void(float x, float y, float *out)> vector_read_fn_;
+  std::function<void(float x, float y, float *out)> scale_x_read_fn_;
+  std::function<void(float x, float y, float *out)> scale_y_read_fn_;
+
  public:
   DisplaceOperation();
 
@@ -62,6 +66,14 @@ class DisplaceOperation : public NodeOperation {
    */
   void deinitExecution() override;
 
+  void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override;
+  void update_memory_buffer_started(MemoryBuffer *output,
+                                    const rcti &area,
+                                    Span<MemoryBuffer *> inputs) override;
+  void update_memory_buffer_partial(MemoryBuffer *output,
+                                    const rcti &area,
+                                    Span<MemoryBuffer *> inputs) override;
+
  private:
   bool read_displacement(
       float x, float y, float xscale, float yscale, const float origin[2], float &r_u, float &r_v);
diff --git a/source/blender/compositor/operations/COM_DisplaceSimpleOperation.cc b/source/blender/compositor/operations/COM_DisplaceSimpleOperation.cc
index f4b77f5d32c..e1c531bd49e 100644
--- a/source/blender/compositor/operations/COM_DisplaceSimpleOperation.cc
+++ b/source/blender/compositor/operations/COM_DisplaceSimpleOperation.cc
@@ -132,4 +132,56 @@ bool DisplaceSimpleOperation::determineDependingAreaOfInterest(rcti *input,
   return false;
 }
 
+void DisplaceSimpleOperation::get_area_of_interest(const int input_idx,
+                                                   const rcti &output_area,
+                                                   rcti &r_input_area)
+{
+  switch (input_idx) {
+    case 0: {
+      r_input_area.xmin = 0;
+      r_input_area.ymin = 0;
+      r_input_area.xmax = getInputOperation(input_idx)->getWidth();
+      r_input_area.ymax = getInputOperation(input_idx)->getHeight();
+      break;
+    }
+    default: {
+      r_input_area = output_area;
+      break;
+    }
+  }
+}
+
+void DisplaceSimpleOperation::update_memory_buffer_partial(MemoryBuffer *output,
+                                                           const rcti &area,
+                                                           Span<MemoryBuffer *> inputs)
+{
+  const float width = this->getWidth();
+  const float height = this->getHeight();
+  const MemoryBuffer *input_color = inputs[0];
+  for (BuffersIterator<float> it = output->iterate_with(inputs.drop_front(1), area); !it.is_end();
+       ++it) {
+    float scale_x = *it.in(1);
+    float scale_y = *it.in(2);
+
+    /* Clamp x and y displacement to triple image resolution -
+     * to prevent hangs from huge values mistakenly plugged in eg. z buffers. */
+    CLAMP(scale_x, -m_width_x4, m_width_x4);
+    CLAMP(scale_y, -m_height_x4, m_height_x4);
+
+    /* Main displacement in pixel space. */
+    const float *vector = it.in(0);
+    const float p_dx = vector[0] * scale_x;
+    const float p_dy = vector[1] * scale_y;
+
+    /* Displaced pixel in uv coords, for image sampling. */
+    /* Clamp nodes to avoid glitches. */
+    float u = it.x - p_dx + 0.5f;
+    float v = it.y - p_dy + 0.5f;
+    CLAMP(u, 0.0f, width - 1.0f);
+    CLAMP(v, 0.0f, height - 1.0f);
+
+    input_color->read_elem_checked(u, v, it.out);
+  }
+}
+
 }  // namespace blender::compositor
diff --git a/source/blender/compositor/operations/COM_DisplaceSimpleOperati

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list