Blender  V2.93
node_shader_math.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2005 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include "node_shader_util.h"
25 
26 #include "NOD_math_functions.hh"
27 
28 /* **************** SCALAR MATH ******************** */
30  {SOCK_FLOAT, N_("Value"), 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
31  {SOCK_FLOAT, N_("Value"), 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
32  {SOCK_FLOAT, N_("Value"), 0.0f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
33  {-1, ""}};
34 
35 static bNodeSocketTemplate sh_node_math_out[] = {{SOCK_FLOAT, N_("Value")}, {-1, ""}};
36 
37 static const char *gpu_shader_get_name(int mode)
38 {
41  if (!info) {
42  return nullptr;
43  }
44  if (info->shader_name.is_empty()) {
45  return nullptr;
46  }
47  return info->shader_name.c_str();
48 }
49 
50 static int gpu_shader_math(GPUMaterial *mat,
51  bNode *node,
52  bNodeExecData *UNUSED(execdata),
53  GPUNodeStack *in,
54  GPUNodeStack *out)
55 {
56  const char *name = gpu_shader_get_name(node->custom1);
57  if (name != nullptr) {
58  int ret = GPU_stack_link(mat, node, name, in, out);
59 
60  if (ret && node->custom2 & SHD_MATH_CLAMP) {
61  float min[3] = {0.0f, 0.0f, 0.0f};
62  float max[3] = {1.0f, 1.0f, 1.0f};
63  GPU_link(
64  mat, "clamp_value", out[0].link, GPU_constant(min), GPU_constant(max), &out[0].link);
65  }
66  return ret;
67  }
68 
69  return 0;
70 }
71 
74 {
75  const int mode = builder.bnode().custom1;
76 
77  const blender::fn::MultiFunction *base_fn = nullptr;
78 
80  mode, [&](auto function, const blender::nodes::FloatMathOperationInfo &info) {
82  base_fn = &fn;
83  });
84  if (base_fn != nullptr) {
85  return *base_fn;
86  }
87 
89  mode, [&](auto function, const blender::nodes::FloatMathOperationInfo &info) {
91  function};
92  base_fn = &fn;
93  });
94  if (base_fn != nullptr) {
95  return *base_fn;
96  }
97 
99  mode, [&](auto function, const blender::nodes::FloatMathOperationInfo &info) {
101  info.title_case_name, function};
102  base_fn = &fn;
103  });
104  if (base_fn != nullptr) {
105  return *base_fn;
106  }
107 
108  return builder.get_not_implemented_fn();
109 }
110 
112 {
113  const blender::fn::MultiFunction &base_function = get_base_multi_function(builder);
114 
115  const blender::nodes::DNode &dnode = builder.dnode();
116  blender::fn::MFNetwork &network = builder.network();
117  blender::fn::MFFunctionNode &base_node = network.add_function(base_function);
118 
119  builder.network_map().add_try_match(*dnode.context(), dnode->inputs(), base_node.inputs());
120 
121  const bool clamp_output = builder.bnode().custom2 != 0;
122  if (clamp_output) {
123  static blender::fn::CustomMF_SI_SO<float, float> clamp_fn{"Clamp", [](float value) {
124  CLAMP(value, 0.0f, 1.0f);
125  return value;
126  }};
127  blender::fn::MFFunctionNode &clamp_node = network.add_function(clamp_fn);
128  network.add_link(base_node.output(0), clamp_node.input(0));
129  builder.network_map().add(blender::nodes::DOutputSocket(dnode.context(), &dnode->output(0)),
130  clamp_node.output(0));
131  }
132  else {
133  builder.network_map().add(blender::nodes::DOutputSocket(dnode.context(), &dnode->output(0)),
134  base_node.output(0));
135  }
136 }
137 
139 {
140  static bNodeType ntype;
141 
148 
149  nodeRegisterType(&ntype);
150 }
void node_type_gpu(struct bNodeType *ntype, NodeGPUExecFunction gpu_fn)
Definition: node.cc:4645
void node_type_socket_templates(struct bNodeType *ntype, struct bNodeSocketTemplate *inputs, struct bNodeSocketTemplate *outputs)
Definition: node.cc:4527
void node_type_update(struct bNodeType *ntype, void(*updatefunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4623
#define SH_NODE_MATH
Definition: BKE_node.h:985
#define NODE_CLASS_CONVERTOR
Definition: BKE_node.h:341
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1298
void node_type_label(struct bNodeType *ntype, void(*labelfunc)(struct bNodeTree *ntree, struct bNode *, char *label, int maxlen))
#define UNUSED(x)
#define N_(msgid)
#define SHD_MATH_CLAMP
@ 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 RGB to Bright Vector Camera CLAMP
@ PROP_NONE
Definition: RNA_types.h:113
constexpr bool is_empty() const
constexpr const char * c_str() const
void add_link(MFOutputSocket &from, MFInputSocket &to)
MFFunctionNode & add_function(const MultiFunction &function)
Span< MFInputSocket * > inputs()
MFOutputSocket & output(int index)
MFInputSocket & input(int index)
const DTreeContext * context() const
void add(const DSocket &dsocket, fn::MFSocket &socket)
void add_try_match(const DNode &dnode, fn::MFNode &node)
const OutputSocketRef & output(int index) const
Span< const InputSocketRef * > inputs() const
OperationNode * 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 char * gpu_shader_get_name(int mode)
static bNodeSocketTemplate sh_node_math_out[]
static int gpu_shader_math(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
void register_node_type_sh_math(void)
static const blender::fn::MultiFunction & get_base_multi_function(blender::nodes::NodeMFNetworkBuilder &builder)
static void sh_node_math_expand_in_mf_network(blender::nodes::NodeMFNetworkBuilder &builder)
static bNodeSocketTemplate sh_node_math_in[]
void sh_fn_node_type_base(bNodeType *ntype, int type, const char *name, short nclass, short flag)
void node_math_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen)
Definition: node_util.c:206
void node_math_update(bNodeTree *UNUSED(ntree), bNode *node)
Definition: node_util.c:100
return ret
#define min(a, b)
Definition: sort.c:51
Compact definition of a node socket.
Definition: BKE_node.h:95
Defines a node type.
Definition: BKE_node.h:221
NodeExpandInMFNetworkFunction expand_in_mf_network
Definition: BKE_node.h:324
short custom1
short custom2
float max