Blender  V3.3
node_shader_math.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2005 Blender Foundation. All rights reserved. */
3 
8 #include "node_shader_util.hh"
9 
10 #include "NOD_math_functions.hh"
12 
13 #include "RNA_enum_types.h"
14 
15 /* **************** SCALAR MATH ******************** */
16 
18 
20 {
21  b.is_function_node();
22  b.add_input<decl::Float>(N_("Value")).default_value(0.5f).min(-10000.0f).max(10000.0f);
23  b.add_input<decl::Float>(N_("Value"), "Value_001")
24  .default_value(0.5f)
25  .min(-10000.0f)
26  .max(10000.0f);
27  b.add_input<decl::Float>(N_("Value"), "Value_002")
28  .default_value(0.5f)
29  .min(-10000.0f)
30  .max(10000.0f);
31  b.add_output<decl::Float>(N_("Value"));
32 }
33 
35  public:
36  std::string socket_name;
39  {
40  bNode &node = params.add_node("ShaderNodeMath");
41  node.custom1 = mode;
42  params.update_and_connect_available_socket(node, socket_name);
43  }
44 };
45 
47 {
48  if (!params.node_tree().typeinfo->validate_link(
49  static_cast<eNodeSocketDatatype>(params.other_socket().type), SOCK_FLOAT)) {
50  return;
51  }
52 
53  const bool is_geometry_node_tree = params.node_tree().type == NTREE_GEOMETRY;
54  const int weight = ELEM(params.other_socket().type, SOCK_FLOAT, SOCK_BOOLEAN, SOCK_INT) ? 0 : -1;
55 
56  for (const EnumPropertyItem *item = rna_enum_node_math_items; item->identifier != nullptr;
57  item++) {
58  if (item->name != nullptr && item->identifier[0] != '\0') {
59  const int gn_weight =
60  (is_geometry_node_tree &&
62  -1 :
63  weight;
64  params.add_item(CTX_IFACE_(BLT_I18NCONTEXT_ID_NODETREE, item->name),
65  SocketSearchOp{"Value", (NodeMathOperation)item->value},
66  gn_weight);
67  }
68  }
69 }
70 
71 static const char *gpu_shader_get_name(int mode)
72 {
74  if (!info) {
75  return nullptr;
76  }
77  if (info->shader_name.is_empty()) {
78  return nullptr;
79  }
80  return info->shader_name.c_str();
81 }
82 
83 static int gpu_shader_math(GPUMaterial *mat,
84  bNode *node,
85  bNodeExecData *UNUSED(execdata),
86  GPUNodeStack *in,
88 {
89  const char *name = gpu_shader_get_name(node->custom1);
90  if (name != nullptr) {
91  int ret = GPU_stack_link(mat, node, name, in, out);
92 
93  if (ret && node->custom2 & SHD_MATH_CLAMP) {
94  float min[3] = {0.0f, 0.0f, 0.0f};
95  float max[3] = {1.0f, 1.0f, 1.0f};
96  GPU_link(
97  mat, "clamp_value", out[0].link, GPU_constant(min), GPU_constant(max), &out[0].link);
98  }
99  return ret;
100  }
101 
102  return 0;
103 }
104 
106 {
107  const int mode = node.custom1;
108  const fn::MultiFunction *base_fn = nullptr;
109 
111  mode, [&](auto devi_fn, auto function, const FloatMathOperationInfo &info) {
113  info.title_case_name.c_str(), function, devi_fn};
114  base_fn = &fn;
115  });
116  if (base_fn != nullptr) {
117  return base_fn;
118  }
119 
121  mode, [&](auto devi_fn, auto function, const FloatMathOperationInfo &info) {
123  info.title_case_name.c_str(), function, devi_fn};
124  base_fn = &fn;
125  });
126  if (base_fn != nullptr) {
127  return base_fn;
128  }
129 
131  mode, [&](auto devi_fn, auto function, const FloatMathOperationInfo &info) {
133  info.title_case_name.c_str(), function, devi_fn};
134  base_fn = &fn;
135  });
136  if (base_fn != nullptr) {
137  return base_fn;
138  }
139 
140  return nullptr;
141 }
142 
144  private:
145  const fn::MultiFunction &fn_;
146 
147  public:
149  {
150  this->set_signature(&fn.signature());
151  }
152 
154  {
155  fn_.call(mask, params, context);
156 
157  /* Assumes the output parameter is the last one. */
158  const int output_param_index = this->param_amount() - 1;
159  /* This has actually been initialized in the call above. */
160  MutableSpan<float> results = params.uninitialized_single_output<float>(output_param_index);
161 
162  for (const int i : mask) {
163  float &value = results[i];
164  CLAMP(value, 0.0f, 1.0f);
165  }
166  }
167 };
168 
170 {
171  const fn::MultiFunction *base_function = get_base_multi_function(builder.node());
172 
173  const bool clamp_output = builder.node().custom2 != 0;
174  if (clamp_output) {
175  builder.construct_and_set_matching_fn<ClampWrapperFunction>(*base_function);
176  }
177  else {
178  builder.set_matching_fn(base_function);
179  }
180 }
181 
182 } // namespace blender::nodes::node_shader_math_cc
183 
185 {
186  namespace file_ns = blender::nodes::node_shader_math_cc;
187 
188  static bNodeType ntype;
189 
192  ntype.labelfunc = node_math_label;
197 
198  nodeRegisterType(&ntype);
199 }
void node_type_gpu(struct bNodeType *ntype, NodeGPUExecFunction gpu_fn)
Definition: node.cc:4465
void node_type_update(struct bNodeType *ntype, void(*updatefunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4443
#define NODE_CLASS_CONVERTER
Definition: BKE_node.h:351
#define SH_NODE_MATH
Definition: BKE_node.h:1092
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1357
#define UNUSED(x)
#define ELEM(...)
#define BLT_I18NCONTEXT_ID_NODETREE
#define CTX_IFACE_(context, msgid)
NodeMathOperation
@ NODE_MATH_GREATER_THAN
@ NODE_MATH_ADD
@ NODE_MATH_LESS_THAN
@ NODE_MATH_COMPARE
#define NTREE_GEOMETRY
#define SHD_MATH_CLAMP
eNodeSocketDatatype
@ SOCK_INT
@ SOCK_BOOLEAN
@ SOCK_FLOAT
GPUNodeLink * GPU_constant(const float *num)
bool GPU_link(GPUMaterial *mat, const char *name,...)
bool GPU_stack_link(GPUMaterial *mat, struct bNode *node, const char *name, GPUNodeStack *in, GPUNodeStack *out,...)
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position CLAMP
constexpr bool is_empty() const
constexpr const char * c_str() const
void set_signature(const MFSignature *signature)
virtual void call(IndexMask mask, MFParams params, MFContext context) const =0
const MFSignature & signature() const
void set_matching_fn(const MultiFunction *fn)
void call(IndexMask mask, fn::MFParams params, fn::MFContext context) const override
OperationNode * node
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
static const char * gpu_shader_get_name(int mode)
static void sh_node_math_gather_link_searches(GatherLinkSearchOpParams &params)
static int gpu_shader_math(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
static void sh_node_math_build_multi_function(NodeMultiFunctionBuilder &builder)
static void sh_node_math_declare(NodeDeclarationBuilder &b)
static const fn::MultiFunction * get_base_multi_function(bNode &node)
bool try_dispatch_float_math_fl_fl_to_fl(const int operation, Callback &&callback)
bool try_dispatch_float_math_fl_to_fl(const int operation, Callback &&callback)
const FloatMathOperationInfo * get_float_math_operation_info(const int operation)
bool try_dispatch_float_math_fl_fl_fl_to_fl(const int operation, Callback &&callback)
static const pxr::TfToken out("out", pxr::TfToken::Immortal)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
void register_node_type_sh_math()
void sh_fn_node_type_base(bNodeType *ntype, int type, const char *name, short nclass)
void node_math_update(bNodeTree *ntree, bNode *node)
Definition: node_util.c:88
void node_math_label(const bNodeTree *UNUSED(ntree), const bNode *node, char *label, int maxlen)
Definition: node_util.c:196
return ret
const EnumPropertyItem rna_enum_node_math_items[]
Definition: rna_nodetree.c:166
#define min(a, b)
Definition: sort.c:35
const char * identifier
Definition: RNA_types.h:461
Defines a node type.
Definition: BKE_node.h:226
NodeGatherSocketLinkOperationsFunction gather_link_search_ops
Definition: BKE_node.h:335
void(* labelfunc)(const struct bNodeTree *ntree, const struct bNode *node, char *label, int maxlen)
Definition: BKE_node.h:256
NodeMultiFunctionBuildFunction build_multi_function
Definition: BKE_node.h:313
NodeDeclareFunction declare
Definition: BKE_node.h:324
short custom2
float max
#define N_(msgid)