Blender V4.3
node_composite_levels.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2006 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <cmath>
10
11#include "BLI_assert.h"
12#include "BLI_math_vector.hh"
14
15#include "UI_interface.hh"
16#include "UI_resources.hh"
17
19
21#include "COM_node_operation.hh"
22
24
25/* **************** LEVELS ******************** */
26
28
30{
31 b.add_input<decl::Color>("Image")
32 .default_value({0.0f, 0.0f, 0.0f, 1.0f})
33 .compositor_domain_priority(0);
34 b.add_output<decl::Float>("Mean");
35 b.add_output<decl::Float>("Std Dev");
36}
37
38static void node_composit_init_view_levels(bNodeTree * /*ntree*/, bNode *node)
39{
40 node->custom1 = 1; /* All channels. */
41}
42
44{
45 uiItemR(layout, ptr, "channel", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
46}
47
48using namespace blender::realtime_compositor;
49
51 private:
52 constexpr static float luminance_coefficients_bt709_[3] = {0.2126f, 0.7152f, 0.0722f};
53
54 public:
56
57 void execute() override
58 {
59 if (get_input("Image").is_single_value()) {
61 return;
62 }
63
64 const float mean = compute_mean();
65
66 Result &mean_result = get_result("Mean");
67 if (mean_result.should_compute()) {
68 mean_result.allocate_single_value();
69 mean_result.set_float_value(mean);
70 }
71
72 Result &standard_deviation_result = get_result("Std Dev");
73 if (standard_deviation_result.should_compute()) {
74 const float standard_deviation = compute_standard_deviation(mean);
75 standard_deviation_result.allocate_single_value();
76 standard_deviation_result.set_float_value(standard_deviation);
77 }
78 }
79
81 {
82 Result &standard_deviation_result = get_result("Std Dev");
83 if (standard_deviation_result.should_compute()) {
84 standard_deviation_result.allocate_single_value();
85 standard_deviation_result.set_float_value(0.0f);
86 }
87
88 Result &mean_result = get_result("Mean");
89 if (!mean_result.should_compute()) {
90 return;
91 }
92
93 mean_result.allocate_single_value();
94 const float3 input = float3(get_input("Image").get_color_value());
95
96 switch (get_channel()) {
98 mean_result.set_float_value(input.x);
99 break;
101 mean_result.set_float_value(input.y);
102 break;
104 mean_result.set_float_value(input.z);
105 break;
107 mean_result.set_float_value(math::dot(input, float3(luminance_coefficients_bt709_)));
108 break;
110 float luminance_coefficients[3];
112 mean_result.set_float_value(math::dot(input, float3(luminance_coefficients)));
113 break;
114 }
115 default:
117 break;
118 }
119 }
120
122 {
123 const Result &input = get_input("Image");
124 return compute_sum() / (input.domain().size.x * input.domain().size.y);
125 }
126
128 {
129 const Result &input = get_input("Image");
130 switch (get_channel()) {
132 return sum_red(context(), input);
134 return sum_green(context(), input);
136 return sum_blue(context(), input);
138 return sum_luminance(context(), input, float3(luminance_coefficients_bt709_));
140 float luminance_coefficients[3];
142 return sum_luminance(context(), input, float3(luminance_coefficients));
143 }
144 default:
146 return 0.0f;
147 }
148 }
149
151 {
152 const Result &input = get_input("Image");
153 const float sum = compute_sum_squared_difference(mean);
154 return std::sqrt(sum / (input.domain().size.x * input.domain().size.y));
155 }
156
157 float compute_sum_squared_difference(float subtrahend)
158 {
159 const Result &input = get_input("Image");
160 switch (get_channel()) {
162 return sum_red_squared_difference(context(), input, subtrahend);
164 return sum_green_squared_difference(context(), input, subtrahend);
166 return sum_blue_squared_difference(context(), input, subtrahend);
169 context(), input, float3(luminance_coefficients_bt709_), subtrahend);
171 float luminance_coefficients[3];
174 context(), input, float3(luminance_coefficients), subtrahend);
175 }
176 default:
178 return 0.0f;
179 }
180 }
181
183 {
184 return static_cast<CMPNodeLevelsChannel>(bnode().custom1);
185 }
186};
187
189{
190 return new LevelsOperation(context, node);
191}
192
193} // namespace blender::nodes::node_composite_levels_cc
194
196{
198
199 static blender::bke::bNodeType ntype;
200
201 cmp_node_type_base(&ntype, CMP_NODE_VIEW_LEVELS, "Levels", NODE_CLASS_OUTPUT);
202 ntype.declare = file_ns::cmp_node_levels_declare;
203 ntype.draw_buttons = file_ns::node_composit_buts_view_levels;
204 ntype.flag |= NODE_PREVIEW;
205 ntype.initfunc = file_ns::node_composit_init_view_levels;
206 ntype.get_compositor_operation = file_ns::get_compositor_operation;
207
209}
#define NODE_CLASS_OUTPUT
Definition BKE_node.hh:405
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
@ NODE_PREVIEW
CMPNodeLevelsChannel
@ CMP_NODE_LEVLES_LUMINANCE
@ CMP_NODE_LEVLES_GREEN
@ CMP_NODE_LEVLES_LUMINANCE_BT709
@ CMP_NODE_LEVLES_RED
@ CMP_NODE_LEVLES_BLUE
BLI_INLINE void IMB_colormanagement_get_luminance_coefficients(float r_rgb[3])
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
@ UI_ITEM_R_SPLIT_EMPTY_NAME
static T sum(const btAlignedObjectArray< T > &items)
NodeOperation(Context &context, DNode node)
Result & get_input(StringRef identifier) const
Definition operation.cc:144
Result & get_result(StringRef identifier)
Definition operation.cc:46
void set_float_value(float value)
Definition result.cc:467
local_group_size(16, 16) .push_constant(Type b
void node_register_type(bNodeType *ntype)
Definition node.cc:1708
T dot(const QuaternionBase< T > &a, const QuaternionBase< T > &b)
static void node_composit_init_view_levels(bNodeTree *, bNode *node)
static void cmp_node_levels_declare(NodeDeclarationBuilder &b)
static void node_composit_buts_view_levels(uiLayout *layout, bContext *, PointerRNA *ptr)
static NodeOperation * get_compositor_operation(Context &context, DNode node)
float sum_blue_squared_difference(Context &context, GPUTexture *texture, float subtrahend)
float sum_luminance_squared_difference(Context &context, GPUTexture *texture, float3 luminance_coefficients, float subtrahend)
float sum_blue(Context &context, GPUTexture *texture)
float sum_red_squared_difference(Context &context, GPUTexture *texture, float subtrahend)
float sum_luminance(Context &context, GPUTexture *texture, float3 luminance_coefficients)
float sum_red(Context &context, GPUTexture *texture)
float sum_green_squared_difference(Context &context, GPUTexture *texture, float subtrahend)
float sum_green(Context &context, GPUTexture *texture)
VecBase< float, 3 > float3
void register_node_type_cmp_view_levels()
void cmp_node_type_base(blender::bke::bNodeType *ntype, int type, const char *name, short nclass)
int16_t custom1
Defines a node type.
Definition BKE_node.hh:218
NodeGetCompositorOperationFunction get_compositor_operation
Definition BKE_node.hh:324
void(* initfunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:267
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
Definition BKE_node.hh:238
NodeDeclareFunction declare
Definition BKE_node.hh:347
PointerRNA * ptr
Definition wm_files.cc:4126