[Bf-blender-cvs] [daa7c59e38c] master: Compositor: Full frame Bokeh Blur and Blur nodes

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


Commit: daa7c59e38c8fe464004b3becd6956b880c38c92
Author: Manuel Castilla
Date:   Mon Aug 23 15:30:31 2021 +0200
Branches: master
https://developer.blender.org/rBdaa7c59e38c8fe464004b3becd6956b880c38c92

Compositor: Full frame Bokeh Blur and Blur nodes

Adds full frame implementation to these nodes operations.

When enabling "extend bounds" node option, tiled implementation
result is slightly different because it's using `TranslateOperation`
with bilinear sampling for centering.
Full frame always uses nearest to don't lose image quality.
It has the disadvantage of causing image jiggling on backdrop
when switching size values as it's not pixel perfect.
This is fixed by rounding to even.

No functional changes.

Part of T88150.

Reviewed By: jbakker

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

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

M	source/blender/blenlib/BLI_math_base.h
M	source/blender/blenlib/intern/math_base_inline.c
M	source/blender/compositor/CMakeLists.txt
M	source/blender/compositor/COM_defines.h
M	source/blender/compositor/intern/COM_NodeOperation.cc
M	source/blender/compositor/intern/COM_NodeOperation.h
M	source/blender/compositor/operations/COM_BlurBaseOperation.cc
M	source/blender/compositor/operations/COM_BlurBaseOperation.h
M	source/blender/compositor/operations/COM_BokehBlurOperation.cc
M	source/blender/compositor/operations/COM_BokehBlurOperation.h
M	source/blender/compositor/operations/COM_FastGaussianBlurOperation.cc
M	source/blender/compositor/operations/COM_FastGaussianBlurOperation.h
M	source/blender/compositor/operations/COM_GammaCorrectOperation.cc
M	source/blender/compositor/operations/COM_GammaCorrectOperation.h
A	source/blender/compositor/operations/COM_GaussianAlphaBlurBaseOperation.cc
A	source/blender/compositor/operations/COM_GaussianAlphaBlurBaseOperation.h
M	source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cc
M	source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h
M	source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cc
M	source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h
A	source/blender/compositor/operations/COM_GaussianBlurBaseOperation.cc
A	source/blender/compositor/operations/COM_GaussianBlurBaseOperation.h
M	source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cc
M	source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h
M	source/blender/compositor/operations/COM_GaussianXBlurOperation.cc
M	source/blender/compositor/operations/COM_GaussianXBlurOperation.h
M	source/blender/compositor/operations/COM_GaussianYBlurOperation.cc
M	source/blender/compositor/operations/COM_GaussianYBlurOperation.h
M	source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cc
M	source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h

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

diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h
index e877503e835..dbdd28766a5 100644
--- a/source/blender/blenlib/BLI_math_base.h
+++ b/source/blender/blenlib/BLI_math_base.h
@@ -196,6 +196,8 @@ MINLINE unsigned int log2_ceil_u(unsigned int x);
 MINLINE int divide_round_i(int a, int b);
 MINLINE int mod_i(int i, int n);
 
+MINLINE float round_to_even(float f);
+
 MINLINE signed char round_fl_to_char(float a);
 MINLINE unsigned char round_fl_to_uchar(float a);
 MINLINE short round_fl_to_short(float a);
diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c
index a80c495ecf3..983fd3b6543 100644
--- a/source/blender/blenlib/intern/math_base_inline.c
+++ b/source/blender/blenlib/intern/math_base_inline.c
@@ -363,6 +363,14 @@ MINLINE signed char round_db_to_char_clamp(double a){
 #undef _round_clamp_fl_impl
 #undef _round_clamp_db_impl
 
+/**
+ * Round to closest even number, halfway cases are rounded away from zero.
+ */
+MINLINE float round_to_even(float f)
+{
+  return roundf(f * 0.5f) * 2.0f;
+}
+
 /* integer division that rounds 0.5 up, particularly useful for color blending
  * with integers, to avoid gradual darkening when rounding down */
 MINLINE int divide_round_i(int a, int b)
diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt
index dba2d1e1e67..8ddcf11602a 100644
--- a/source/blender/compositor/CMakeLists.txt
+++ b/source/blender/compositor/CMakeLists.txt
@@ -328,10 +328,14 @@ set(SRC
   operations/COM_FastGaussianBlurOperation.h
   operations/COM_GammaCorrectOperation.cc
   operations/COM_GammaCorrectOperation.h
+  operations/COM_GaussianAlphaBlurBaseOperation.cc
+  operations/COM_GaussianAlphaBlurBaseOperation.h
   operations/COM_GaussianAlphaXBlurOperation.cc
   operations/COM_GaussianAlphaXBlurOperation.h
   operations/COM_GaussianAlphaYBlurOperation.cc
   operations/COM_GaussianAlphaYBlurOperation.h
+  operations/COM_GaussianBlurBaseOperation.cc
+  operations/COM_GaussianBlurBaseOperation.h
   operations/COM_GaussianBokehBlurOperation.cc
   operations/COM_GaussianBokehBlurOperation.h
   operations/COM_GaussianXBlurOperation.cc
diff --git a/source/blender/compositor/COM_defines.h b/source/blender/compositor/COM_defines.h
index ee9bea7b2c6..e270eeb3386 100644
--- a/source/blender/compositor/COM_defines.h
+++ b/source/blender/compositor/COM_defines.h
@@ -33,6 +33,8 @@ enum class eExecutionModel {
   FullFrame
 };
 
+enum class eDimension { X, Y };
+
 /**
  * \brief possible data types for sockets
  * \ingroup Model
diff --git a/source/blender/compositor/intern/COM_NodeOperation.cc b/source/blender/compositor/intern/COM_NodeOperation.cc
index 575e8446abe..1b87cdf72fb 100644
--- a/source/blender/compositor/intern/COM_NodeOperation.cc
+++ b/source/blender/compositor/intern/COM_NodeOperation.cc
@@ -82,8 +82,12 @@ void NodeOperation::determineResolution(unsigned int resolution[2],
     input.determineResolution(resolution, preferredResolution);
     used_resolution_index = m_resolutionInputSocketIndex;
   }
-  unsigned int temp2[2] = {resolution[0], resolution[1]};
 
+  if (modify_determined_resolution_fn_) {
+    modify_determined_resolution_fn_(resolution);
+  }
+
+  unsigned int temp2[2] = {resolution[0], resolution[1]};
   unsigned int temp[2];
   for (unsigned int index = 0; index < m_inputs.size(); index++) {
     if (index == used_resolution_index) {
diff --git a/source/blender/compositor/intern/COM_NodeOperation.h b/source/blender/compositor/intern/COM_NodeOperation.h
index 934007d25ce..b402dc7f174 100644
--- a/source/blender/compositor/intern/COM_NodeOperation.h
+++ b/source/blender/compositor/intern/COM_NodeOperation.h
@@ -287,6 +287,8 @@ class NodeOperation {
    */
   unsigned int m_resolutionInputSocketIndex;
 
+  std::function<void(unsigned int resolution[2])> modify_determined_resolution_fn_;
+
   /**
    * \brief mutex reference for very special node initializations
    * \note only use when you really know what you are doing.
@@ -517,6 +519,15 @@ class NodeOperation {
    */
   void setResolutionInputSocketIndex(unsigned int index);
 
+  /**
+   * Set a custom function to modify determined resolution from main input just before setting it
+   * as preferred resolution for the other inputs.
+   */
+  void set_determined_resolution_modifier(std::function<void(unsigned int resolution[2])> fn)
+  {
+    modify_determined_resolution_fn_ = fn;
+  }
+
   /**
    * \brief get the render priority of this node.
    * \note only applicable for output operations like ViewerOperation
diff --git a/source/blender/compositor/operations/COM_BlurBaseOperation.cc b/source/blender/compositor/operations/COM_BlurBaseOperation.cc
index 8b73624ca79..280a6026ebe 100644
--- a/source/blender/compositor/operations/COM_BlurBaseOperation.cc
+++ b/source/blender/compositor/operations/COM_BlurBaseOperation.cc
@@ -17,6 +17,8 @@
  */
 
 #include "COM_BlurBaseOperation.h"
+#include "COM_ConstantOperation.h"
+
 #include "BLI_math.h"
 #include "MEM_guardedalloc.h"
 
@@ -36,11 +38,15 @@ BlurBaseOperation::BlurBaseOperation(DataType data_type)
   this->m_size = 1.0f;
   this->m_sizeavailable = false;
   this->m_extend_bounds = false;
+  use_variable_size_ = false;
 }
-void BlurBaseOperation::initExecution()
+
+void BlurBaseOperation::init_data()
 {
-  this->m_inputProgram = this->getInputSocketReader(0);
-  this->m_inputSize = this->getInputSocketReader(1);
+  if (execution_model_ == eExecutionModel::FullFrame) {
+    updateSize();
+  }
+
   this->m_data.image_in_width = this->getWidth();
   this->m_data.image_in_height = this->getHeight();
   if (this->m_data.relative) {
@@ -61,6 +67,12 @@ void BlurBaseOperation::initExecution()
     this->m_data.sizex = round_fl_to_int(this->m_data.percentx * 0.01f * sizex);
     this->m_data.sizey = round_fl_to_int(this->m_data.percenty * 0.01f * sizey);
   }
+}
+
+void BlurBaseOperation::initExecution()
+{
+  this->m_inputProgram = this->getInputSocketReader(0);
+  this->m_inputSize = this->getInputSocketReader(1);
 
   QualityStepHelper::initExecution(COM_QH_MULTIPLY);
 }
@@ -165,23 +177,82 @@ void BlurBaseOperation::setData(const NodeBlurData *data)
   memcpy(&m_data, data, sizeof(NodeBlurData));
 }
 
