49 .description(
"Amount of mixing between the A and B inputs");
51 .default_value(
float3(0.5f))
54 .
description(
"Amount of mixing between the A and B vector inputs");
61 .description(
"Value of the first floating number input");
66 .description(
"Value of the second floating number input");
69 .is_default_link_socket()
71 .description(
"Value of the first vector input");
77 .default_value({0.5f, 0.5f, 0.5f, 1.0f})
78 .is_default_link_socket()
80 .description(
"Value of the first color input");
82 .default_value({0.5f, 0.5f, 0.5f, 1.0f})
87 .is_default_link_socket()
101 switch (data.data_type) {
158 bool use_vector_factor = data_type ==
SOCK_VECTOR &&
165 for (
bNodeSocket *socket = sock_factor_vec->
next; socket !=
nullptr; socket = socket->next) {
181 node_storage(node).data_type =
SOCK_RGBA;
182 node_storage(node).blend_type =
type;
213 node_storage(node).data_type = type;
214 params.update_and_connect_available_socket(node,
"Result");
222 node_storage(node).data_type = type;
223 params.update_and_connect_available_socket(node,
"A");
231 node_storage(node).data_type = type;
232 params.update_and_connect_available_socket(node,
"B");
238 IFACE_(
"Factor (Non-Uniform)"),
243 params.update_and_connect_available_socket(node,
"Factor");
253 node_storage(node).data_type = type;
254 params.update_and_connect_available_socket(node,
"Factor");
268 const std::string socket_name =
params.in_out() ==
SOCK_IN ?
"A" :
"Result";
272 if (item->name !=
nullptr && item->identifier[0] !=
'\0') {
283 data->clamp_factor = 1;
284 data->clamp_result = 0;
286 node->storage =
data;
290 const bool non_uniform,
291 const int blend_type)
295 return "node_mix_float";
297 return (non_uniform) ?
"node_mix_vector_non_uniform" :
"node_mix_vector";
299 switch (blend_type) {
301 return "node_mix_blend";
303 return "node_mix_add";
305 return "node_mix_mult";
307 return "node_mix_sub";
309 return "node_mix_screen";
311 return "node_mix_div_fallback";
313 return "node_mix_diff";
315 return "node_mix_exclusion";
317 return "node_mix_dark";
319 return "node_mix_light";
321 return "node_mix_overlay";
323 return "node_mix_dodge";
325 return "node_mix_burn";
327 return "node_mix_hue";
329 return "node_mix_sat";
331 return "node_mix_val";
333 return "node_mix_color";
335 return "node_mix_soft";
337 return "node_mix_linear";
364 if (name ==
nullptr) {
369 if (is_non_uniform && is_vector_mode) {
370 const float min[3] = {0.0f, 0.0f, 0.0f};
371 const float max[3] = {1.0f, 1.0f, 1.0f};
374 "node_mix_clamp_vector",
381 const float min = 0.0f;
382 const float max = 1.0f;
385 "node_mix_clamp_value",
396 const float min[3] = {0.0f, 0.0f, 0.0f};
397 const float max[3] = {1.0f, 1.0f, 1.0f};
399 "node_mix_clamp_vector",
410 const bool clamp_factor_;
411 const bool clamp_result_;
412 const int blend_type_;
416 : clamp_factor_(clamp_factor), clamp_result_(clamp_result), blend_type_(blend_type)
421 builder.single_input<
float>(
"Factor");
440 results[i] = col1[i];
441 ramp_blend(blend_type_, results[i], std::clamp(fac[i], 0.0f, 1.0f), col2[i]);
446 results[i] = col1[i];
447 ramp_blend(blend_type_, results[i], fac[i], col2[i]);
452 mask.foreach_index_optimized<
int64_t>(
462 const bool clamp_factor = data->clamp_factor;
463 switch (data->data_type) {
466 static auto fn = mf::build::SI3_SO<float, float, float, float>(
467 "Clamp Mix Float", [](
float t,
const float a,
const float b) {
473 static auto fn = mf::build::SI3_SO<float, float, float, float>(
474 "Mix Float", [](
const float t,
const float a,
const float b) {
482 if (uniform_factor) {
483 static auto fn = mf::build::SI3_SO<float, float3, float3, float3>(
484 "Clamp Mix Vector", [](
const float t,
const float3 a,
const float3 b) {
490 static auto fn = mf::build::SI3_SO<float3, float3, float3, float3>(
493 return a * (
float3(1.0f) - t) +
b * t;
499 if (uniform_factor) {
500 static auto fn = mf::build::SI3_SO<float, float3, float3, float3>(
501 "Mix Vector", [](
const float t,
const float3 a,
const float3 b) {
507 static auto fn = mf::build::SI3_SO<float3, float3, float3, float3>(
509 return a * (
float3(1.0f) - t) +
b * t;
518 mf::build::SI3_SO<float, math::Quaternion, math::Quaternion, math::Quaternion>(
519 "Clamp Mix Rotation",
527 mf::build::SI3_SO<float, math::Quaternion, math::Quaternion, math::Quaternion>(
559 NodeItem factor = empty();
560 NodeItem value1 = empty();
561 NodeItem value2 = empty();
562 switch (data->data_type) {
564 factor = get_input_value(0, NodeItem::Type::Float);
565 value1 = get_input_value(2, NodeItem::Type::Float);
566 value2 = get_input_value(3, NodeItem::Type::Float);
571 factor = get_input_value(0, NodeItem::Type::Float);
574 factor = get_input_value(1, NodeItem::Type::Vector3);
576 value1 = get_input_value(4, NodeItem::Type::Vector3);
577 value2 = get_input_value(5, NodeItem::Type::Vector3);
581 factor = get_input_value(0, NodeItem::Type::Float);
582 value1 = get_input_value(6, NodeItem::Type::Color4);
583 value2 = get_input_value(7, NodeItem::Type::Color4);
590 if (data->clamp_factor) {
591 factor = factor.clamp();
593 NodeItem res = factor.mix(value1, value2);
597 if (data->clamp_result) {
614 ntype.
declare = file_ns::sh_node_mix_declare;
615 ntype.
ui_class = file_ns::sh_node_mix_ui_class;
616 ntype.
gpu_fn = file_ns::gpu_shader_mix;
617 ntype.
updatefunc = file_ns::sh_node_mix_update;
618 ntype.
initfunc = file_ns::node_mix_init;
623 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)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
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::string translation_context
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)
local_group_size(16, 16) .push_constant(Type b
void node_set_socket_availability(bNodeTree *ntree, bNodeSocket *sock, bool is_available)
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))
void node_register_type(bNodeType *ntype)
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)
VecBase< float, 3 > float3
#define NODE_SHADER_MATERIALX_BEGIN
#define NODE_SHADER_MATERIALX_END
void register_node_type_sh_mix()
void sh_fn_node_type_base(blender::bke::bNodeType *ntype, int type, const char *name, short nclass)
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
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
void(* draw_buttons)(uiLayout *, bContext *C, PointerRNA *ptr)
NodeGatherSocketLinkOperationsFunction gather_link_search_ops
NodeDeclareFunction declare
void(* updatefunc)(bNodeTree *ntree, bNode *node)