[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