+int BlurBaseOperation::get_blur_size(eDimension dim) const
+{
+  switch (dim) {
+    case eDimension::X:
+      return m_data.sizex;
+    case eDimension::Y:
+      return m_data.sizey;
+  }
+  return -1;
+}
+
 void BlurBaseOperation::updateSize()
 {
-  if (!this->m_sizeavailable) {
-    float result[4];
-    this->getInputSocketReader(1)->readSampled(result, 0, 0, PixelSampler::Nearest);
-    this->m_size = result[0];
-    this->m_sizeavailable = true;
+  if (this->m_sizeavailable || use_variable_size_) {
+    return;
   }
+
+  switch (execution_model_) {
+    case eExecutionModel::Tiled: {
+      float result[4];
+      this->getInputSocketReader(1)->readSampled(result, 0, 0, PixelSampler::Nearest);
+      this->m_size = result[0];
+      break;
+    }
+    case eExecutionModel::FullFrame: {
+      NodeOperation *size_input = get_input_operation(SIZE_INPUT_INDEX);
+      if (size_input->get_flags().is_constant_operation) {
+        m_size = *static_cast<ConstantOperation *>(size_input)->get_constant_elem();
+      } /* Else use default. */
+      break;
+    }
+  }
+  this->m_sizeavailable = true;
 }
 
 void BlurBaseOperation::determineResolution(unsigned int resolution[2],
                                             unsigned int preferredResolution[2])
 {
-  NodeOperation::determineResolution(resolution, preferredResolution);
-  if (this->m_extend_bounds) {
-    resolution[0] += 2 * this->m_size * m_data.sizex;
-    resolution[1] += 2 * this->m_size * m_data.sizey;
+  if (!m_extend_bounds) {
+    NodeOperation::determineResolution(resolution, preferredResolution);
+    return;
+  }
+
+  switch (execution_model_) {
+    case eExecutionModel::Tiled: {
+      NodeOperation::determineResolution(resolution, preferredResolution);
+      resolution[0] += 2 * m_size * m_data.sizex;
+      resolution[1] += 2 * m_size * m_data.sizey;
+      break;
+    }
+    case eExecutionModel::FullFrame: {
+      /* Setting a modifier ensures all non main inputs have extended bounds as preferred
+       * resolution, avoiding unnecessary resolution convertions that would hide constant
+       * operations. */
+      set_determined_resolution_modifier([=](unsigned int res[2]) {
+        /* Rounding to even prevents jiggling in backdrop while switching size values. */
+        res[0] += round_to_even(2 * m_size * m_data.sizex);
+        res[1] += round_to_even(2 * m_size * m_data.sizey);
+      });
+      NodeOperation::determineResolution(resolution, preferredResolution);
+      break;
+    }
+  }
+}
+
+void BlurBaseOperation::get_area_of_interest(const int input_idx,
+                                             const rcti &output_area,
+                                             rcti &r_input_area)
+{
+  switch (input_idx) {
+    case 0:
+      r_input_area = output_area;
+      break;
+    case 1:
+      r_input_area = use_variable_size_ ? output_area : COM_SINGLE_ELEM_AREA;
+      break;
   }
 }
 
diff --git a/source/blender/compositor/operations/COM_BlurBaseOperation.h b/source/blender/compositor/operations/COM_BlurBaseOperation.h
index 7937ebd69dc..78b1e919aa6 100644
--- a/source/blender/compositor/operations/COM_BlurBaseOperation.h
+++ b/source/blender/compositor/operations/COM_BlurBaseOperation.h
@@ -18,7 +18,7 @@
 
 #pragma once
 
-#include "COM_NodeOperation.h"
+#include "COM_MultiThreadedOperation.h"
 #include "COM_QualityStepHelper.h"
 
 #define MAX_GAUSSTAB_RADIUS 30000
@@ -27,10 +27,16 @@
 
 namespace blender::compositor {
 
-class BlurBaseOperation : public NodeOperation, public QualityStepHelper {
+class BlurBaseOperation : public MultiThreadedOperation, public QualityStepHelper {
  private:
+  bool m_extend_bounds;
+
+ protected:
+  static constexpr int IMAGE_INPUT_INDEX = 0;
+  static constexpr int SIZE_INPUT_INDEX = 1;
+
  protected:
-  BlurBaseOperation(DataType data_type);
+  BlurBaseOperation(DataType data_type8);
   float *make_gausstab(float rad, int size);
 #ifdef BLI_HA

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list