Blender  V3.3
node_shader_bsdf_principled.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 
4 #include "node_shader_util.hh"
5 
6 #include "UI_interface.h"
7 #include "UI_resources.h"
8 
10 
12 {
13  b.add_input<decl::Color>(N_("Base Color")).default_value({0.8f, 0.8f, 0.8f, 1.0f});
14  b.add_input<decl::Float>(N_("Subsurface"))
15  .default_value(0.0f)
16  .min(0.0f)
17  .max(1.0f)
18  .subtype(PROP_FACTOR);
19  b.add_input<decl::Vector>(N_("Subsurface Radius"))
20  .default_value({1.0f, 0.2f, 0.1f})
21  .min(0.0f)
22  .max(100.0f)
23  .compact();
24  b.add_input<decl::Color>(N_("Subsurface Color")).default_value({0.8f, 0.8f, 0.8f, 1.0f});
25  b.add_input<decl::Float>(N_("Subsurface IOR"))
26  .default_value(1.4f)
27  .min(1.01f)
28  .max(3.8f)
29  .subtype(PROP_FACTOR);
30  b.add_input<decl::Float>(N_("Subsurface Anisotropy"))
31  .default_value(0.0f)
32  .min(0.0f)
33  .max(1.0f)
34  .subtype(PROP_FACTOR);
35  b.add_input<decl::Float>(N_("Metallic"))
36  .default_value(0.0f)
37  .min(0.0f)
38  .max(1.0f)
39  .subtype(PROP_FACTOR);
40  b.add_input<decl::Float>(N_("Specular"))
41  .default_value(0.5f)
42  .min(0.0f)
43  .max(1.0f)
44  .subtype(PROP_FACTOR);
45  b.add_input<decl::Float>(N_("Specular Tint"))
46  .default_value(0.0f)
47  .min(0.0f)
48  .max(1.0f)
49  .subtype(PROP_FACTOR);
50  b.add_input<decl::Float>(N_("Roughness"))
51  .default_value(0.5f)
52  .min(0.0f)
53  .max(1.0f)
54  .subtype(PROP_FACTOR);
55  b.add_input<decl::Float>(N_("Anisotropic"))
56  .default_value(0.0f)
57  .min(0.0f)
58  .max(1.0f)
59  .subtype(PROP_FACTOR);
60  b.add_input<decl::Float>(N_("Anisotropic Rotation"))
61  .default_value(0.0f)
62  .min(0.0f)
63  .max(1.0f)
64  .subtype(PROP_FACTOR);
65  b.add_input<decl::Float>(N_("Sheen"))
66  .default_value(0.0f)
67  .min(0.0f)
68  .max(1.0f)
69  .subtype(PROP_FACTOR);
70  b.add_input<decl::Float>(N_("Sheen Tint"))
71  .default_value(0.5f)
72  .min(0.0f)
73  .max(1.0f)
74  .subtype(PROP_FACTOR);
75  b.add_input<decl::Float>(N_("Clearcoat"))
76  .default_value(0.0f)
77  .min(0.0f)
78  .max(1.0f)
79  .subtype(PROP_FACTOR);
80  b.add_input<decl::Float>(N_("Clearcoat Roughness"))
81  .default_value(0.03f)
82  .min(0.0f)
83  .max(1.0f)
84  .subtype(PROP_FACTOR);
85  b.add_input<decl::Float>(N_("IOR")).default_value(1.45f).min(0.0f).max(1000.0f);
86  b.add_input<decl::Float>(N_("Transmission"))
87  .default_value(0.0f)
88  .min(0.0f)
89  .max(1.0f)
90  .subtype(PROP_FACTOR);
91  b.add_input<decl::Float>(N_("Transmission Roughness"))
92  .default_value(0.0f)
93  .min(0.0f)
94  .max(1.0f)
95  .subtype(PROP_FACTOR);
96  b.add_input<decl::Color>(N_("Emission")).default_value({0.0f, 0.0f, 0.0f, 1.0f});
97  b.add_input<decl::Float>(N_("Emission Strength")).default_value(1.0).min(0.0f).max(1000000.0f);
98  b.add_input<decl::Float>(N_("Alpha"))
99  .default_value(1.0f)
100  .min(0.0f)
101  .max(1.0f)
102  .subtype(PROP_FACTOR);
103  b.add_input<decl::Vector>(N_("Normal")).hide_value();
104  b.add_input<decl::Vector>(N_("Clearcoat Normal")).hide_value();
105  b.add_input<decl::Vector>(N_("Tangent")).hide_value();
106  b.add_input<decl::Float>(N_("Weight")).unavailable();
107  b.add_output<decl::Shader>(N_("BSDF"));
108 }
109 
111 {
112  uiItemR(layout, ptr, "distribution", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
113  uiItemR(layout, ptr, "subsurface_method", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
114 }
115 
117 {
118  node->custom1 = SHD_GLOSSY_GGX;
119  node->custom2 = SHD_SUBSURFACE_RANDOM_WALK;
120 }
121 
122 #define socket_not_zero(sock) (in[sock].link || (clamp_f(in[sock].vec[0], 0.0f, 1.0f) > 1e-5f))
123 #define socket_not_one(sock) \
124  (in[sock].link || (clamp_f(in[sock].vec[0], 0.0f, 1.0f) < 1.0f - 1e-5f))
125 
127  bNode *node,
128  bNodeExecData *UNUSED(execdata),
129  GPUNodeStack *in,
130  GPUNodeStack *out)
131 {
132  /* Normals */
133  if (!in[22].link) {
134  GPU_link(mat, "world_normals_get", &in[22].link);
135  }
136 
137  /* Clearcoat Normals */
138  if (!in[23].link) {
139  GPU_link(mat, "world_normals_get", &in[23].link);
140  }
141 
142 #if 0 /* Not used at the moment. */
143  /* Tangents */
144  if (!in[24].link) {
145  GPUNodeLink *orco = GPU_attribute(CD_ORCO, "");
146  GPU_link(mat, "tangent_orco_z", orco, &in[24].link);
147  GPU_link(mat, "node_tangent", in[24].link, &in[24].link);
148  }
149 #endif
150 
151  bool use_diffuse = socket_not_one(6) && socket_not_one(17);
152  bool use_subsurf = socket_not_zero(1) && use_diffuse;
153  bool use_refract = socket_not_one(6) && socket_not_zero(17);
154  bool use_transparency = socket_not_one(21);
155  bool use_clear = socket_not_zero(14);
156 
158  if (use_diffuse) {
159  flag |= GPU_MATFLAG_DIFFUSE;
160  }
161  if (use_refract) {
162  flag |= GPU_MATFLAG_REFRACT;
163  }
164  if (use_subsurf) {
165  flag |= GPU_MATFLAG_SUBSURFACE;
166  }
167  if (use_transparency) {
168  flag |= GPU_MATFLAG_TRANSPARENT;
169  }
170  if (use_clear) {
171  flag |= GPU_MATFLAG_CLEARCOAT;
172  }
173 
174  /* Ref. T98190: Defines are optimizations for old compilers.
175  * Might become unecessary with EEVEE-Next. */
176  if (use_diffuse == false && use_refract == false && use_clear == true) {
178  }
179  else if (use_diffuse == false && use_refract == false && use_clear == false) {
181  }
182  else if (use_diffuse == true && use_refract == false && use_clear == false) {
184  }
185  else if (use_diffuse == false && use_refract == true && use_clear == false) {
187  }
188  else {
190  }
191 
192  if (use_subsurf) {
193  bNodeSocket *socket = (bNodeSocket *)BLI_findlink(&node->original->inputs, 2);
194  bNodeSocketValueRGBA *socket_data = (bNodeSocketValueRGBA *)socket->default_value;
195  /* For some reason it seems that the socket value is in ARGB format. */
196  use_subsurf = GPU_material_sss_profile_create(mat, &socket_data->value[1]);
197  }
198 
199  float use_multi_scatter = (node->custom1 == SHD_GLOSSY_MULTI_GGX) ? 1.0f : 0.0f;
200  float use_sss = (use_subsurf) ? 1.0f : 0.0f;
201  float use_diffuse_f = (use_diffuse) ? 1.0f : 0.0f;
202  float use_clear_f = (use_clear) ? 1.0f : 0.0f;
203  float use_refract_f = (use_refract) ? 1.0f : 0.0f;
204 
205  GPU_material_flag_set(mat, flag);
206 
207  return GPU_stack_link(mat,
208  node,
209  "node_bsdf_principled",
210  in,
211  out,
212  GPU_constant(&use_diffuse_f),
213  GPU_constant(&use_clear_f),
214  GPU_constant(&use_refract_f),
215  GPU_constant(&use_multi_scatter),
216  GPU_uniform(&use_sss));
217 }
218 
220 {
221  const int distribution = node->custom1;
222  const int sss_method = node->custom2;
223 
224  LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
225  if (STREQ(sock->name, "Transmission Roughness")) {
226  nodeSetSocketAvailability(ntree, sock, distribution == SHD_GLOSSY_GGX);
227  }
228 
229  if (STR_ELEM(sock->name, "Subsurface IOR", "Subsurface Anisotropy")) {
231  }
232  }
233 }
234 
235 } // namespace blender::nodes::node_shader_bsdf_principled_cc
236 
237 /* node type definition */
239 {
241 
242  static bNodeType ntype;
243 
244  sh_node_type_base(&ntype, SH_NODE_BSDF_PRINCIPLED, "Principled BSDF", NODE_CLASS_SHADER);
251 
252  nodeRegisterType(&ntype);
253 }
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 SH_NODE_BSDF_PRINCIPLED
Definition: BKE_node.h:1164
void nodeSetSocketAvailability(struct bNodeTree *ntree, struct bNodeSocket *sock, bool is_available)
Definition: node.cc:3664
void node_type_init(struct bNodeType *ntype, void(*initfunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4390
void node_type_size_preset(struct bNodeType *ntype, eNodeSizePreset size)
Definition: node.cc:4408
#define NODE_CLASS_SHADER
Definition: BKE_node.h:358
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1357
@ NODE_SIZE_LARGE
Definition: BKE_node.h:367
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define STR_ELEM(...)
Definition: BLI_string.h:539
#define UNUSED(x)
#define STREQ(a, b)
@ SHD_SUBSURFACE_BURLEY
@ SHD_SUBSURFACE_RANDOM_WALK
#define SHD_GLOSSY_GGX
#define SHD_GLOSSY_MULTI_GGX
GPUNodeLink * GPU_attribute(GPUMaterial *mat, eCustomDataType type, const char *name)
bool GPU_material_sss_profile_create(GPUMaterial *material, float radii[3])
Definition: gpu_material.c:438
GPUNodeLink * GPU_constant(const float *num)
eGPUMaterialFlag
Definition: GPU_material.h:70
@ GPU_MATFLAG_PRINCIPLED_GLASS
Definition: GPU_material.h:91
@ GPU_MATFLAG_GLOSSY
Definition: GPU_material.h:73
@ GPU_MATFLAG_PRINCIPLED_DIELECTRIC
Definition: GPU_material.h:90
@ GPU_MATFLAG_REFRACT
Definition: GPU_material.h:74
@ GPU_MATFLAG_PRINCIPLED_CLEARCOAT
Definition: GPU_material.h:88
@ GPU_MATFLAG_CLEARCOAT
Definition: GPU_material.h:80
@ GPU_MATFLAG_PRINCIPLED_ANY
Definition: GPU_material.h:92
@ GPU_MATFLAG_DIFFUSE
Definition: GPU_material.h:71
@ GPU_MATFLAG_TRANSPARENT
Definition: GPU_material.h:76
@ GPU_MATFLAG_SUBSURFACE
Definition: GPU_material.h:72
@ GPU_MATFLAG_PRINCIPLED_METALLIC
Definition: GPU_material.h:89
void GPU_material_flag_set(GPUMaterial *mat, eGPUMaterialFlag flag)
Definition: gpu_material.c:596
GPUNodeLink * GPU_uniform(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,...)
@ PROP_FACTOR
Definition: RNA_types.h:144
@ UI_ITEM_R_SPLIT_EMPTY_NAME
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
OperationNode * node
bNodeTree * ntree
static void node_shader_buts_principled(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
static void node_shader_init_principled(bNodeTree *UNUSED(ntree), bNode *node)
static void node_declare(NodeDeclarationBuilder &b)
static void node_shader_update_principled(bNodeTree *ntree, bNode *node)
static int node_shader_gpu_bsdf_principled(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
static const pxr::TfToken out("out", pxr::TfToken::Immortal)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
#define socket_not_one(sock)
#define socket_not_zero(sock)
void register_node_type_sh_bsdf_principled()
void sh_node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass)
#define min(a, b)
Definition: sort.c:35
void * default_value
Defines a node type.
Definition: BKE_node.h:226
void(* draw_buttons)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr)
Definition: BKE_node.h:244
NodeDeclareFunction declare
Definition: BKE_node.h:324
#define N_(msgid)
PointerRNA * ptr
Definition: wm_files.c:3480