[Bf-blender-cvs] [c84a294c661] compositor-full-frame: Compositor: Full frame Lens Distortion node

Manuel Castilla noreply at git.blender.org
Wed Aug 4 23:03:39 CEST 2021


Commit: c84a294c66179ba412040d194e04dbc3d7525b64
Author: Manuel Castilla
Date:   Wed Aug 4 10:38:51 2021 +0200
Branches: compositor-full-frame
https://developer.blender.org/rBc84a294c66179ba412040d194e04dbc3d7525b64

Compositor: Full frame Lens Distortion node

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

M	source/blender/compositor/COM_defines.h
M	source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cc
M	source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h
M	source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cc
M	source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h

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

diff --git a/source/blender/compositor/COM_defines.h b/source/blender/compositor/COM_defines.h
index 900f29db44c..d0daf53ba22 100644
--- a/source/blender/compositor/COM_defines.h
+++ b/source/blender/compositor/COM_defines.h
@@ -113,6 +113,8 @@ constexpr float COM_PREVIEW_SIZE = 140.f;
 constexpr float COM_RULE_OF_THIRDS_DIVIDER = 100.0f;
 constexpr float COM_BLUR_BOKEH_PIXELS = 512;
 
+constexpr rcti COM_SINGLE_ELEM_AREA = {0, 1, 0, 1};
+
 constexpr IndexRange XRange(const rcti &area)
 {
   return IndexRange(area.xmin, area.xmax - area.xmin);
diff --git a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cc b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cc
index 93702d3f0cf..fcab5dd5751 100644
--- a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cc
+++ b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cc
@@ -17,6 +17,8 @@
  */
 
 #include "COM_ProjectorLensDistortionOperation.h"
+#include "COM_ConstantOperation.h"
+
 #include "BLI_math.h"
 #include "BLI_utildefines.h"
 
@@ -32,6 +34,20 @@ ProjectorLensDistortionOperation::ProjectorLensDistortionOperation()
   this->m_dispersionAvailable = false;
   this->m_dispersion = 0.0f;
 }
