[Bf-blender-cvs] [b02069ef4da] compositor-full-frame: Compositor: Sample single elem buffers at borders

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


Commit: b02069ef4da254814e4c35a260349885dea797d3
Author: Manuel Castilla
Date:   Tue Aug 3 20:48:45 2021 +0200
Branches: compositor-full-frame
https://developer.blender.org/rBb02069ef4da254814e4c35a260349885dea797d3

Compositor: Sample single elem buffers at borders

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

M	source/blender/compositor/intern/COM_MemoryBuffer.cc
M	source/blender/compositor/intern/COM_MemoryBuffer.h

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

diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.cc b/source/blender/compositor/intern/COM_MemoryBuffer.cc
index 6a019a01b81..4edd5c783f6 100644
--- a/source/blender/compositor/intern/COM_MemoryBuffer.cc
+++ b/source/blender/compositor/intern/COM_MemoryBuffer.cc
@@ -415,32 +415,28 @@ void MemoryBuffer::read_elem_filtered(
     const float x, const float y, float dx[2], float dy[2], float *out) const
 {
   BLI_assert(this->m_datatype == DataType::Color);
-  if (m_is_a_single_elem) {
-    read_elem_checked(x, y, out);
-  }
-  else {
-    const float deriv[2][2] = {{dx[0], dx[1]}, {dy[0], dy[1]}};
-
-    float inv_width = 1.0f / (float)this->getWidth(), inv_height = 1.0f / (float)this->getHeight();
-    /* TODO(sergey): Render pipeline uses normalized coordinates and derivatives,
-     * but compositor uses pixel space. For now let's just divide the values and
-     * switch compositor to normalized space for EWA later.
-     */
-    float uv_normal[2] = {get_relative_x(x) * inv_width, get_relative_y(y) * inv_height};
-    float du_normal[2] = {deriv[0][0] * inv_width, deriv[0][1] * inv_height};
-    float dv_normal[2] = {deriv[1][0] * inv_width, deriv[1][1] * inv_height};
 
-    BLI_ewa_filter(this->getWidth(),
-                   this->getHeight(),
-                   false,
-                   true,
-                   uv_normal,
-                   du_normal,
-                   dv_normal,
-                   read_ewa_elem,
-                   const_cast<MemoryBuffer *>(this),
-                   out);
-  }
+  const float deriv[2][2] = {{dx[0], dx[1]}, {dy[0], dy[1]}};
+
+  float inv_width = 1.0f / (float)this->getWidth(), inv_height = 1.0f / (float)this->getHeight();
+  /* TODO(sergey): Render pipeline uses normalized coordinates and derivatives,
+   * but compositor uses pixel space. For now let's just divide the values and
+   * switch compositor to normalized space for EWA later.
+   */
+  float uv_normal[2] = {get_relative_x(x) * inv_width, get_relative_y(y) * inv_height};
+  float du_normal[2] = {deriv[0][0] * inv_width, deriv[0][1] * inv_height};
+  float dv_normal[2] = {deriv[1][0] * inv_width, deriv[1][1] * inv_height};
+
+  BLI_ewa_filter(this->getWidth(),
+                 this->getHeight(),
+                 false,
+                 true,
+                 uv_normal,
+                 du_normal,
+                 dv_normal,
+                 read_ewa_elem,
+                 const_cast<MemoryBuffer *>(this),
+                 out);
 }
 
 /* TODO(manzanilla): To be removed with tiled implementation. */
diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.h b/source/blender/compositor/intern/COM_MemoryBuffer.h
index e73b8803b53..4e27338eea1 100644
--- a/source/blender/compositor/intern/COM_MemoryBuffer.h
+++ b/source/blender/compositor/intern/COM_MemoryBuffer.h
@@ -216,6 +216,7 @@ class MemoryBuffer {
 
   void read_elem_bilinear(float x, float y, float *out) const
   {
+    /* Only clear past +/-1 borders to be able to smooth edges. */
     if (x <= m_rect.xmin - 1.0f || x >= m_rect.xmax || y <= m_rect.ymin - 1.0f ||
         y >= m_rect.ymax) {
       clear_elem(out);
@@ -223,17 +224,44 @@ class MemoryBuffer {
     }
 
     if (m_is_a_single_elem) {
-      read_elem_checked(x, y, out);
-    }
-    else {
-      BLI_bilinear_interpolation_fl(m_buffer,
-                                    out,
-                                    getWidth(),
-                                    getHeight(),
-                                    m_num_channels,
-                                    get_relative_x(x),
-                                    get_relative_y(y));
+      if (x >= m_rect.xmin && x < m_rect.xmax - 1.0f && y >= m_rect.ymin &&
+          y < m_rect.ymax - 1.0f) {
+        memcpy(out, m_buffer, get_elem_bytes_len());
+        return;
+      }
+
+      /* Do sampling at borders to smooth edges. */
+      const float last_x = getWidth() - 1.0f;
+      const float rel_x = get_relative_x(x);
+      float single_x = 0.0f;
+      if (rel_x < 0.0f) {
+        single_x = rel_x;
+      }
+      else if (rel_x > last_x) {
+        single_x = rel_x - last_x;
+      }
+
+      const float last_y = getHeight() - 1.0f;
+      const float rel_y = get_relative_y(y);
+      float single_y = 0.0f;
+      if (rel_y < 0.0f) {
+        single_y = rel_y;
+      }
+      else if (rel_y > last_y) {
+        single_y = rel_y - last_y;
+      }
+
+      BLI_bilinear_interpolation_fl(m_buffer, out, 1, 1, m_num_channels, single_x, single_y);
+      return;
     }
+
+    BLI_bilinear_interpolation_fl(m_buffer,
+                                  out,
+                                  getWidth(),
+                                  getHeight(),
+                                  m_num_channels,
+                                  get_relative_x(x),
+                                  get_relative_y(y));
   }
 
   void read_elem_sampled(float x, float y, PixelSampler sampler, float *out) const



More information about the Bf-blender-cvs mailing list