diff options
Diffstat (limited to 'source/blender/nodes/composite/nodes/node_composite_color_spill.cc')
-rw-r--r-- | source/blender/nodes/composite/nodes/node_composite_color_spill.cc | 116 |
1 files changed, 111 insertions, 5 deletions
diff --git a/source/blender/nodes/composite/nodes/node_composite_color_spill.cc b/source/blender/nodes/composite/nodes/node_composite_color_spill.cc index 9ad5dfbaeb2..ba829da83ed 100644 --- a/source/blender/nodes/composite/nodes/node_composite_color_spill.cc +++ b/source/blender/nodes/composite/nodes/node_composite_color_spill.cc @@ -10,31 +10,44 @@ #include "UI_interface.h" #include "UI_resources.h" +#include "GPU_material.h" + +#include "COM_shader_node.hh" + #include "node_composite_util.hh" /* ******************* Color Spill Suppression ********************************* */ namespace blender::nodes::node_composite_color_spill_cc { +NODE_STORAGE_FUNCS(NodeColorspill) + static void cmp_node_color_spill_declare(NodeDeclarationBuilder &b) { - b.add_input<decl::Color>(N_("Image")).default_value({1.0f, 1.0f, 1.0f, 1.0f}); - b.add_input<decl::Float>(N_("Fac")).default_value(1.0f).min(0.0f).max(1.0f).subtype(PROP_FACTOR); + b.add_input<decl::Color>(N_("Image")) + .default_value({1.0f, 1.0f, 1.0f, 1.0f}) + .compositor_domain_priority(0); + b.add_input<decl::Float>(N_("Fac")) + .default_value(1.0f) + .min(0.0f) + .max(1.0f) + .subtype(PROP_FACTOR) + .compositor_domain_priority(1); b.add_output<decl::Color>(N_("Image")); } -static void node_composit_init_color_spill(bNodeTree *UNUSED(ntree), bNode *node) +static void node_composit_init_color_spill(bNodeTree * /*ntree*/, bNode *node) { NodeColorspill *ncs = MEM_cnew<NodeColorspill>(__func__); node->storage = ncs; + node->custom2 = CMP_NODE_COLOR_SPILL_LIMIT_ALGORITHM_SINGLE; node->custom1 = 2; /* green channel */ - node->custom2 = 0; /* simple limit algorithm */ ncs->limchan = 0; /* limit by red */ ncs->limscale = 1.0f; /* limit scaling factor */ ncs->unspill = 0; /* do not use unspill */ } -static void node_composit_buts_color_spill(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +static void node_composit_buts_color_spill(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) { uiLayout *row, *col; @@ -80,6 +93,98 @@ static void node_composit_buts_color_spill(uiLayout *layout, bContext *UNUSED(C) } } +using namespace blender::realtime_compositor; + +class ColorSpillShaderNode : public ShaderNode { + public: + using ShaderNode::ShaderNode; + + void compile(GPUMaterial *material) override + { + GPUNodeStack *inputs = get_inputs_array(); + GPUNodeStack *outputs = get_outputs_array(); + + const float spill_channel = get_spill_channel(); + float spill_scale[3]; + get_spill_scale(spill_scale); + float limit_channels[2]; + get_limit_channels(limit_channels); + const float limit_scale = get_limit_scale(); + + GPU_stack_link(material, + &bnode(), + "node_composite_color_spill", + inputs, + outputs, + GPU_constant(&spill_channel), + GPU_uniform(spill_scale), + GPU_constant(limit_channels), + GPU_uniform(&limit_scale)); + } + + /* Get the index of the channel used for spilling. */ + int get_spill_channel() + { + return bnode().custom1 - 1; + } + + CMPNodeColorSpillLimitAlgorithm get_limit_algorithm() + { + return (CMPNodeColorSpillLimitAlgorithm)bnode().custom2; + } + + void get_spill_scale(float spill_scale[3]) + { + const NodeColorspill &node_color_spill = node_storage(bnode()); + if (node_color_spill.unspill) { + spill_scale[0] = node_color_spill.uspillr; + spill_scale[1] = node_color_spill.uspillg; + spill_scale[2] = node_color_spill.uspillb; + spill_scale[get_spill_channel()] *= -1.0f; + } + else { + spill_scale[0] = 0.0f; + spill_scale[1] = 0.0f; + spill_scale[2] = 0.0f; + spill_scale[get_spill_channel()] = -1.0f; + } + } + + /* Get the index of the channel used for limiting. */ + int get_limit_channel() + { + return node_storage(bnode()).limchan; + } + + /* Get the indices of the channels used to compute the limit value. We always assume the limit + * algorithm is Average, if it is a single limit channel, store it in both limit channels, + * because the average of two identical values is the same value. */ + void get_limit_channels(float limit_channels[2]) + { + if (get_limit_algorithm() == CMP_NODE_COLOR_SPILL_LIMIT_ALGORITHM_AVERAGE) { + /* If the algorithm is Average, store the indices of the other two channels other than the + * spill channel. */ + limit_channels[0] = (get_spill_channel() + 1) % 3; + limit_channels[1] = (get_spill_channel() + 2) % 3; + } + else { + /* If the algorithm is Single, store the index of the limit channel in both channels. */ + limit_channels[0] = get_limit_channel(); + limit_channels[1] = get_limit_channel(); + } + } + + float get_limit_scale() + { + return node_storage(bnode()).limscale; + } +}; + +static ShaderNode *get_compositor_shader_node(DNode node) +{ + return new ColorSpillShaderNode(node); +} + } // namespace blender::nodes::node_composite_color_spill_cc void register_node_type_cmp_color_spill() @@ -94,6 +199,7 @@ void register_node_type_cmp_color_spill() node_type_init(&ntype, file_ns::node_composit_init_color_spill); node_type_storage( &ntype, "NodeColorspill", node_free_standard_storage, node_copy_standard_storage); + ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node; nodeRegisterType(&ntype); } |