+
+void ProjectorLensDistortionOperation::init_data()
+{
+  if (execution_model_ == eExecutionModel::FullFrame) {
+    NodeOperation *dispersion_input = get_input_operation(1);
+    if (dispersion_input->get_flags().is_constant_operation) {
+      this->m_dispersion =
+          static_cast<ConstantOperation *>(dispersion_input)->get_constant_elem()[0];
+    }
+    this->m_kr = 0.25f * max_ff(min_ff(this->m_dispersion, 1.0f), 0.0f);
+    this->m_kr2 = this->m_kr * 20;
+  }
+}
+
 void ProjectorLensDistortionOperation::initExecution()
 {
   this->initMutex();
@@ -97,6 +113,7 @@ bool ProjectorLensDistortionOperation::determineDependingAreaOfInterest(
   return false;
 }
 
+/* TODO(manzanilla): to be removed with tiled implementation. */
 void ProjectorLensDistortionOperation::updateDispersion()
 {
   if (this->m_dispersionAvailable) {
@@ -114,4 +131,41 @@ void ProjectorLensDistortionOperation::updateDispersion()
   this->unlockMutex();
 }
 
+void ProjectorLensDistortionOperation::get_area_of_interest(const int input_idx,
+                                                            const rcti &output_area,
+                                                            rcti &r_input_area)
+{
+  if (input_idx == 1) {
+    /* Dispersion input is used as constant only. */
+    r_input_area = COM_SINGLE_ELEM_AREA;
+    return;
+  }
+
+  r_input_area.ymax = output_area.ymax;
+  r_input_area.ymin = output_area.ymin;
+  r_input_area.xmin = output_area.xmin - this->m_kr2 - 2;
+  r_input_area.xmax = output_area.xmax + this->m_kr2 + 2;
+}
+
+void ProjectorLensDistortionOperation::update_memory_buffer_partial(MemoryBuffer *output,
+                                                                    const rcti &area,
+                                                                    Span<MemoryBuffer *> inputs)
+{
+  const MemoryBuffer *input_image = inputs[0];
+  const float height = this->getHeight();
+  const float width = this->getWidth();
+  float color[4];
+  for (BuffersIterator<float> it = output->iterate_with({}, area); !it.is_end(); ++it) {
+    const float v = (it.y + 0.5f) / height;
+    const float u = (it.x + 0.5f) / width;
+    input_image->read_elem_bilinear((u * width + this->m_kr2) - 0.5f, v * height - 0.5f, color);
+    it.out[0] = color[0];
+    input_image->read_elem(it.x, it.y, color);
+    it.out[1] = color[1];
+    input_image->read_elem_bilinear((u * width - this->m_kr2) - 0.5f, v * height - 0.5f, color);
+    it.out[2] = color[2];
+    it.out[3] = 1.0f;
+  }
+}
+
 }  // namespace blender::compositor
diff --git a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h
index bce61d3de15..7c7626bf271 100644
--- a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h
+++ b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h
@@ -18,12 +18,12 @@
 
 #pragma once
 
-#include "COM_NodeOperation.h"
+#include "COM_MultiThreadedOperation.h"
 #include "DNA_node_types.h"
 
 namespace blender::compositor {
 
-class ProjectorLensDistortionOperation : public NodeOperation {
+class ProjectorLensDistortionOperation : public MultiThreadedOperation {
  private:
   /**
    * Cached reference to the inputProgram
@@ -31,6 +31,7 @@ class ProjectorLensDistortionOperation : public NodeOperation {
   SocketReader *m_inputProgram;
 
   float m_dispersion;
+  /* TODO(manzanilla): to be removed with tiled implementation. */
   bool m_dispersionAvailable;
 
   float m_kr, m_kr2;
@@ -43,6 +44,7 @@ class ProjectorLensDistortionOperation : public NodeOperation {
    */
   void executePixel(float output[4], int x, int y, void *data) override;
 
+  void init_data() override;
   /**
    * Initialize the execution
    */
@@ -59,6 +61,11 @@ class ProjectorLensDistortionOperation : public NodeOperation {
                                         rcti *output) override;
 
   void updateDispersion();
+
+  void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override;
+  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_ScreenLensDistortionOperation.cc b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cc
index 634fe66b0dd..4741104b8f0 100644
--- a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cc
+++ b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cc
@@ -17,6 +17,7 @@
  */
 
 #include "COM_ScreenLensDistortionOperation.h"
+#include "COM_ConstantOperation.h"
 
 #include "BLI_math.h"
 #include "BLI_rand.h"
@@ -53,6 +54,35 @@ void ScreenLensDistortionOperation::setDispersion(float dispersion)
   m_dispersion_const = true;
 }
 
+void ScreenLensDistortionOperation::init_data()
+{
+  this->m_cx = 0.5f * (float)getWidth();
+  this->m_cy = 0.5f * (float)getHeight();
+
+  switch (execution_model_) {
+    case eExecutionModel::FullFrame: {
+      NodeOperation *distortion_op = get_input_operation(1);
+      NodeOperation *dispersion_op = get_input_operation(2);
+      if (!m_distortion_const && distortion_op->get_flags().is_constant_operation) {
+        m_distortion = static_cast<ConstantOperation *>(distortion_op)->get_constant_elem()[0];
+      }
+      if (!m_dispersion_const && distortion_op->get_flags().is_constant_operation) {
+        m_dispersion = static_cast<ConstantOperation *>(dispersion_op)->get_constant_elem()[0];
+      }
+      updateVariables(m_distortion, m_dispersion);
+      break;
+    }
+    case eExecutionModel::Tiled: {
+      /* If both are constant, init variables once. */
+      if (m_distortion_const && m_dispersion_const) {
+        updateVariables(m_distortion, m_dispersion);
+        m_variables_ready = true;
+      }
+      break;
+    }
+  }
+}
+
 void ScreenLensDistortionOperation::initExecution()
 {
   this->m_inputProgram = this->getInputSocketReader(0);
@@ -61,15 +91,6 @@ void ScreenLensDistortionOperation::initExecution()
   uint rng_seed = (uint)(PIL_check_seconds_timer_i() & UINT_MAX);
   rng_seed ^= (uint)POINTER_AS_INT(m_inputProgram);
   this->m_rng = BLI_rng_new(rng_seed);
-
-  this->m_cx = 0.5f * (float)getWidth();
-  this->m_cy = 0.5f * (float)getHeight();
-
-  /* if both are constant, init variables once */
-  if (m_distortion_const && m_dispersion_const) {
-    updateVariables(m_distortion, m_dispersion);
-    m_variables_ready = true;
-  }
 }
 
 void *ScreenLensDistortionOperation::initializeTileData(rcti * /*rect*/)
@@ -130,7 +151,7 @@ bool ScreenLensDistortionOperation::get_delta(float r_sq,
   return false;
 }
 
-void ScreenLensDistortionOperation::accumulate(MemoryBuffer *buffer,
+void ScreenLensDistortionOperation::accumulate(const MemoryBuffer *buffer,
                                                int a,
                                                int b,
                                                float r_sq,
@@ -154,7 +175,14 @@ void ScreenLensDistortionOperation::accumulate(MemoryBuffer *buffer,
 
     float xy[2];
     distort_uv(uv, t, xy);
-    buffer->readBilinear(color, xy[0], xy[1]);
+    switch (execution_model_) {
+      case eExecutionModel::Tiled:
+        buffer->readBilinear(color, xy[0], xy[1]);
+        break;
+      case eExecutionModel::FullFrame:
+        buffer->read_elem_bilinear(xy[0], xy[1], color);
+        break;
+    }
 
     sum[a] += (1.0f - tz) * color[a];
     sum[b] += (tz)*color[b];
@@ -354,4 +382,146 @@ void ScreenLensDistortionOperation::updateVariables(float distortion, float disp
   mul_v3_v3fl(m_k4, m_k, 4.0f);
 }
 
+void ScreenLensDistortionOperation::get_area_of_interest(const int input_idx,
+                                                         const rcti &output_area,
+                                                         rcti &r_input_area)
+{
+  if (input_idx != 0) {
+    /* Dispersion and distorsion inputs are used as constants only. */
+    r_input_area.xmin = output_area.xmin;
+    r_input_area.ymin = output_area.ymin;
+    r_input_area.xmax = output_area.xmin + 1;
+    r_input_area.ymax = output_area.ymin + 1;
+  }
+
+  /* XXX the original method of estimating the area-of-interest does not work
+   * it assumes a linear increase/decrease of mapped coordinates, which does not
+   * yield correct results for the area and leaves uninitialized buffer areas.
+   * So now just use the full image area, which may not be as efficient but works at least ...
+   */
+#if 1
+  NodeOperation *image = getInputOperation(0);
+  r_input_area.xmax = image->getWidth();
+  r_input_area.xmin = 0;
+  r_input_area.ymax = image->getHeight();
+  r_input_area.ymin = 0;
+
+#else /* Original method in tiled implementation. */
+  rcti newInput;
+  const float margin = 2;
+
+  BLI_rcti_init_minmax(&ne

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list