Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/compositor/operations/COM_AlphaOverKeyOperation.cc30
-rw-r--r--source/blender/compositor/operations/COM_AlphaOverKeyOperation.h4
-rw-r--r--source/blender/compositor/operations/COM_AlphaOverMixedOperation.cc27
-rw-r--r--source/blender/compositor/operations/COM_AlphaOverMixedOperation.h2
-rw-r--r--source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cc29
-rw-r--r--source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h4
-rw-r--r--source/blender/compositor/operations/COM_ChangeHSVOperation.cc23
-rw-r--r--source/blender/compositor/operations/COM_ChangeHSVOperation.h8
-rw-r--r--source/blender/compositor/operations/COM_InvertOperation.cc28
-rw-r--r--source/blender/compositor/operations/COM_InvertOperation.h8
-rw-r--r--source/blender/compositor/operations/COM_TonemapOperation.cc124
-rw-r--r--source/blender/compositor/operations/COM_TonemapOperation.h16
-rw-r--r--source/blender/compositor/operations/COM_ZCombineOperation.cc70
-rw-r--r--source/blender/compositor/operations/COM_ZCombineOperation.h20
14 files changed, 385 insertions, 8 deletions
diff --git a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cc b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cc
index 0c656753a51..30e7fab4027 100644
--- a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cc
+++ b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cc
@@ -20,6 +20,11 @@
namespace blender::compositor {
+AlphaOverKeyOperation::AlphaOverKeyOperation()
+{
+ this->flags.can_be_constant = true;
+}
+
void AlphaOverKeyOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -50,4 +55,29 @@ void AlphaOverKeyOperation::executePixelSampled(float output[4],
}
}
+void AlphaOverKeyOperation::update_memory_buffer_row(PixelCursor &p)
+{
+ for (; p.out < p.row_end; p.next()) {
+ const float *color1 = p.color1;
+ const float *over_color = p.color2;
+ const float value = *p.value;
+
+ if (over_color[3] <= 0.0f) {
+ copy_v4_v4(p.out, color1);
+ }
+ else if (value == 1.0f && over_color[3] >= 1.0f) {
+ copy_v4_v4(p.out, over_color);
+ }
+ else {
+ const float premul = value * over_color[3];
+ const float mul = 1.0f - premul;
+
+ p.out[0] = (mul * color1[0]) + premul * over_color[0];
+ p.out[1] = (mul * color1[1]) + premul * over_color[1];
+ p.out[2] = (mul * color1[2]) + premul * over_color[2];
+ p.out[3] = (mul * color1[3]) + value * over_color[3];
+ }
+ }
+}
+
} // namespace blender::compositor
diff --git a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h
index 83713d18971..960fbc98fe9 100644
--- a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h
+++ b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.h
@@ -28,10 +28,14 @@ namespace blender::compositor {
*/
class AlphaOverKeyOperation : public MixBaseOperation {
public:
+ AlphaOverKeyOperation();
+
/**
* The inner loop of this operation.
*/
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
+
+ void update_memory_buffer_row(PixelCursor &p) override;
};
} // namespace blender::compositor
diff --git a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cc b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cc
index c68c79d2263..0cc179ea209 100644
--- a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cc
+++ b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cc
@@ -23,6 +23,7 @@ namespace blender::compositor {
AlphaOverMixedOperation::AlphaOverMixedOperation()
{
this->m_x = 0.0f;
+ this->flags.can_be_constant = true;
}
void AlphaOverMixedOperation::executePixelSampled(float output[4],
@@ -56,4 +57,30 @@ void AlphaOverMixedOperation::executePixelSampled(float output[4],
}
}
+void AlphaOverMixedOperation::update_memory_buffer_row(PixelCursor &p)
+{
+ for (; p.out < p.row_end; p.next()) {
+ const float *color1 = p.color1;
+ const float *over_color = p.color2;
+ const float value = *p.value;
+
+ if (over_color[3] <= 0.0f) {
+ copy_v4_v4(p.out, color1);
+ }
+ else if (value == 1.0f && over_color[3] >= 1.0f) {
+ copy_v4_v4(p.out, over_color);
+ }
+ else {
+ const float addfac = 1.0f - this->m_x + over_color[3] * this->m_x;
+ const float premul = value * addfac;
+ const float mul = 1.0f - value * over_color[3];
+
+ p.out[0] = (mul * color1[0]) + premul * over_color[0];
+ p.out[1] = (mul * color1[1]) + premul * over_color[1];
+ p.out[2] = (mul * color1[2]) + premul * over_color[2];
+ p.out[3] = (mul * color1[3]) + value * over_color[3];
+ }
+ }
+}
+
} // namespace blender::compositor
diff --git a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h
index e2b3af84162..2b88cd5f421 100644
--- a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h
+++ b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.h
@@ -45,6 +45,8 @@ class AlphaOverMixedOperation : public MixBaseOperation {
{
this->m_x = x;
}
+
+ void update_memory_buffer_row(PixelCursor &p) override;
};
} // namespace blender::compositor
diff --git a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cc b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cc
index 3dd4607e273..a57e8c7f8a3 100644
--- a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cc
+++ b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cc
@@ -20,6 +20,11 @@
namespace blender::compositor {
+AlphaOverPremultiplyOperation::AlphaOverPremultiplyOperation()
+{
+ this->flags.can_be_constant = true;
+}
+
void AlphaOverPremultiplyOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -50,4 +55,28 @@ void AlphaOverPremultiplyOperation::executePixelSampled(float output[4],
}
}
+void AlphaOverPremultiplyOperation::update_memory_buffer_row(PixelCursor &p)
+{
+ for (; p.out < p.row_end; p.next()) {
+ const float *color1 = p.color1;
+ const float *over_color = p.color2;
+ const float value = *p.value;
+
+ if (over_color[3] <= 0.0f) {
+ copy_v4_v4(p.out, color1);
+ }
+ else if (value == 1.0f && over_color[3] >= 1.0f) {
+ copy_v4_v4(p.out, over_color);
+ }
+ else {
+ const float mul = 1.0f - value * over_color[3];
+
+ p.out[0] = (mul * color1[0]) + value * over_color[0];
+ p.out[1] = (mul * color1[1]) + value * over_color[1];
+ p.out[2] = (mul * color1[2]) + value * over_color[2];
+ p.out[3] = (mul * color1[3]) + value * over_color[3];
+ }
+ }
+}
+
} // namespace blender::compositor
diff --git a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h
index f1d4b668fce..701bc07cc27 100644
--- a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h
+++ b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h
@@ -28,10 +28,14 @@ namespace blender::compositor {
*/
class AlphaOverPremultiplyOperation : public MixBaseOperation {
public:
+ AlphaOverPremultiplyOperation();
+
/**
* The inner loop of this operation.
*/
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
+
+ void update_memory_buffer_row(PixelCursor &p) override;
};
} // namespace blender::compositor
diff --git a/source/blender/compositor/operations/COM_ChangeHSVOperation.cc b/source/blender/compositor/operations/COM_ChangeHSVOperation.cc
index eee007ce9e6..1e3e7806968 100644
--- a/source/blender/compositor/operations/COM_ChangeHSVOperation.cc
+++ b/source/blender/compositor/operations/COM_ChangeHSVOperation.cc
@@ -28,6 +28,7 @@ ChangeHSVOperation::ChangeHSVOperation()
this->addInputSocket(DataType::Value);
this->addOutputSocket(DataType::Color);
this->m_inputOperation = nullptr;
+ this->flags.can_be_constant = true;
}
void ChangeHSVOperation::initExecution()
@@ -71,4 +72,26 @@ void ChangeHSVOperation::executePixelSampled(float output[4],
output[3] = inputColor1[3];
}
+void ChangeHSVOperation::update_memory_buffer_partial(MemoryBuffer *output,
+ const rcti &area,
+ Span<MemoryBuffer *> inputs)
+{
+ for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) {
+ const float *color = it.in(0);
+ const float hue = *it.in(1);
+ it.out[0] = color[0] + (hue - 0.5f);
+ if (it.out[0] > 1.0f) {
+ it.out[0] -= 1.0f;
+ }
+ else if (it.out[0] < 0.0f) {
+ it.out[0] += 1.0f;
+ }
+ const float saturation = *it.in(2);
+ const float value = *it.in(3);
+ it.out[1] = color[1] * saturation;
+ it.out[2] = color[2] * value;
+ it.out[3] = color[3];
+ }
+}
+
} // namespace blender::compositor
diff --git a/source/blender/compositor/operations/COM_ChangeHSVOperation.h b/source/blender/compositor/operations/COM_ChangeHSVOperation.h
index d38b4be3efe..e7bc3274f25 100644
--- a/source/blender/compositor/operations/COM_ChangeHSVOperation.h
+++ b/source/blender/compositor/operations/COM_ChangeHSVOperation.h
@@ -18,7 +18,7 @@
#pragma once
-#include "COM_MixOperation.h"
+#include "COM_MultiThreadedOperation.h"
namespace blender::compositor {
@@ -26,7 +26,7 @@ namespace blender::compositor {
* this program converts an input color to an output value.
* it assumes we are in sRGB color space.
*/
-class ChangeHSVOperation : public NodeOperation {
+class ChangeHSVOperation : public MultiThreadedOperation {
private:
SocketReader *m_inputOperation;
SocketReader *m_hueOperation;
@@ -46,6 +46,10 @@ class ChangeHSVOperation : public NodeOperation {
* The inner loop of this operation.
*/
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) 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_InvertOperation.cc b/source/blender/compositor/operations/COM_InvertOperation.cc
index 339e40a5d1f..4f71a1d0d1d 100644
--- a/source/blender/compositor/operations/COM_InvertOperation.cc
+++ b/source/blender/compositor/operations/COM_InvertOperation.cc
@@ -30,6 +30,7 @@ InvertOperation::InvertOperation()
this->m_color = true;
this->m_alpha = false;
setResolutionInputSocketIndex(1);
+ this->flags.can_be_constant = true;
}
void InvertOperation::initExecution()
{
@@ -70,4 +71,31 @@ void InvertOperation::deinitExecution()
this->m_inputColorProgram = nullptr;
}
+void InvertOperation::update_memory_buffer_partial(MemoryBuffer *output,
+ const rcti &area,
+ Span<MemoryBuffer *> inputs)
+{
+ for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) {
+ const float value = *it.in(0);
+ const float inverted_value = 1.0f - value;
+ const float *color = it.in(1);
+
+ if (this->m_color) {
+ it.out[0] = (1.0f - color[0]) * value + color[0] * inverted_value;
+ it.out[1] = (1.0f - color[1]) * value + color[1] * inverted_value;
+ it.out[2] = (1.0f - color[2]) * value + color[2] * inverted_value;
+ }
+ else {
+ copy_v3_v3(it.out, color);
+ }
+
+ if (this->m_alpha) {
+ it.out[3] = (1.0f - color[3]) * value + color[3] * inverted_value;
+ }
+ else {
+ it.out[3] = color[3];
+ }
+ }
+}
+
} // namespace blender::compositor
diff --git a/source/blender/compositor/operations/COM_InvertOperation.h b/source/blender/compositor/operations/COM_InvertOperation.h
index 17e5eb95f3e..a084bf5d559 100644
--- a/source/blender/compositor/operations/COM_InvertOperation.h
+++ b/source/blender/compositor/operations/COM_InvertOperation.h
@@ -18,11 +18,11 @@
#pragma once
-#include "COM_NodeOperation.h"
+#include "COM_MultiThreadedOperation.h"
namespace blender::compositor {
-class InvertOperation : public NodeOperation {
+class InvertOperation : public MultiThreadedOperation {
private:
/**
* Cached reference to the inputProgram
@@ -59,6 +59,10 @@ class InvertOperation : public NodeOperation {
{
this->m_alpha = alpha;
}
+
+ 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_TonemapOperation.cc b/source/blender/compositor/operations/COM_TonemapOperation.cc
index 6bfacb0c75d..20da468eeb1 100644
--- a/source/blender/compositor/operations/COM_TonemapOperation.cc
+++ b/source/blender/compositor/operations/COM_TonemapOperation.cc
@@ -17,6 +17,8 @@
*/
#include "COM_TonemapOperation.h"
+#include "COM_ExecutionSystem.h"
+
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -153,4 +155,126 @@ void TonemapOperation::deinitializeTileData(rcti * /*rect*/, void * /*data*/)
/* pass */
}
+void TonemapOperation::get_area_of_interest(const int input_idx,
+ const rcti &UNUSED(output_area),
+ rcti &r_input_area)
+{
+ BLI_assert(input_idx == 0);
+ NodeOperation *operation = getInputOperation(input_idx);
+ r_input_area.xmin = 0;
+ r_input_area.ymin = 0;
+ r_input_area.xmax = operation->getWidth();
+ r_input_area.ymax = operation->getHeight();
+}
+
+struct Luminance {
+ float sum;
+ float color_sum[3];
+ float log_sum;
+ float min;
+ float max;
+ int num_pixels;
+};
+
+static Luminance calc_area_luminance(const MemoryBuffer *input, const rcti &area)
+{
+ Luminance lum = {0};
+ for (const float *elem : input->get_buffer_area(area)) {
+ const float lu = IMB_colormanagement_get_luminance(elem);
+ lum.sum += lu;
+ add_v3_v3(lum.color_sum, elem);
+ lum.log_sum += logf(MAX2(lu, 0.0f) + 1e-5f);
+ lum.max = MAX2(lu, lum.max);
+ lum.min = MIN2(lu, lum.min);
+ lum.num_pixels++;
+ }
+ return lum;
+}
+
+void TonemapOperation::update_memory_buffer_started(MemoryBuffer *UNUSED(output),
+ const rcti &UNUSED(area),
+ Span<MemoryBuffer *> inputs)
+{
+ if (this->m_cachedInstance == nullptr) {
+ Luminance lum = {0};
+ const MemoryBuffer *input = inputs[0];
+ exec_system_->execute_work<Luminance>(
+ input->get_rect(),
+ [=](const rcti &split) { return calc_area_luminance(input, split); },
+ lum,
+ [](Luminance &join, const Luminance &chunk) {
+ join.sum += chunk.sum;
+ add_v3_v3(join.color_sum, chunk.color_sum);
+ join.log_sum += chunk.log_sum;
+ join.max = MAX2(join.max, chunk.max);
+ join.min = MIN2(join.min, chunk.min);
+ join.num_pixels += chunk.num_pixels;
+ });
+
+ AvgLogLum *avg = new AvgLogLum();
+ avg->lav = lum.sum / lum.num_pixels;
+ mul_v3_v3fl(avg->cav, lum.color_sum, 1.0f / lum.num_pixels);
+ const float max_log = log((double)lum.max + 1e-5);
+ const float min_log = log((double)lum.min + 1e-5);
+ const float avg_log = lum.log_sum / lum.num_pixels;
+ avg->auto_key = (max_log > min_log) ? ((max_log - avg_log) / (max_log - min_log)) : 1.0f;
+ const float al = exp((double)avg_log);
+ avg->al = (al == 0.0f) ? 0.0f : (this->m_data->key / al);
+ avg->igm = (this->m_data->gamma == 0.0f) ? 1 : (1.0f / this->m_data->gamma);
+ this->m_cachedInstance = avg;
+ }
+}
+
+void TonemapOperation::update_memory_buffer_partial(MemoryBuffer *output,
+ const rcti &area,
+ Span<MemoryBuffer *> inputs)
+{
+ AvgLogLum *avg = m_cachedInstance;
+ const float igm = avg->igm;
+ const float offset = this->m_data->offset;
+ for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) {
+ copy_v4_v4(it.out, it.in(0));
+ mul_v3_fl(it.out, avg->al);
+ float dr = it.out[0] + offset;
+ float dg = it.out[1] + offset;
+ float db = it.out[2] + offset;
+ it.out[0] /= ((dr == 0.0f) ? 1.0f : dr);
+ it.out[1] /= ((dg == 0.0f) ? 1.0f : dg);
+ it.out[2] /= ((db == 0.0f) ? 1.0f : db);
+ if (igm != 0.0f) {
+ it.out[0] = powf(MAX2(it.out[0], 0.0f), igm);
+ it.out[1] = powf(MAX2(it.out[1], 0.0f), igm);
+ it.out[2] = powf(MAX2(it.out[2], 0.0f), igm);
+ }
+ }
+}
+
+void PhotoreceptorTonemapOperation::update_memory_buffer_partial(MemoryBuffer *output,
+ const rcti &area,
+ Span<MemoryBuffer *> inputs)
+{
+ AvgLogLum *avg = m_cachedInstance;
+ NodeTonemap *ntm = this->m_data;
+ const float f = expf(-this->m_data->f);
+ const float m = (ntm->m > 0.0f) ? ntm->m : (0.3f + 0.7f * powf(avg->auto_key, 1.4f));
+ const float ic = 1.0f - ntm->c;
+ const float ia = 1.0f - ntm->a;
+ for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) {
+ copy_v4_v4(it.out, it.in(0));
+ const float L = IMB_colormanagement_get_luminance(it.out);
+ float I_l = it.out[0] + ic * (L - it.out[0]);
+ float I_g = avg->cav[0] + ic * (avg->lav - avg->cav[0]);
+ float I_a = I_l + ia * (I_g - I_l);
+ it.out[0] /= (it.out[0] + powf(f * I_a, m));
+ I_l = it.out[1] + ic * (L - it.out[1]);
+ I_g = avg->cav[1] + ic * (avg->lav - avg->cav[1]);
+ I_a = I_l + ia * (I_g - I_l);
+ it.out[1] /= (it.out[1] + powf(f * I_a, m));
+ I_l = it.out[2] + ic * (L - it.out[2]);
+ I_g = avg->cav[2] + ic * (avg->lav - avg->cav[2]);
+ I_a = I_l + ia * (I_g - I_l);
+ it.out[2] /= (it.out[2] + powf(f * I_a, m));
+ }
+}
+
} // namespace blender::compositor
diff --git a/source/blender/compositor/operations/COM_TonemapOperation.h b/source/blender/compositor/operations/COM_TonemapOperation.h
index 7ecb179504d..56b57730ec1 100644
--- a/source/blender/compositor/operations/COM_TonemapOperation.h
+++ b/source/blender/compositor/operations/COM_TonemapOperation.h
@@ -18,7 +18,7 @@
#pragma once
-#include "COM_NodeOperation.h"
+#include "COM_MultiThreadedOperation.h"
#include "DNA_node_types.h"
namespace blender::compositor {
@@ -39,7 +39,7 @@ typedef struct AvgLogLum {
* \brief base class of tonemap, implementing the simple tonemap
* \ingroup operation
*/
-class TonemapOperation : public NodeOperation {
+class TonemapOperation : public MultiThreadedOperation {
protected:
/**
* \brief Cached reference to the reader
@@ -85,6 +85,14 @@ class TonemapOperation : public NodeOperation {
bool determineDependingAreaOfInterest(rcti *input,
ReadBufferOperation *readOperation,
rcti *output) 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;
+ virtual void update_memory_buffer_partial(MemoryBuffer *output,
+ const rcti &area,
+ Span<MemoryBuffer *> inputs) override;
};
/**
@@ -99,6 +107,10 @@ class PhotoreceptorTonemapOperation : public TonemapOperation {
* The inner loop of this operation.
*/
void executePixel(float output[4], int x, int y, void *data) 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_ZCombineOperation.cc b/source/blender/compositor/operations/COM_ZCombineOperation.cc
index 9d3ca7e736e..7050c3b2d83 100644
--- a/source/blender/compositor/operations/COM_ZCombineOperation.cc
+++ b/source/blender/compositor/operations/COM_ZCombineOperation.cc
@@ -33,6 +33,7 @@ ZCombineOperation::ZCombineOperation()
this->m_depth1Reader = nullptr;
this->m_image2Reader = nullptr;
this->m_depth2Reader = nullptr;
+ this->flags.can_be_constant = true;
}
void ZCombineOperation::initExecution()
@@ -60,6 +61,19 @@ void ZCombineOperation::executePixelSampled(float output[4],
this->m_image2Reader->readSampled(output, x, y, sampler);
}
}
+
+void ZCombineOperation::update_memory_buffer_partial(MemoryBuffer *output,
+ const rcti &area,
+ Span<MemoryBuffer *> inputs)
+{
+ for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) {
+ const float depth1 = *it.in(1);
+ const float depth2 = *it.in(3);
+ const float *color = (depth1 < depth2) ? it.in(0) : it.in(2);
+ copy_v4_v4(it.out, color);
+ }
+}
+
void ZCombineAlphaOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -88,6 +102,32 @@ void ZCombineAlphaOperation::executePixelSampled(float output[4],
output[3] = MAX2(color1[3], color2[3]);
}
+void ZCombineAlphaOperation::update_memory_buffer_partial(MemoryBuffer *output,
+ const rcti &area,
+ Span<MemoryBuffer *> inputs)
+{
+ for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) {
+ const float depth1 = *it.in(1);
+ const float depth2 = *it.in(3);
+ const float *color1;
+ const float *color2;
+ if (depth1 <= depth2) {
+ color1 = it.in(0);
+ color2 = it.in(2);
+ }
+ else {
+ color1 = it.in(2);
+ color2 = it.in(0);
+ }
+ const float fac = color1[3];
+ const float ifac = 1.0f - fac;
+ it.out[0] = fac * color1[0] + ifac * color2[0];
+ it.out[1] = fac * color1[1] + ifac * color2[1];
+ it.out[2] = fac * color1[2] + ifac * color2[2];
+ it.out[3] = MAX2(color1[3], color2[3]);
+ }
+}
+
void ZCombineOperation::deinitExecution()
{
this->m_image1Reader = nullptr;
@@ -132,6 +172,18 @@ void ZCombineMaskOperation::executePixelSampled(float output[4],
interp_v4_v4v4(output, color1, color2, 1.0f - mask[0]);
}
+void ZCombineMaskOperation::update_memory_buffer_partial(MemoryBuffer *output,
+ const rcti &area,
+ Span<MemoryBuffer *> inputs)
+{
+ for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) {
+ const float mask = *it.in(0);
+ const float *color1 = it.in(1);
+ const float *color2 = it.in(2);
+ interp_v4_v4v4(it.out, color1, color2, 1.0f - mask);
+ }
+}
+
void ZCombineMaskAlphaOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -154,6 +206,24 @@ void ZCombineMaskAlphaOperation::executePixelSampled(float output[4],
output[3] = MAX2(color1[3], color2[3]);
}
+void ZCombineMaskAlphaOperation::update_memory_buffer_partial(MemoryBuffer *output,
+ const rcti &area,
+ Span<MemoryBuffer *> inputs)
+{
+ for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) {
+ const float mask = *it.in(0);
+ const float *color1 = it.in(1);
+ const float *color2 = it.in(2);
+ const float fac = (1.0f - mask) * (1.0f - color1[3]) + mask * color2[3];
+ const float mfac = 1.0f - fac;
+
+ it.out[0] = color1[0] * mfac + color2[0] * fac;
+ it.out[1] = color1[1] * mfac + color2[1] * fac;
+ it.out[2] = color1[2] * mfac + color2[2] * fac;
+ it.out[3] = MAX2(color1[3], color2[3]);
+ }
+}
+
void ZCombineMaskOperation::deinitExecution()
{
this->m_image1Reader = nullptr;
diff --git a/source/blender/compositor/operations/COM_ZCombineOperation.h b/source/blender/compositor/operations/COM_ZCombineOperation.h
index d0b1aee7310..acd60b6c866 100644
--- a/source/blender/compositor/operations/COM_ZCombineOperation.h
+++ b/source/blender/compositor/operations/COM_ZCombineOperation.h
@@ -26,7 +26,7 @@ namespace blender::compositor {
* this program converts an input color to an output value.
* it assumes we are in sRGB color space.
*/
-class ZCombineOperation : public NodeOperation {
+class ZCombineOperation : public MultiThreadedOperation {
protected:
SocketReader *m_image1Reader;
SocketReader *m_depth1Reader;
@@ -46,13 +46,21 @@ class ZCombineOperation : public NodeOperation {
* The inner loop of this operation.
*/
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
+
+ void update_memory_buffer_partial(MemoryBuffer *output,
+ const rcti &area,
+ Span<MemoryBuffer *> inputs) override;
};
class ZCombineAlphaOperation : public ZCombineOperation {
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
+
+ void update_memory_buffer_partial(MemoryBuffer *output,
+ const rcti &area,
+ Span<MemoryBuffer *> inputs) override;
};
-class ZCombineMaskOperation : public NodeOperation {
+class ZCombineMaskOperation : public MultiThreadedOperation {
protected:
SocketReader *m_maskReader;
SocketReader *m_image1Reader;
@@ -64,9 +72,17 @@ class ZCombineMaskOperation : public NodeOperation {
void initExecution() override;
void deinitExecution() override;
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
+
+ void update_memory_buffer_partial(MemoryBuffer *output,
+ const rcti &area,
+ Span<MemoryBuffer *> inputs) override;
};
class ZCombineMaskAlphaOperation : public ZCombineMaskOperation {
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
+
+ void update_memory_buffer_partial(MemoryBuffer *output,
+ const rcti &area,
+ Span<MemoryBuffer *> inputs) override;
};
} // namespace blender::compositor