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:
Diffstat (limited to 'source/blender/nodes/composite/nodes/node_composite_levels.cc')
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_levels.cc144
1 files changed, 141 insertions, 3 deletions
diff --git a/source/blender/nodes/composite/nodes/node_composite_levels.cc b/source/blender/nodes/composite/nodes/node_composite_levels.cc
index a4fe1f33813..4c901372b9f 100644
--- a/source/blender/nodes/composite/nodes/node_composite_levels.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_levels.cc
@@ -5,9 +5,18 @@
* \ingroup cmpnodes
*/
+#include <cmath>
+
+#include "BLI_assert.h"
+#include "BLI_math_vec_types.hh"
+#include "BLI_math_vector.hh"
+
#include "UI_interface.h"
#include "UI_resources.h"
+#include "IMB_colormanagement.h"
+
+#include "COM_algorithm_parallel_reduction.hh"
#include "COM_node_operation.hh"
#include "node_composite_util.hh"
@@ -18,7 +27,9 @@ namespace blender::nodes::node_composite_levels_cc {
static void cmp_node_levels_declare(NodeDeclarationBuilder &b)
{
- b.add_input<decl::Color>(N_("Image")).default_value({0.0f, 0.0f, 0.0f, 1.0f});
+ b.add_input<decl::Color>(N_("Image"))
+ .default_value({0.0f, 0.0f, 0.0f, 1.0f})
+ .compositor_domain_priority(0);
b.add_output<decl::Float>(N_("Mean"));
b.add_output<decl::Float>(N_("Std Dev"));
}
@@ -36,13 +47,140 @@ static void node_composit_buts_view_levels(uiLayout *layout, bContext * /*C*/, P
using namespace blender::realtime_compositor;
class LevelsOperation : public NodeOperation {
+ private:
+ constexpr static float luminance_coefficients_bt709_[3] = {0.2126f, 0.7152f, 0.0722f};
+
public:
using NodeOperation::NodeOperation;
void execute() override
{
- get_result("Mean").allocate_invalid();
- get_result("Std Dev").allocate_invalid();
+ if (get_input("Image").is_single_value()) {
+ execute_single_value();
+ return;
+ }
+
+ const float mean = compute_mean();
+
+ Result &mean_result = get_result("Mean");
+ if (mean_result.should_compute()) {
+ mean_result.allocate_single_value();
+ mean_result.set_float_value(mean);
+ }
+
+ Result &standard_deviation_result = get_result("Std Dev");
+ if (standard_deviation_result.should_compute()) {
+ const float standard_deviation = compute_standard_deviation(mean);
+ standard_deviation_result.allocate_single_value();
+ standard_deviation_result.set_float_value(standard_deviation);
+ }
+ }
+
+ void execute_single_value()
+ {
+ Result &standard_deviation_result = get_result("Std Dev");
+ if (standard_deviation_result.should_compute()) {
+ standard_deviation_result.allocate_single_value();
+ standard_deviation_result.set_float_value(0.0f);
+ }
+
+ Result &mean_result = get_result("Mean");
+ if (!mean_result.should_compute()) {
+ return;
+ }
+
+ mean_result.allocate_single_value();
+ const float3 input = float3(get_input("Image").get_color_value());
+
+ switch (get_channel()) {
+ case CMP_NODE_LEVLES_RED:
+ mean_result.set_float_value(input.x);
+ break;
+ case CMP_NODE_LEVLES_GREEN:
+ mean_result.set_float_value(input.y);
+ break;
+ case CMP_NODE_LEVLES_BLUE:
+ mean_result.set_float_value(input.z);
+ break;
+ case CMP_NODE_LEVLES_LUMINANCE_BT709:
+ mean_result.set_float_value(math::dot(input, float3(luminance_coefficients_bt709_)));
+ break;
+ case CMP_NODE_LEVLES_LUMINANCE: {
+ float luminance_coefficients[3];
+ IMB_colormanagement_get_luminance_coefficients(luminance_coefficients);
+ mean_result.set_float_value(math::dot(input, float3(luminance_coefficients)));
+ break;
+ }
+ default:
+ BLI_assert_unreachable();
+ break;
+ }
+ }
+
+ float compute_mean()
+ {
+ const Result &input = get_input("Image");
+ return compute_sum() / (input.domain().size.x * input.domain().size.y);
+ }
+
+ float compute_sum()
+ {
+ const Result &input = get_input("Image");
+ switch (get_channel()) {
+ case CMP_NODE_LEVLES_RED:
+ return sum_red(context(), input.texture());
+ case CMP_NODE_LEVLES_GREEN:
+ return sum_green(context(), input.texture());
+ case CMP_NODE_LEVLES_BLUE:
+ return sum_blue(context(), input.texture());
+ case CMP_NODE_LEVLES_LUMINANCE_BT709:
+ return sum_luminance(context(), input.texture(), float3(luminance_coefficients_bt709_));
+ case CMP_NODE_LEVLES_LUMINANCE: {
+ float luminance_coefficients[3];
+ IMB_colormanagement_get_luminance_coefficients(luminance_coefficients);
+ return sum_luminance(context(), input.texture(), float3(luminance_coefficients));
+ }
+ default:
+ BLI_assert_unreachable();
+ return 0.0f;
+ }
+ }
+
+ float compute_standard_deviation(float mean)
+ {
+ const Result &input = get_input("Image");
+ const float sum = compute_sum_squared_difference(mean);
+ return std::sqrt(sum / (input.domain().size.x * input.domain().size.y));
+ }
+
+ float compute_sum_squared_difference(float subtrahend)
+ {
+ const Result &input = get_input("Image");
+ switch (get_channel()) {
+ case CMP_NODE_LEVLES_RED:
+ return sum_red_squared_difference(context(), input.texture(), subtrahend);
+ case CMP_NODE_LEVLES_GREEN:
+ return sum_green_squared_difference(context(), input.texture(), subtrahend);
+ case CMP_NODE_LEVLES_BLUE:
+ return sum_blue_squared_difference(context(), input.texture(), subtrahend);
+ case CMP_NODE_LEVLES_LUMINANCE_BT709:
+ return sum_luminance_squared_difference(
+ context(), input.texture(), float3(luminance_coefficients_bt709_), subtrahend);
+ case CMP_NODE_LEVLES_LUMINANCE: {
+ float luminance_coefficients[3];
+ IMB_colormanagement_get_luminance_coefficients(luminance_coefficients);
+ return sum_luminance_squared_difference(
+ context(), input.texture(), float3(luminance_coefficients), subtrahend);
+ }
+ default:
+ BLI_assert_unreachable();
+ return 0.0f;
+ }
+ }
+
+ CMPNodeLevelsChannel get_channel()
+ {
+ return static_cast<CMPNodeLevelsChannel>(bnode().custom1);
}
};