41 .description(
"Channel values lower than this minimum are keyed");
47 .description(
"Channel values higher than this maximum are not keyed");
68 row = &layout->
row(
false);
73 col->label(
IFACE_(
"Key Channel:"), ICON_NONE);
74 row = &
col->row(
false);
85 col->label(
IFACE_(
"Limiting Channel:"), ICON_NONE);
86 row = &
col->row(
false);
111 return node_storage(node).channel - 1;
132 return limit_channels;
147 "node_composite_channel_matte",
155template<CMPNodeChannelMatteColorSpace ColorSpace>
157 const float min_limit,
158 const float max_limit,
159 const int matte_channel,
160 const int2 limit_channels,
178 channels =
color.xyz();
181 float matte_value = channels[matte_channel];
182 float limit_value =
math::max(channels[limit_channels.x], channels[limit_channels.y]);
184 float alpha = 1.0f - (matte_value - limit_value);
185 if (alpha > max_limit) {
188 else if (alpha < min_limit) {
192 alpha = (alpha - min_limit) / (max_limit - min_limit);
205 switch (color_space) {
208 return mf::build::SI3_SO2<float4, float, float, float4, float>(
211 const float &minimum,
212 const float &maximum,
214 float &matte) ->
void {
216 color, minimum, maximum, matte_channel, limit_channels, output_color, matte);
218 mf::build::exec_presets::SomeSpanOrSingle<0>());
223 return mf::build::SI3_SO2<float4, float, float, float4, float>(
226 const float &minimum,
227 const float &maximum,
229 float &matte) ->
void {
231 color, minimum, maximum, matte_channel, limit_channels, output_color, matte);
233 mf::build::exec_presets::SomeSpanOrSingle<0>());
238 return mf::build::SI3_SO2<float4, float, float, float4, float>(
241 const float &minimum,
242 const float &maximum,
244 float &matte) ->
void {
246 color, minimum, maximum, matte_channel, limit_channels, output_color, matte);
248 mf::build::exec_presets::SomeSpanOrSingle<0>());
253 return mf::build::SI3_SO2<float4, float, float, float4, float>(
256 const float &minimum,
257 const float &maximum,
259 float &matte) ->
void {
261 color, minimum, maximum, matte_channel, limit_channels, output_color, matte);
263 mf::build::exec_presets::SomeSpanOrSingle<0>());
279 ntype.
ui_description =
"Create matte based on differences in color channels";
282 ntype.
declare = file_ns::cmp_node_channel_matte_declare;
283 ntype.
draw_buttons = file_ns::node_composit_buts_channel_matte;
285 ntype.
initfunc = file_ns::node_composit_init_channel_matte;
288 ntype.
gpu_fn = file_ns::node_gpu_material;
#define NODE_STORAGE_FUNCS(StorageT)
#define CMP_NODE_CHANNEL_MATTE
void rgb_to_hsv_v(const float rgb[3], float r_hsv[3])
#define BLI_YUV_ITU_BT709
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)
#define BLI_YCC_ITU_BT709
@ CMP_NODE_CHANNEL_MATTE_LIMIT_ALGORITHM_MAX
CMPNodeChannelMatteColorSpace
@ CMP_NODE_CHANNEL_MATTE_CS_YUV
@ CMP_NODE_CHANNEL_MATTE_CS_RGB
@ CMP_NODE_CHANNEL_MATTE_CS_HSV
@ CMP_NODE_CHANNEL_MATTE_CS_YCC
bool GPU_stack_link(GPUMaterial *mat, const bNode *node, const char *name, GPUNodeStack *in, GPUNodeStack *out,...)
GPUNodeLink * GPU_constant(const float *num)
blender::ocio::ColorSpace ColorSpace
#define NOD_REGISTER_NODE(REGISTER_FUNC)
@ UI_ITEM_R_SPLIT_EMPTY_NAME
void construct_and_set_matching_fn_cb(Fn &&create_multi_function)
ColorGeometry4f default_value
void * MEM_callocN(size_t len, const char *str)
void node_register_type(bNodeType &ntype)
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))
T min(const T &a, const T &b)
T max(const T &a, const T &b)
static int node_gpu_material(GPUMaterial *material, bNode *node, bNodeExecData *, GPUNodeStack *inputs, GPUNodeStack *outputs)
static void node_composit_buts_channel_matte(uiLayout *layout, bContext *, PointerRNA *ptr)
static CMPNodeChannelMatteColorSpace get_color_space(const bNode &node)
static void cmp_node_channel_matte_declare(NodeDeclarationBuilder &b)
static int2 get_limit_channels(const bNode &node)
static int get_matte_channel(const bNode &node)
static int get_limit_channel(const bNode &node)
static void channel_key(const float4 &color, const float min_limit, const float max_limit, const int matte_channel, const int2 limit_channels, float4 &result, float &matte)
static void node_composit_init_channel_matte(bNodeTree *, bNode *node)
static void node_build_multi_function(blender::nodes::NodeMultiFunctionBuilder &builder)
VecBase< float, 4 > float4
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
VecBase< float, 3 > float3
static void register_node_type_cmp_channel_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)
void node_copy_standard_storage(bNodeTree *, bNode *dest_node, const bNode *src_node)
int RNA_enum_get(PointerRNA *ptr, const char *name)
std::string ui_description
void(* initfunc)(bNodeTree *ntree, bNode *node)
NodeGPUExecFunction gpu_fn
NodeMultiFunctionBuildFunction build_multi_function
const char * enum_name_legacy
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
NodeDeclareFunction declare
void label(blender::StringRef name, int icon)
uiLayout & column(bool align)
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)