49 .description(
"Amount of mixing between the A and B inputs")
50 .compositor_domain_priority(2);
57 .description(
"Amount of mixing between the A and B vector inputs")
58 .compositor_domain_priority(2);
63 .is_default_link_socket()
65 .description(
"Value of the first floating number input")
66 .compositor_domain_priority(0);
71 .description(
"Value of the second floating number input")
72 .compositor_domain_priority(1);
77 .description(
"Value of the first vector input")
78 .compositor_domain_priority(0);
81 .description(
"Value of the second vector input")
82 .compositor_domain_priority(1);
86 .is_default_link_socket()
88 .description(
"Value of the first color input")
89 .compositor_domain_priority(0);
93 .description(
"Value of the second color input")
94 .compositor_domain_priority(1);
99 .compositor_domain_priority(0);
102 .compositor_domain_priority(1);
114 switch (
data.data_type) {
173 bool use_vector_factor = data_type ==
SOCK_VECTOR &&
180 for (
bNodeSocket *socket = sock_factor_vec->
next; socket !=
nullptr; socket = socket->
next) {
196 node_storage(node).data_type =
SOCK_RGBA;
197 node_storage(node).blend_type =
type;
228 node_storage(node).data_type = type;
229 params.update_and_connect_available_socket(node,
"Result");
237 node_storage(node).data_type = type;
238 params.update_and_connect_available_socket(node,
"A");
246 node_storage(node).data_type = type;
247 params.update_and_connect_available_socket(node,
"B");
253 IFACE_(
"Factor (Non-Uniform)"),
258 params.update_and_connect_available_socket(node,
"Factor");
268 node_storage(node).data_type = type;
269 params.update_and_connect_available_socket(node,
"Factor");
283 const std::string socket_name =
params.in_out() ==
SOCK_IN ?
"A" :
"Result";
287 if (item->name !=
nullptr && item->identifier[0] !=
'\0') {
298 data->clamp_factor = 1;
299 data->clamp_result = 0;
305 const bool non_uniform,
306 const int blend_type)
310 return "node_mix_float";
312 return (non_uniform) ?
"node_mix_vector_non_uniform" :
"node_mix_vector";
314 switch (blend_type) {
316 return "node_mix_blend";
318 return "node_mix_add";
320 return "node_mix_mult";
322 return "node_mix_sub";
324 return "node_mix_screen";
326 return "node_mix_div_fallback";
328 return "node_mix_diff";
330 return "node_mix_exclusion";
332 return "node_mix_dark";
334 return "node_mix_light";
336 return "node_mix_overlay";
338 return "node_mix_dodge";
340 return "node_mix_burn";
342 return "node_mix_hue";
344 return "node_mix_sat";
346 return "node_mix_val";
348 return "node_mix_color";
350 return "node_mix_soft";
352 return "node_mix_linear";
379 if (
name ==
nullptr) {
384 if (is_non_uniform && is_vector_mode) {
385 const float min[3] = {0.0f, 0.0f, 0.0f};
386 const float max[3] = {1.0f, 1.0f, 1.0f};
389 "node_mix_clamp_vector",
396 const float min = 0.0f;
397 const float max = 1.0f;
400 "node_mix_clamp_value",
411 const float min[4] = {0.0f, 0.0f, 0.0f, 0.0f};
412 const float max[4] = {1.0f, 1.0f, 1.0f, 1.0f};
414 "node_mix_clamp_color",
425 const bool clamp_factor_;
426 const bool clamp_result_;
427 const int blend_type_;
431 : clamp_factor_(clamp_factor), clamp_result_(clamp_result), blend_type_(blend_type)
433 static const mf::Signature
signature = []() {
435 mf::SignatureBuilder builder{
"MixColor",
signature};
436 builder.single_input<
float>(
"Factor");
455 results[
i] = col1[
i];
456 ramp_blend(blend_type_, results[
i], std::clamp(fac[
i], 0.0f, 1.0f), col2[
i]);
461 results[
i] = col1[
i];
477 const bool clamp_factor =
data->clamp_factor;
478 switch (
data->data_type) {
481 static auto fn = mf::build::SI3_SO<float, float, float, float>(
482 "Clamp Mix Float", [](
float t,
const float a,
const float b) {
487 static auto fn = mf::build::SI3_SO<float, float, float, float>(
494 if (uniform_factor) {
495 static auto fn = mf::build::SI3_SO<float, float3, float3, float3>(
496 "Clamp Mix Vector", [](
const float t,
const float3 a,
const float3 b) {
501 static auto fn = mf::build::SI3_SO<float3, float3, float3, float3>(
504 return a * (
float3(1.0f) - t) +
b * t;
508 if (uniform_factor) {
509 static auto fn = mf::build::SI3_SO<float, float3, float3, float3>(
510 "Mix Vector", [](
const float t,
const float3 a,
const float3 b) {
515 static auto fn = mf::build::SI3_SO<float3, float3, float3, float3>(
517 return a * (
float3(1.0f) - t) +
b * t;
524 mf::build::SI3_SO<float, math::Quaternion, math::Quaternion, math::Quaternion>(
525 "Clamp Mix Rotation",
532 mf::build::SI3_SO<float, math::Quaternion, math::Quaternion, math::Quaternion>(
563 NodeItem factor = empty();
564 NodeItem value1 = empty();
565 NodeItem value2 = empty();
566 switch (
data->data_type) {
568 factor = get_input_value(0, NodeItem::Type::Float);
569 value1 = get_input_value(2, NodeItem::Type::Float);
570 value2 = get_input_value(3, NodeItem::Type::Float);
575 factor = get_input_value(0, NodeItem::Type::Float);
578 factor = get_input_value(1, NodeItem::Type::Vector3);
580 value1 = get_input_value(4, NodeItem::Type::Vector3);
581 value2 = get_input_value(5, NodeItem::Type::Vector3);
585 factor = get_input_value(0, NodeItem::Type::Float);
586 value1 = get_input_value(6, NodeItem::Type::Color3);
587 value2 = get_input_value(7, NodeItem::Type::Color3);
594 if (
data->clamp_factor) {
595 factor = factor.clamp();
597 NodeItem res = factor.mix(value1, value2);
601 if (
data->clamp_result) {
622 ntype.
declare = file_ns::sh_node_mix_declare;
623 ntype.
ui_class = file_ns::sh_node_mix_ui_class;
624 ntype.
gpu_fn = file_ns::gpu_shader_mix;
625 ntype.
updatefunc = file_ns::sh_node_mix_update;
626 ntype.
initfunc = file_ns::node_mix_init;
631 ntype.
labelfunc = file_ns::sh_node_mix_label;
General operations, lookup, etc. for materials.
void ramp_blend(int type, float r_col[3], float fac, const float col[3])
#define NODE_CLASS_CONVERTER
#define NODE_STORAGE_FUNCS(StorageT)
#define NODE_CLASS_OP_VECTOR
#define NODE_CLASS_OP_COLOR
#define BLI_assert_unreachable()
#define LISTBASE_FOREACH(type, var, list)
MINLINE void clamp_v3(float vec[3], float min, float max)
char * BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
#define BLT_I18NCONTEXT_ID_NODETREE
#define CTX_IFACE_(context, msgid)
@ NODE_MIX_MODE_NON_UNIFORM
bool GPU_stack_link(GPUMaterial *mat, const bNode *node, const char *name, GPUNodeStack *in, GPUNodeStack *out,...)
GPUNodeLink * GPU_constant(const float *num)
bool GPU_link(GPUMaterial *mat, const char *name,...)
GPUNodeLink * GPU_uniform(const float *num)
BMesh const char void * data
const Signature & signature() const
void set_signature(const Signature *signature)
void set_matching_fn(const mf::MultiFunction *fn)
void construct_and_set_matching_fn(Args &&...args)
bool is_default_link_socket
std::optional< std::string > translation_context
ColorGeometry4f default_value
void call(const IndexMask &mask, mf::Params params, mf::Context) const override
MixColorFunction(const bool clamp_factor, const bool clamp_result, const int blend_type)
void operator()(LinkSearchOpParams ¶ms)
void * MEM_callocN(size_t len, const char *str)
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
void node_register_type(bNodeType &ntype)
void node_set_socket_availability(bNodeTree &ntree, bNodeSocket &sock, bool is_available)
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))
QuaternionBase< float > Quaternion
T clamp(const T &a, const T &min, const T &max)
T interpolate(const T &a, const T &b, const FactorT &t)
static const char * gpu_shader_get_name(eNodeSocketDatatype data_type, const bool non_uniform, const int blend_type)
static void node_mix_init(bNodeTree *, bNode *node)
static int sh_node_mix_ui_class(const bNode *node)
static void node_mix_gather_link_searches(GatherLinkSearchOpParams ¶ms)
static void sh_node_mix_build_multi_function(NodeMultiFunctionBuilder &builder)
static void sh_node_mix_layout(uiLayout *layout, bContext *, PointerRNA *ptr)
static const mf::MultiFunction * get_multi_function(const bNode &node)
static int gpu_shader_mix(GPUMaterial *mat, bNode *node, bNodeExecData *, GPUNodeStack *in, GPUNodeStack *out)
static void sh_node_mix_declare(NodeDeclarationBuilder &b)
static void sh_node_mix_update(bNodeTree *ntree, bNode *node)
static void sh_node_mix_label(const bNodeTree *, const bNode *node, char *label, int label_maxncpy)
ColorSceneLinear4f< eAlpha::Premultiplied > ColorGeometry4f
VecBase< float, 3 > float3
#define NODE_SHADER_MATERIALX_BEGIN
#define NODE_SHADER_MATERIALX_END
void register_node_type_sh_mix()
void common_node_type_base(blender::bke::bNodeType *ntype, std::string idname, const std::optional< int16_t > legacy_type)
void node_free_standard_storage(bNode *node)
void node_copy_standard_storage(bNodeTree *, bNode *dest_node, const bNode *src_node)
bool RNA_enum_name(const EnumPropertyItem *item, const int value, const char **r_name)
const EnumPropertyItem rna_enum_ramp_blend_items[]
struct bNodeSocket * next
NodeMaterialXFunction materialx_fn
std::string ui_description
int(* ui_class)(const bNode *node)
void(* initfunc)(bNodeTree *ntree, bNode *node)
void(* labelfunc)(const bNodeTree *ntree, const bNode *node, char *label, int label_maxncpy)
NodeGPUExecFunction gpu_fn
NodeMultiFunctionBuildFunction build_multi_function
const char * enum_name_legacy
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
NodeGatherSocketLinkOperationsFunction gather_link_search_ops
NodeDeclareFunction declare
void(* updatefunc)(bNodeTree *ntree, bNode *node)
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)