[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