Blender V5.0
node_composite_sepcomb_color.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BLI_assert.h"
6#include "BLI_math_color.h"
8
10
11#include "NOD_multi_function.hh"
12
13#include "GPU_material.hh"
14
16
17static void node_cmp_combsep_color_init(bNodeTree * /*ntree*/, bNode *node)
18{
21 data->ycc_mode = BLI_YCC_ITU_BT709;
22 node->storage = data;
23}
24
26{
27 bNodeSocket *sock1 = (bNodeSocket *)sockets->first;
28 bNodeSocket *sock2 = sock1->next;
29 bNodeSocket *sock3 = sock2->next;
30
34
35 switch (mode) {
37 node_sock_label(sock1, "Red");
38 node_sock_label(sock2, "Green");
39 node_sock_label(sock3, "Blue");
40 break;
42 node_sock_label(sock1, "Hue");
43 node_sock_label(sock2, "Saturation");
44 node_sock_label(sock3, "Value");
45 break;
47 node_sock_label(sock1, "Hue");
48 node_sock_label(sock2, "Saturation");
49 node_sock_label(sock3, "Lightness");
50 break;
52 node_sock_label(sock1, "Y");
53 node_sock_label(sock2, "Cb");
54 node_sock_label(sock3, "Cr");
55 break;
57 node_sock_label(sock1, "Y");
58 node_sock_label(sock2, "U");
59 node_sock_label(sock3, "V");
60 break;
61 default:
63 break;
64 }
65}
66
67/* **************** SEPARATE COLOR ******************** */
68
70
72
74{
75 b.is_function_node();
76 b.add_input<decl::Color>("Image").default_value({1.0f, 1.0f, 1.0f, 1.0f});
77 b.add_output<decl::Float>("Red");
78 b.add_output<decl::Float>("Green");
79 b.add_output<decl::Float>("Blue");
80 b.add_output<decl::Float>("Alpha");
81}
82
83static void cmp_node_separate_color_update(bNodeTree * /*ntree*/, bNode *node)
84{
85 const NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)node->storage;
87}
88
89using namespace blender::compositor;
90
91static int node_gpu_material(GPUMaterial *material,
92 bNode *node,
93 bNodeExecData * /*execdata*/,
96{
97 switch (node_storage(*node).mode) {
99 return GPU_stack_link(material, node, "node_composite_separate_rgba", inputs, outputs);
101 return GPU_stack_link(material, node, "node_composite_separate_hsva", inputs, outputs);
103 return GPU_stack_link(material, node, "node_composite_separate_hsla", inputs, outputs);
105 return GPU_stack_link(
106 material, node, "node_composite_separate_yuva_itu_709", inputs, outputs);
108 switch (node_storage(*node).ycc_mode) {
110 return GPU_stack_link(
111 material, node, "node_composite_separate_ycca_itu_601", inputs, outputs);
113 return GPU_stack_link(
114 material, node, "node_composite_separate_ycca_itu_709", inputs, outputs);
116 return GPU_stack_link(
117 material, node, "node_composite_separate_ycca_jpeg", inputs, outputs);
118 }
119 }
120
121 return false;
122}
123
125{
126 static auto rgba_function = mf::build::SI1_SO4<float4, float, float, float, float>(
127 "Separate Color RGBA",
128 [](const float4 &color, float &r, float &g, float &b, float &a) -> void {
129 r = color.x;
130 g = color.y;
131 b = color.z;
132 a = color.w;
133 },
134 mf::build::exec_presets::AllSpanOrSingle());
135
136 static auto hsva_function = mf::build::SI1_SO4<float4, float, float, float, float>(
137 "Separate Color HSVA",
138 [](const float4 &color, float &h, float &s, float &v, float &a) -> void {
139 rgb_to_hsv(color.x, color.y, color.z, &h, &s, &v);
140 a = color.w;
141 },
142 mf::build::exec_presets::AllSpanOrSingle());
143
144 static auto hsla_function = mf::build::SI1_SO4<float4, float, float, float, float>(
145 "Separate Color HSLA",
146 [](const float4 &color, float &h, float &s, float &l, float &a) -> void {
147 rgb_to_hsl(color.x, color.y, color.z, &h, &s, &l);
148 a = color.w;
149 },
150 mf::build::exec_presets::AllSpanOrSingle());
151
152 static auto yuva_function = mf::build::SI1_SO4<float4, float, float, float, float>(
153 "Separate Color YUVA",
154 [](const float4 &color, float &y, float &u, float &v, float &a) -> void {
155 rgb_to_yuv(color.x, color.y, color.z, &y, &u, &v, BLI_YUV_ITU_BT709);
156 a = color.w;
157 },
158 mf::build::exec_presets::AllSpanOrSingle());
159
160 static auto ycca_itu_601_function = mf::build::SI1_SO4<float4, float, float, float, float>(
161 "Separate Color YCCA ITU 601",
162 [](const float4 &color, float &y, float &cb, float &cr, float &a) -> void {
163 rgb_to_ycc(color.x, color.y, color.z, &y, &cb, &cr, BLI_YCC_ITU_BT601);
164 y /= 255.0f;
165 cb /= 255.0f;
166 cr /= 255.0f;
167 a = color.w;
168 },
169 mf::build::exec_presets::AllSpanOrSingle());
170
171 static auto ycca_itu_709_function = mf::build::SI1_SO4<float4, float, float, float, float>(
172 "Separate Color YCCA ITU 709",
173 [](const float4 &color, float &y, float &cb, float &cr, float &a) -> void {
174 rgb_to_ycc(color.x, color.y, color.z, &y, &cb, &cr, BLI_YCC_ITU_BT709);
175 y /= 255.0f;
176 cb /= 255.0f;
177 cr /= 255.0f;
178 a = color.w;
179 },
180 mf::build::exec_presets::AllSpanOrSingle());
181
182 static auto ycca_jpeg_function = mf::build::SI1_SO4<float4, float, float, float, float>(
183 "Separate Color YCCA JPEG",
184 [](const float4 &color, float &y, float &cb, float &cr, float &a) -> void {
185 rgb_to_ycc(color.x, color.y, color.z, &y, &cb, &cr, BLI_YCC_JFIF_0_255);
186 y /= 255.0f;
187 cb /= 255.0f;
188 cr /= 255.0f;
189 a = color.w;
190 },
191 mf::build::exec_presets::AllSpanOrSingle());
192
193 switch (node_storage(builder.node()).mode) {
195 builder.set_matching_fn(rgba_function);
196 break;
198 builder.set_matching_fn(hsva_function);
199 break;
201 builder.set_matching_fn(hsla_function);
202 break;
204 builder.set_matching_fn(yuva_function);
205 break;
207 switch (node_storage(builder.node()).ycc_mode) {
209 builder.set_matching_fn(ycca_itu_601_function);
210 break;
212 builder.set_matching_fn(ycca_itu_709_function);
213 break;
215 builder.set_matching_fn(ycca_jpeg_function);
216 break;
217 }
218 }
219}
220
221} // namespace blender::nodes::node_composite_separate_color_cc
222
224{
226
227 static blender::bke::bNodeType ntype;
228
229 cmp_node_type_base(&ntype, "CompositorNodeSeparateColor", CMP_NODE_SEPARATE_COLOR);
230 ntype.ui_name = "Separate Color";
231 ntype.ui_description = "Split an image into its composite color channels";
232 ntype.enum_name_legacy = "SEPARATE_COLOR";
234 ntype.declare = file_ns::cmp_node_separate_color_declare;
237 ntype, "NodeCMPCombSepColor", node_free_standard_storage, node_copy_standard_storage);
238 ntype.updatefunc = file_ns::cmp_node_separate_color_update;
239 ntype.gpu_fn = file_ns::node_gpu_material;
240 ntype.build_multi_function = file_ns::node_build_multi_function;
241
243}
245
246/* **************** COMBINE COLOR ******************** */
247
249
251
253{
254 b.is_function_node();
255 b.add_input<decl::Float>("Red").default_value(0.0f).min(0.0f).max(1.0f).subtype(PROP_FACTOR);
256 b.add_input<decl::Float>("Green").default_value(0.0f).min(0.0f).max(1.0f).subtype(PROP_FACTOR);
257 b.add_input<decl::Float>("Blue").default_value(0.0f).min(0.0f).max(1.0f).subtype(PROP_FACTOR);
258 b.add_input<decl::Float>("Alpha").default_value(1.0f).min(0.0f).max(1.0f).subtype(PROP_FACTOR);
259 b.add_output<decl::Color>("Image");
260}
261
262static void cmp_node_combine_color_update(bNodeTree * /*ntree*/, bNode *node)
263{
264 const NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)node->storage;
266}
267
268using namespace blender::compositor;
269
270static int node_gpu_material(GPUMaterial *material,
271 bNode *node,
272 bNodeExecData * /*execdata*/,
275{
276 switch (node_storage(*node).mode) {
278 return GPU_stack_link(material, node, "node_composite_combine_rgba", inputs, outputs);
280 return GPU_stack_link(material, node, "node_composite_combine_hsva", inputs, outputs);
282 return GPU_stack_link(material, node, "node_composite_combine_hsla", inputs, outputs);
284 return GPU_stack_link(
285 material, node, "node_composite_combine_yuva_itu_709", inputs, outputs);
287 switch (node_storage(*node).ycc_mode) {
289 return GPU_stack_link(
290 material, node, "node_composite_combine_ycca_itu_601", inputs, outputs);
292 return GPU_stack_link(
293 material, node, "node_composite_combine_ycca_itu_709", inputs, outputs);
295 return GPU_stack_link(
296 material, node, "node_composite_combine_ycca_jpeg", inputs, outputs);
297 }
298 }
299
300 return false;
301}
302
304{
305 static auto rgba_function = mf::build::SI4_SO<float, float, float, float, float4>(
306 "Combine Color RGBA",
307 [](const float r, const float g, const float b, const float a) -> float4 {
308 return float4(r, g, b, a);
309 },
310 mf::build::exec_presets::Materialized());
311
312 static auto hsva_function = mf::build::SI4_SO<float, float, float, float, float4>(
313 "Combine Color HSVA",
314 [](const float h, const float s, const float v, const float a) -> float4 {
316 hsv_to_rgb(h, s, v, &result.x, &result.y, &result.z);
317 result.w = a;
318 return result;
319 },
320 mf::build::exec_presets::Materialized());
321
322 static auto hsla_function = mf::build::SI4_SO<float, float, float, float, float4>(
323 "Combine Color HSLA",
324 [](const float h, const float s, const float l, const float a) -> float4 {
326 hsl_to_rgb(h, s, l, &result.x, &result.y, &result.z);
327 result.w = a;
328 return result;
329 },
330 mf::build::exec_presets::Materialized());
331
332 static auto yuva_function = mf::build::SI4_SO<float, float, float, float, float4>(
333 "Combine Color YUVA",
334 [](const float y, const float u, const float v, const float a) -> float4 {
337 result.w = a;
338 return result;
339 },
340 mf::build::exec_presets::Materialized());
341
342 static auto ycca_itu_601_function = mf::build::SI4_SO<float, float, float, float, float4>(
343 "Combine Color YCCA ITU 601",
344 [](const float y, const float cb, const float cr, const float a) -> float4 {
346 ycc_to_rgb(y * 255.0f,
347 cb * 255.0f,
348 cr * 255.0f,
349 &result.x,
350 &result.y,
351 &result.z,
353 result.w = a;
354 return result;
355 },
356 mf::build::exec_presets::Materialized());
357
358 static auto ycca_itu_709_function = mf::build::SI4_SO<float, float, float, float, float4>(
359 "Combine Color YCCA ITU 709",
360 [](const float y, const float cb, const float cr, const float a) -> float4 {
362 ycc_to_rgb(y * 255.0f,
363 cb * 255.0f,
364 cr * 255.0f,
365 &result.x,
366 &result.y,
367 &result.z,
369 result.w = a;
370 return result;
371 },
372 mf::build::exec_presets::Materialized());
373
374 static auto ycca_jpeg_function = mf::build::SI4_SO<float, float, float, float, float4>(
375 "Combine Color YCCA JPEG",
376 [](const float y, const float cb, const float cr, const float a) -> float4 {
378 ycc_to_rgb(y * 255.0f,
379 cb * 255.0f,
380 cr * 255.0f,
381 &result.x,
382 &result.y,
383 &result.z,
385 result.w = a;
386 return result;
387 },
388 mf::build::exec_presets::Materialized());
389
390 switch (node_storage(builder.node()).mode) {
392 builder.set_matching_fn(rgba_function);
393 break;
395 builder.set_matching_fn(hsva_function);
396 break;
398 builder.set_matching_fn(hsla_function);
399 break;
401 builder.set_matching_fn(yuva_function);
402 break;
404 switch (node_storage(builder.node()).ycc_mode) {
406 builder.set_matching_fn(ycca_itu_601_function);
407 break;
409 builder.set_matching_fn(ycca_itu_709_function);
410 break;
412 builder.set_matching_fn(ycca_jpeg_function);
413 break;
414 }
415 }
416}
417
418} // namespace blender::nodes::node_composite_combine_color_cc
419
421{
423
424 static blender::bke::bNodeType ntype;
425
426 cmp_node_type_base(&ntype, "CompositorNodeCombineColor", CMP_NODE_COMBINE_COLOR);
427 ntype.ui_name = "Combine Color";
428 ntype.ui_description = "Combine an image from its composite color channels";
429 ntype.enum_name_legacy = "COMBINE_COLOR";
431 ntype.declare = file_ns::cmp_node_combine_color_declare;
434 ntype, "NodeCMPCombSepColor", node_free_standard_storage, node_copy_standard_storage);
435 ntype.updatefunc = file_ns::cmp_node_combine_color_update;
436 ntype.gpu_fn = file_ns::node_gpu_material;
437 ntype.build_multi_function = file_ns::node_build_multi_function;
438
440}
#define NODE_CLASS_CONVERTER
Definition BKE_node.hh:453
#define NODE_STORAGE_FUNCS(StorageT)
Definition BKE_node.hh:1240
#define CMP_NODE_SEPARATE_COLOR
#define CMP_NODE_COMBINE_COLOR
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define BLI_YUV_ITU_BT709
void rgb_to_hsl(float r, float g, float b, float *r_h, float *r_s, float *r_l)
#define BLI_YCC_JFIF_0_255
void rgb_to_hsv(float r, float g, float b, float *r_h, float *r_s, float *r_v)
void ycc_to_rgb(float y, float cb, float cr, float *r_r, float *r_g, float *r_b, int colorspace)
void hsv_to_rgb(float h, float s, float v, float *r_r, float *r_g, float *r_b)
Definition math_color.cc:21
#define BLI_YCC_ITU_BT601
void rgb_to_ycc(float r, float g, float b, float *r_y, float *r_cb, float *r_cr, int colorspace)
void rgb_to_yuv(float r, float g, float b, float *r_y, float *r_u, float *r_v, int colorspace)
Definition math_color.cc:67
void hsl_to_rgb(float h, float s, float l, float *r_r, float *r_g, float *r_b)
Definition math_color.cc:38
void yuv_to_rgb(float y, float u, float v, float *r_r, float *r_g, float *r_b, int colorspace)
Definition math_color.cc:91
#define BLI_YCC_ITU_BT709
CMPNodeCombSepColorMode
@ CMP_NODE_COMBSEP_COLOR_YCC
@ CMP_NODE_COMBSEP_COLOR_YUV
@ CMP_NODE_COMBSEP_COLOR_RGB
@ CMP_NODE_COMBSEP_COLOR_HSV
@ CMP_NODE_COMBSEP_COLOR_HSL
bool GPU_stack_link(GPUMaterial *mat, const bNode *node, const char *name, GPUNodeStack *in, GPUNodeStack *out,...)
#define NOD_REGISTER_NODE(REGISTER_FUNC)
@ PROP_FACTOR
Definition RNA_types.hh:251
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
void set_matching_fn(const mf::MultiFunction *fn)
VecBase< float, 4 > float4
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void node_register_type(bNodeType &ntype)
Definition node.cc:2416
void node_type_storage(bNodeType &ntype, std::optional< StringRefNull > storagename, void(*freefunc)(bNode *node), void(*copyfunc)(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node))
Definition node.cc:5414
static void cmp_node_combine_color_update(bNodeTree *, bNode *node)
static void node_build_multi_function(blender::nodes::NodeMultiFunctionBuilder &builder)
static void cmp_node_combine_color_declare(NodeDeclarationBuilder &b)
static int node_gpu_material(GPUMaterial *material, bNode *node, bNodeExecData *, GPUNodeStack *inputs, GPUNodeStack *outputs)
static void cmp_node_separate_color_declare(NodeDeclarationBuilder &b)
static int node_gpu_material(GPUMaterial *material, bNode *node, bNodeExecData *, GPUNodeStack *inputs, GPUNodeStack *outputs)
static void node_build_multi_function(blender::nodes::NodeMultiFunctionBuilder &builder)
static void cmp_node_separate_color_update(bNodeTree *, bNode *node)
VecBase< float, 4 > float4
static void node_cmp_combsep_color_label(const ListBase *sockets, CMPNodeCombSepColorMode mode)
static void register_node_type_cmp_combine_color()
static void register_node_type_cmp_separate_color()
static void node_cmp_combsep_color_init(bNodeTree *, bNode *node)
void cmp_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
static blender::bke::bNodeSocketTemplate outputs[]
static blender::bke::bNodeSocketTemplate inputs[]
void node_sock_label_clear(bNodeSocket *sock)
Definition node_util.cc:78
void node_sock_label(bNodeSocket *sock, const char *name)
Definition node_util.cc:73
void node_free_standard_storage(bNode *node)
Definition node_util.cc:42
void node_copy_standard_storage(bNodeTree *, bNode *dest_node, const bNode *src_node)
Definition node_util.cc:54
#define min(a, b)
Definition sort.cc:36
void * first
struct bNodeSocket * next
ListBase inputs
void * storage
ListBase outputs
Defines a node type.
Definition BKE_node.hh:238
std::string ui_description
Definition BKE_node.hh:244
void(* initfunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:289
NodeGPUExecFunction gpu_fn
Definition BKE_node.hh:342
NodeMultiFunctionBuildFunction build_multi_function
Definition BKE_node.hh:351
const char * enum_name_legacy
Definition BKE_node.hh:247
NodeDeclareFunction declare
Definition BKE_node.hh:362
void(* updatefunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:281
max
Definition text_draw.cc:251