Blender V4.3
node_composite_color_spill.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 "RNA_access.hh"
10
11#include "UI_interface.hh"
12#include "UI_resources.hh"
13
14#include "GPU_material.hh"
15
16#include "COM_shader_node.hh"
17
19
20/* ******************* Color Spill Suppression ********************************* */
21
23
25
27{
28 b.add_input<decl::Color>("Image")
29 .default_value({1.0f, 1.0f, 1.0f, 1.0f})
30 .compositor_domain_priority(0);
31 b.add_input<decl::Float>("Fac")
32 .default_value(1.0f)
33 .min(0.0f)
34 .max(1.0f)
36 .compositor_domain_priority(1);
37 b.add_output<decl::Color>("Image");
38}
39
40static void node_composit_init_color_spill(bNodeTree * /*ntree*/, bNode *node)
41{
42 NodeColorspill *ncs = MEM_cnew<NodeColorspill>(__func__);
43 node->storage = ncs;
45 node->custom1 = 2; /* green channel */
46 ncs->limchan = 0; /* limit by red */
47 ncs->limscale = 1.0f; /* limit scaling factor */
48 ncs->unspill = 0; /* do not use unspill */
49}
50
52{
53 uiLayout *row, *col;
54
55 uiItemL(layout, IFACE_("Despill Channel:"), ICON_NONE);
56 row = uiLayoutRow(layout, false);
57 uiItemR(row, ptr, "channel", UI_ITEM_R_SPLIT_EMPTY_NAME | UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
58
59 col = uiLayoutColumn(layout, false);
60 uiItemR(col, ptr, "limit_method", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
61
62 if (RNA_enum_get(ptr, "limit_method") == 0) {
63 uiItemL(col, IFACE_("Limiting Channel:"), ICON_NONE);
64 row = uiLayoutRow(col, false);
65 uiItemR(row,
66 ptr,
67 "limit_channel",
69 nullptr,
70 ICON_NONE);
71 }
72
73 uiItemR(col, ptr, "ratio", UI_ITEM_R_SPLIT_EMPTY_NAME | UI_ITEM_R_SLIDER, nullptr, ICON_NONE);
74 uiItemR(col, ptr, "use_unspill", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE);
75 if (RNA_boolean_get(ptr, "use_unspill") == true) {
77 ptr,
78 "unspill_red",
80 nullptr,
81 ICON_NONE);
83 ptr,
84 "unspill_green",
86 nullptr,
87 ICON_NONE);
89 ptr,
90 "unspill_blue",
92 nullptr,
93 ICON_NONE);
94 }
95}
96
97using namespace blender::realtime_compositor;
98
100 public:
102
103 void compile(GPUMaterial *material) override
104 {
105 GPUNodeStack *inputs = get_inputs_array();
106 GPUNodeStack *outputs = get_outputs_array();
107
108 const float spill_channel = get_spill_channel();
109 float spill_scale[3];
110 get_spill_scale(spill_scale);
111 float limit_channels[2];
112 get_limit_channels(limit_channels);
113 const float limit_scale = get_limit_scale();
114
115 GPU_stack_link(material,
116 &bnode(),
117 "node_composite_color_spill",
118 inputs,
119 outputs,
120 GPU_constant(&spill_channel),
121 GPU_uniform(spill_scale),
122 GPU_constant(limit_channels),
123 GPU_uniform(&limit_scale));
124 }
125
126 /* Get the index of the channel used for spilling. */
128 {
129 return bnode().custom1 - 1;
130 }
131
136
137 void get_spill_scale(float spill_scale[3])
138 {
139 const NodeColorspill &node_color_spill = node_storage(bnode());
140 if (node_color_spill.unspill) {
141 spill_scale[0] = node_color_spill.uspillr;
142 spill_scale[1] = node_color_spill.uspillg;
143 spill_scale[2] = node_color_spill.uspillb;
144 spill_scale[get_spill_channel()] *= -1.0f;
145 }
146 else {
147 spill_scale[0] = 0.0f;
148 spill_scale[1] = 0.0f;
149 spill_scale[2] = 0.0f;
150 spill_scale[get_spill_channel()] = -1.0f;
151 }
152 }
153
154 /* Get the index of the channel used for limiting. */
156 {
157 return node_storage(bnode()).limchan;
158 }
159
160 /* Get the indices of the channels used to compute the limit value. We always assume the limit
161 * algorithm is Average, if it is a single limit channel, store it in both limit channels,
162 * because the average of two identical values is the same value. */
163 void get_limit_channels(float limit_channels[2])
164 {
166 /* If the algorithm is Average, store the indices of the other two channels other than the
167 * spill channel. */
168 limit_channels[0] = (get_spill_channel() + 1) % 3;
169 limit_channels[1] = (get_spill_channel() + 2) % 3;
170 }
171 else {
172 /* If the algorithm is Single, store the index of the limit channel in both channels. */
173 limit_channels[0] = get_limit_channel();
174 limit_channels[1] = get_limit_channel();
175 }
176 }
177
179 {
180 return node_storage(bnode()).limscale;
181 }
182};
183
185{
186 return new ColorSpillShaderNode(node);
187}
188
189} // namespace blender::nodes::node_composite_color_spill_cc
190
192{
194
195 static blender::bke::bNodeType ntype;
196
197 cmp_node_type_base(&ntype, CMP_NODE_COLOR_SPILL, "Color Spill", NODE_CLASS_MATTE);
198 ntype.declare = file_ns::cmp_node_color_spill_declare;
199 ntype.draw_buttons = file_ns::node_composit_buts_color_spill;
200 ntype.initfunc = file_ns::node_composit_init_color_spill;
202 &ntype, "NodeColorspill", node_free_standard_storage, node_copy_standard_storage);
203 ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node;
204
206}
#define NODE_CLASS_MATTE
Definition BKE_node.hh:411
#define NODE_STORAGE_FUNCS(StorageT)
Definition BKE_node.hh:1799
#define IFACE_(msgid)
CMPNodeColorSpillLimitAlgorithm
@ CMP_NODE_COLOR_SPILL_LIMIT_ALGORITHM_AVERAGE
@ CMP_NODE_COLOR_SPILL_LIMIT_ALGORITHM_SINGLE
bool GPU_stack_link(GPUMaterial *mat, const bNode *node, const char *name, GPUNodeStack *in, GPUNodeStack *out,...)
GPUNodeLink * GPU_constant(const float *num)
GPUNodeLink * GPU_uniform(const float *num)
@ PROP_FACTOR
Definition RNA_types.hh:154
void uiItemL(uiLayout *layout, const char *name, int icon)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
@ UI_ITEM_R_SPLIT_EMPTY_NAME
@ UI_ITEM_R_EXPAND
@ UI_ITEM_R_SLIDER
local_group_size(16, 16) .push_constant(Type b
uint col
void node_type_storage(bNodeType *ntype, const char *storagename, void(*freefunc)(bNode *node), void(*copyfunc)(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node))
Definition node.cc:4632
void node_register_type(bNodeType *ntype)
Definition node.cc:1708
static void node_composit_init_color_spill(bNodeTree *, bNode *node)
static void node_composit_buts_color_spill(uiLayout *layout, bContext *, PointerRNA *ptr)
static void cmp_node_color_spill_declare(NodeDeclarationBuilder &b)
void register_node_type_cmp_color_spill()
void cmp_node_type_base(blender::bke::bNodeType *ntype, int type, const char *name, short nclass)
void node_free_standard_storage(bNode *node)
Definition node_util.cc:46
void node_copy_standard_storage(bNodeTree *, bNode *dest_node, const bNode *src_node)
Definition node_util.cc:58
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
int16_t custom1
int16_t custom2
Defines a node type.
Definition BKE_node.hh:218
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
NodeGetCompositorShaderNodeFunction get_compositor_shader_node
Definition BKE_node.hh:328
PointerRNA * ptr
Definition wm_files.cc:4126