Blender V4.5
node_composite_distance_matte.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
8
9#include "BLI_math_base.hh"
10#include "BLI_math_color.h"
11#include "BLI_math_vector.hh"
13
15
16#include "NOD_multi_function.hh"
17
18#include "UI_interface.hh"
19#include "UI_resources.hh"
20
21#include "GPU_material.hh"
22
24
25/* ******************* channel Distance Matte ********************************* */
26
28
30
32{
33 b.add_input<decl::Color>("Image").default_value({1.0f, 1.0f, 1.0f, 1.0f});
34 b.add_input<decl::Color>("Key Color").default_value({1.0f, 1.0f, 1.0f, 1.0f});
35 b.add_input<decl::Float>("Tolerance")
36 .default_value(0.1f)
37 .subtype(PROP_FACTOR)
38 .min(0.0f)
39 .max(1.0f)
40 .description(
41 "If the distance between the color and the key color in the given color space is less "
42 "than this threshold, it is keyed");
43 b.add_input<decl::Float>("Falloff")
44 .default_value(0.1f)
45 .subtype(PROP_FACTOR)
46 .min(0.0f)
47 .max(1.0f)
48 .description(
49 "If the distance between the color and the key color in the given color space is less "
50 "than this threshold, it is partially keyed, otherwise, it is not keyed");
51
52 b.add_output<decl::Color>("Image");
53 b.add_output<decl::Float>("Matte");
54}
55
62
64{
65 layout->label(IFACE_("Color Space:"), ICON_NONE);
66 uiLayout *row = &layout->row(false);
67 row->prop(
68 ptr, "channel", UI_ITEM_R_SPLIT_EMPTY_NAME | UI_ITEM_R_EXPAND, std::nullopt, ICON_NONE);
69}
70
71using namespace blender::compositor;
72
74{
75 return static_cast<CMPNodeDistanceMatteColorSpace>(node_storage(node).channel);
76}
77
78static int node_gpu_material(GPUMaterial *material,
79 bNode *node,
80 bNodeExecData * /*execdata*/,
83{
84 switch (get_color_space(*node)) {
86 return GPU_stack_link(material, node, "node_composite_distance_matte_rgba", inputs, outputs);
88 return GPU_stack_link(material, node, "node_composite_distance_matte_ycca", inputs, outputs);
89 }
90
91 return false;
92}
93
94static void distance_key_rgba(const float4 &color,
95 const float4 &key,
96 const float tolerance,
97 const float falloff,
99 float &matte)
100{
101 float difference = math::distance(color.xyz(), key.xyz());
102 bool is_opaque = difference > tolerance + falloff;
103 float alpha = is_opaque ? color.w : math::max(0.0f, difference - tolerance) / falloff;
104 matte = math::min(alpha, color.w);
105 result = color * matte;
106}
107
108static void distance_key_ycca(const float4 &color,
109 const float4 &key,
110 const float tolerance,
111 const float falloff,
112 float4 &result,
113 float &matte)
114{
115 float3 color_ycca;
117 color.x, color.y, color.z, &color_ycca.x, &color_ycca.y, &color_ycca.z, BLI_YCC_ITU_BT709);
118 color_ycca /= 255.0f;
119 float3 key_ycca;
120 rgb_to_ycc(key.x, key.y, key.z, &key_ycca.x, &key_ycca.y, &key_ycca.z, BLI_YCC_ITU_BT709);
121 key_ycca /= 255.0f;
122
123 float difference = math::distance(color_ycca.yz(), key_ycca.yz());
124 bool is_opaque = difference > tolerance + falloff;
125 float alpha = is_opaque ? color.w : math::max(0.0f, difference - tolerance) / falloff;
126 matte = math::min(alpha, color.w);
127 result = color * matte;
128}
129
131{
132 const CMPNodeDistanceMatteColorSpace color_space = get_color_space(builder.node());
133
134 switch (color_space) {
137 return mf::build::SI4_SO2<float4, float4, float, float, float4, float>(
138 "Distance Key YCCA",
139 [=](const float4 &color,
140 const float4 &key_color,
141 const float &tolerance,
142 const float &falloff,
143 float4 &output_color,
144 float &matte) -> void {
145 distance_key_ycca(color, key_color, tolerance, falloff, output_color, matte);
146 },
147 mf::build::exec_presets::SomeSpanOrSingle<0, 1>());
148 });
149 break;
152 return mf::build::SI4_SO2<float4, float4, float, float, float4, float>(
153 "Distance Key RGBA",
154 [=](const float4 &color,
155 const float4 &key_color,
156 const float &tolerance,
157 const float &falloff,
158 float4 &output_color,
159 float &matte) -> void {
160 distance_key_rgba(color, key_color, tolerance, falloff, output_color, matte);
161 },
162 mf::build::exec_presets::SomeSpanOrSingle<0, 1>());
163 });
164 break;
165 }
166}
167
168} // namespace blender::nodes::node_composite_distance_matte_cc
169
171{
173
174 static blender::bke::bNodeType ntype;
175
176 cmp_node_type_base(&ntype, "CompositorNodeDistanceMatte", CMP_NODE_DIST_MATTE);
177 ntype.ui_name = "Distance Key";
178 ntype.ui_description = "Create matte based on 3D distance between colors";
179 ntype.enum_name_legacy = "DISTANCE_MATTE";
180 ntype.nclass = NODE_CLASS_MATTE;
181 ntype.declare = file_ns::cmp_node_distance_matte_declare;
182 ntype.draw_buttons = file_ns::node_composit_buts_distance_matte;
183 ntype.flag |= NODE_PREVIEW;
184 ntype.initfunc = file_ns::node_composit_init_distance_matte;
187 ntype.gpu_fn = file_ns::node_gpu_material;
188 ntype.build_multi_function = file_ns::node_build_multi_function;
189
191}
#define NODE_CLASS_MATTE
Definition BKE_node.hh:440
#define NODE_STORAGE_FUNCS(StorageT)
Definition BKE_node.hh:1215
#define CMP_NODE_DIST_MATTE
void rgb_to_ycc(float r, float g, float b, float *r_y, float *r_cb, float *r_cr, int colorspace)
#define BLI_YCC_ITU_BT709
#define IFACE_(msgid)
@ NODE_PREVIEW
CMPNodeDistanceMatteColorSpace
@ CMP_NODE_DISTANCE_MATTE_COLOR_SPACE_YCCA
@ CMP_NODE_DISTANCE_MATTE_COLOR_SPACE_RGBA
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:239
@ UI_ITEM_R_SPLIT_EMPTY_NAME
@ UI_ITEM_R_EXPAND
void construct_and_set_matching_fn_cb(Fn &&create_multi_function)
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void node_register_type(bNodeType &ntype)
Definition node.cc:2748
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:5603
T distance(const T &a, const T &b)
T min(const T &a, const T &b)
T max(const T &a, const T &b)
static void node_composit_init_distance_matte(bNodeTree *, bNode *node)
static CMPNodeDistanceMatteColorSpace get_color_space(const bNode &node)
static void distance_key_ycca(const float4 &color, const float4 &key, const float tolerance, const float falloff, float4 &result, float &matte)
static void distance_key_rgba(const float4 &color, const float4 &key, const float tolerance, const float falloff, float4 &result, float &matte)
static void node_build_multi_function(blender::nodes::NodeMultiFunctionBuilder &builder)
static void node_composit_buts_distance_matte(uiLayout *layout, bContext *, PointerRNA *ptr)
static void cmp_node_distance_matte_declare(NodeDeclarationBuilder &b)
static int node_gpu_material(GPUMaterial *material, bNode *node, bNodeExecData *, GPUNodeStack *inputs, GPUNodeStack *outputs)
VecBase< float, 4 > float4
VecBase< float, 3 > float3
static void register_node_type_cmp_distance_matte()
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_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 * storage
VecBase< T, 3 > xyz() const
VecBase< T, 2 > yz() const
Defines a node type.
Definition BKE_node.hh:226
std::string ui_description
Definition BKE_node.hh:232
void(* initfunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:277
NodeGPUExecFunction gpu_fn
Definition BKE_node.hh:330
NodeMultiFunctionBuildFunction build_multi_function
Definition BKE_node.hh:344
const char * enum_name_legacy
Definition BKE_node.hh:235
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
Definition BKE_node.hh:247
NodeDeclareFunction declare
Definition BKE_node.hh:355
void label(blender::StringRef name, int icon)
uiLayout & row(bool align)
void prop(PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, std::optional< blender::StringRef > name_opt, int icon, std::optional< blender::StringRef > placeholder=std::nullopt)
max
Definition text_draw.cc:251
PointerRNA * ptr
Definition wm_files.cc:4226