Blender V4.3
node_shader_bsdf_principled.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2005 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include <map>
6
7#include "BLI_string.h"
8
9#include "node_shader_util.hh"
10
11#include "UI_interface.hh"
12#include "UI_resources.hh"
13
14#include "BKE_node_runtime.hh"
15
17
19{
25 b.use_custom_socket_order();
26
27 b.add_output<decl::Shader>("BSDF");
28
29 b.add_input<decl::Color>("Base Color")
30 .default_value({0.8f, 0.8f, 0.8f, 1.0f})
31 .description(
32 "Color of the material used for diffuse, subsurface, metallic and transmission");
33#define SOCK_BASE_COLOR_ID 0
34 b.add_input<decl::Float>("Metallic")
35 .default_value(0.0f)
36 .min(0.0f)
37 .max(1.0f)
39 .description(
40 "Blends between a dielectric and metallic material model. "
41 "At 0.0 the material consists of a diffuse or transmissive base layer, "
42 "with a specular reflection layer on top. A value of 1.0 gives a fully specular "
43 "reflection tinted with the base color, without diffuse reflection or transmission");
44#define SOCK_METALLIC_ID 1
45 b.add_input<decl::Float>("Roughness")
46 .default_value(0.5f)
47 .min(0.0f)
48 .max(1.0f)
50 .description(
51 "Specifies microfacet roughness of the surface for specular reflection and transmission"
52 " (0.0 is a perfect mirror reflection, 1.0 is completely rough)");
53#define SOCK_ROUGHNESS_ID 2
54 b.add_input<decl::Float>("IOR").default_value(1.5f).min(1.0f).max(1000.0f).description(
55 "Index of Refraction (IOR) for specular reflection and transmission. "
56 "For most materials, the IOR is between 1.0 (vacuum and air) and 4.0 (germanium). "
57 "The default value of 1.5 is a good approximation for glass");
58#define SOCK_IOR_ID 3
59 b.add_input<decl::Float>("Alpha")
60 .default_value(1.0f)
61 .min(0.0f)
62 .max(1.0f)
64 .description("Controls the transparency of the surface, with 1.0 fully opaque");
65#define SOCK_ALPHA_ID 4
66 b.add_input<decl::Vector>("Normal").hide_value();
67#define SOCK_NORMAL_ID 5
68 b.add_input<decl::Float>("Weight").available(false);
69#define SOCK_WEIGHT_ID 6
70
71 /* Panel for Diffuse settings. */
72 PanelDeclarationBuilder &diffuse = b.add_panel("Diffuse").default_closed(true);
73 diffuse.add_input<decl::Float>("Diffuse Roughness")
74 .default_value(0.0f)
75 .min(0.0f)
76 .max(1.0f)
78 .description(
79 "Specifies microfacet roughness of the diffuse base"
80 " (0.0 is perfect lambertian reflection, 1.0 is completely rough)");
81#define SOCK_DIFFUSE_ROUGHNESS_ID 7
82
83 /* Panel for Subsurface scattering settings. */
85 b.add_panel("Subsurface")
86 .default_closed(true)
87 .draw_buttons([](uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) {
88 uiItemR(layout, ptr, "subsurface_method", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
89 });
90 sss.add_input<decl::Float>("Subsurface Weight")
91 .default_value(0.0f)
92 .min(0.0f)
93 .max(1.0f)
95 .short_label("Weight")
96 .description(
97 "Blend between diffuse surface and subsurface scattering. "
98 "Typically should be zero or one (either fully diffuse or subsurface)");
99#define SOCK_SUBSURFACE_WEIGHT_ID 8
100 sss.add_input<decl::Vector>("Subsurface Radius")
101 .default_value({1.0f, 0.2f, 0.1f})
102 .min(0.0f)
103 .max(100.0f)
104 .short_label("Radius")
105 .description("Scattering radius to use for subsurface component (multiplied with Scale)");
106#define SOCK_SUBSURFACE_RADIUS_ID 9
107 sss.add_input<decl::Float>("Subsurface Scale")
108 .default_value(0.05f)
109 .min(0.0f)
110 .max(10.0f)
112 .short_label("Scale")
113 .description("Scale of the subsurface scattering (multiplied with Radius)");
114#define SOCK_SUBSURFACE_SCALE_ID 10
115 sss.add_input<decl::Float>("Subsurface IOR")
116 .default_value(1.4f)
117 .min(1.01f)
118 .max(3.8f)
120 .short_label("IOR")
121 .description("Index of Refraction (IOR) used for rays that enter the subsurface component");
122#define SOCK_SUBSURFACE_IOR_ID 11
123 sss.add_input<decl::Float>("Subsurface Anisotropy")
124 .default_value(0.0f)
125 .min(0.0f)
126 .max(1.0f)
128 .short_label("Anisotropy")
129 .description(
130 "Directionality of volume scattering within the subsurface medium. "
131 "Zero scatters uniformly in all directions, with higher values "
132 "scattering more strongly forward. For example, skin has been measured "
133 "to have an anisotropy of 0.8");
134#define SOCK_SUBSURFACE_ANISOTROPY_ID 12
135
136 /* Panel for Specular settings. */
138 b.add_panel("Specular")
139 .default_closed(true)
140 .draw_buttons([](uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) {
141 uiItemR(layout, ptr, "distribution", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
142 });
143 spec.add_input<decl::Float>("Specular IOR Level")
144 .default_value(0.5f)
145 .min(0.0f)
146 .max(1.0f)
148 .short_label("IOR Level")
149 .description(
150 "Adjustment to the Index of Refraction (IOR) to increase or decrease specular intensity "
151 "(0.5 means no adjustment, 0 removes all reflections, 1 doubles them at normal "
152 "incidence)");
153#define SOCK_SPECULAR_ID 13
154 spec.add_input<decl::Color>("Specular Tint")
155 .default_value({1.0f, 1.0f, 1.0f, 1.0f})
156 .short_label("Tint")
158 "Tint dielectric reflection at normal incidence for artistic control, and metallic "
159 "reflection at near-grazing incidence to simulate complex index of refraction")
160 .translation_context(BLT_I18NCONTEXT_ID_NODETREE);
161#define SOCK_SPECULAR_TINT_ID 14
162 spec.add_input<decl::Float>("Anisotropic")
163 .default_value(0.0f)
164 .min(0.0f)
165 .max(1.0f)
167 .description(
168 "Amount of anisotropy for specular reflection. "
169 "Higher values give elongated highlights along the tangent direction");
170#define SOCK_ANISOTROPIC_ID 15
171 spec.add_input<decl::Float>("Anisotropic Rotation")
172 .default_value(0.0f)
173 .min(0.0f)
174 .max(1.0f)
176 .description("Rotates the direction of anisotropy, with 1.0 going full circle");
177#define SOCK_ANISOTROPIC_ROTATION_ID 16
178 spec.add_input<decl::Vector>("Tangent").hide_value().description(
179 "Controls the tangent direction for anisotropy");
180#define SOCK_TANGENT_ID 17
181
182 /* Panel for Transmission settings. */
183 PanelDeclarationBuilder &transmission = b.add_panel("Transmission").default_closed(true);
184 transmission.add_input<decl::Float>("Transmission Weight")
185 .default_value(0.0f)
186 .min(0.0f)
187 .max(1.0f)
189 .short_label("Weight")
190 .description("Blend between transmission and other base layer components");
191#define SOCK_TRANSMISSION_WEIGHT_ID 18
192
193 /* Panel for Coat settings. */
194 PanelDeclarationBuilder &coat = b.add_panel("Coat").default_closed(true);
195 coat.add_input<decl::Float>("Coat Weight")
196 .default_value(0.0f)
197 .min(0.0f)
198 .max(1.0f)
200 .short_label("Weight")
201 .description(
202 "Controls the intensity of the coat layer, both the reflection and the tinting. "
203 "Typically should be zero or one for physically-based materials");
204#define SOCK_COAT_WEIGHT_ID 19
205 coat.add_input<decl::Float>("Coat Roughness")
206 .default_value(0.03f)
207 .min(0.0f)
208 .max(1.0f)
210 .short_label("Roughness")
211 .description("The roughness of the coat layer");
212#define SOCK_COAT_ROUGHNESS_ID 20
213 coat.add_input<decl::Float>("Coat IOR")
214 .default_value(1.5f)
215 .min(1.0f)
216 .max(4.0f)
217 .short_label("IOR")
218 .description(
219 "The Index of Refraction (IOR) of the coat layer "
220 "(affects its reflectivity as well as the falloff of coat tinting)");
221#define SOCK_COAT_IOR_ID 21
222 coat.add_input<decl::Color>("Coat Tint")
223 .default_value({1.0f, 1.0f, 1.0f, 1.0f})
224 .short_label("Tint")
226 "Adds a colored tint to the coat layer by modeling absorption in the layer. "
227 "Saturation increases at shallower angles, as the light travels farther "
228 "through the medium (depending on the Coat IOR)")
229 .translation_context(BLT_I18NCONTEXT_ID_NODETREE);
230#define SOCK_COAT_TINT_ID 22
231 coat.add_input<decl::Vector>("Coat Normal").short_label("Normal").hide_value();
232#define SOCK_COAT_NORMAL_ID 23
233
234 /* Panel for Sheen settings. */
235 PanelDeclarationBuilder &sheen = b.add_panel("Sheen").default_closed(true);
236 sheen.add_input<decl::Float>("Sheen Weight")
237 .default_value(0.0f)
238 .min(0.0f)
239 .max(1.0f)
241 .short_label("Weight");
242#define SOCK_SHEEN_WEIGHT_ID 24
243 sheen.add_input<decl::Float>("Sheen Roughness")
244 .default_value(0.5f)
245 .min(0.0f)
246 .max(1.0f)
248 .short_label("Roughness");
249#define SOCK_SHEEN_ROUGHNESS_ID 25
250 sheen.add_input<decl::Color>("Sheen Tint")
251 .default_value({1.0f, 1.0f, 1.0f, 1.0f})
252 .translation_context(BLT_I18NCONTEXT_ID_NODETREE)
253 .short_label("Tint");
254#define SOCK_SHEEN_TINT_ID 26
255
256 /* Panel for Emission settings. */
257 PanelDeclarationBuilder &emis = b.add_panel("Emission").default_closed(true);
258 emis.add_input<decl::Color>("Emission Color")
259 .default_value({1.0f, 1.0f, 1.0f, 1.0f})
260 .short_label("Color")
261 .description("Color of light emission from the surface");
262#define SOCK_EMISSION_ID 27
263 emis.add_input<decl::Float>("Emission Strength")
264 .default_value(0.0)
265 .min(0.0f)
266 .max(1000000.0f)
267 .short_label("Strength")
268 .description(
269 "Strength of the emitted light. A value of 1.0 ensures "
270 "that the object in the image has the exact same color as the Emission Color");
271#define SOCK_EMISSION_STRENGTH_ID 28
272
273 /* Panel for Thin Film settings. */
274 PanelDeclarationBuilder &film = b.add_panel("Thin Film").default_closed(true);
275 film.add_input<decl::Float>("Thin Film Thickness")
276 .default_value(0.0)
277 .min(0.0f)
278 .max(100000.0f)
280#define SOCK_THIN_FILM_THICKNESS_ID 29
281 film.add_input<decl::Float>("Thin Film IOR").default_value(1.33f).min(1.0f).max(1000.0f);
282#define SOCK_THIN_FILM_IOR_ID 30
283}
284
285static void node_shader_init_principled(bNodeTree * /*ntree*/, bNode *node)
286{
287 node->custom1 = SHD_GLOSSY_MULTI_GGX;
288 node->custom2 = SHD_SUBSURFACE_RANDOM_WALK;
289}
290
291#define socket_not_zero(sock) (in[sock].link || (clamp_f(in[sock].vec[0], 0.0f, 1.0f) > 1e-5f))
292#define socket_not_one(sock) \
293 (in[sock].link || (clamp_f(in[sock].vec[0], 0.0f, 1.0f) < 1.0f - 1e-5f))
294
296 bNode *node,
297 bNodeExecData * /*execdata*/,
298 GPUNodeStack *in,
299 GPUNodeStack *out)
300{
301 /* Normals */
302 if (!in[SOCK_NORMAL_ID].link) {
303 GPU_link(mat, "world_normals_get", &in[SOCK_NORMAL_ID].link);
304 }
305
306 /* Coat Normals */
307 if (!in[SOCK_COAT_NORMAL_ID].link) {
308 GPU_link(mat, "world_normals_get", &in[SOCK_COAT_NORMAL_ID].link);
309 }
310
311#if 0 /* Not used at the moment. */
312 /* Tangents */
313 if (!in[SOCK_TANGENT_ID].link) {
314 GPUNodeLink *orco = GPU_attribute(CD_ORCO, "");
315 GPU_link(mat, "tangent_orco_z", orco, &in[SOCK_TANGENT_ID].link);
316 GPU_link(mat, "node_tangent", in[SOCK_TANGENT_ID].link, &in[SOCK_TANGENT_ID].link);
317 }
318#endif
319
320 bool use_diffuse = socket_not_zero(SOCK_SHEEN_WEIGHT_ID) ||
323 bool use_subsurf = socket_not_zero(SOCK_SUBSURFACE_WEIGHT_ID) && use_diffuse;
324 bool use_refract = socket_not_one(SOCK_METALLIC_ID) &&
326 bool use_transparency = socket_not_one(SOCK_ALPHA_ID);
327 bool use_coat = socket_not_zero(SOCK_COAT_WEIGHT_ID);
328
330 if (use_diffuse) {
332 }
333 if (use_refract) {
335 }
336 if (use_subsurf) {
338 }
339 if (use_transparency) {
341 }
342 if (use_coat) {
344 }
345
346 if (use_subsurf) {
347 bNodeSocket *socket = (bNodeSocket *)BLI_findlink(&node->runtime->original->inputs,
350 /* For some reason it seems that the socket value is in ARGB format. */
351 use_subsurf = GPU_material_sss_profile_create(mat, &socket_data->value[1]);
352 }
353
354 float use_multi_scatter = (node->custom1 == SHD_GLOSSY_MULTI_GGX) ? 1.0f : 0.0f;
355
357
358 return GPU_stack_link(
359 mat, node, "node_bsdf_principled", in, out, GPU_constant(&use_multi_scatter));
360}
361
363{
364 const int sss_method = node->custom2;
365
367 bke::node_find_socket(node, SOCK_IN, "Subsurface IOR"),
368 sss_method == SHD_SUBSURFACE_RANDOM_WALK_SKIN);
370 bke::node_find_socket(node, SOCK_IN, "Subsurface Anisotropy"),
371 sss_method != SHD_SUBSURFACE_BURLEY);
372}
373
375#ifdef WITH_MATERIALX
376{
377 using InputsType = std::map<std::string, NodeItem>;
378
379 /* NOTE: commented inputs aren't used for node creation. */
380 auto bsdf_inputs = [&]() -> InputsType {
381 return {
382 {"base_color", get_input_value("Base Color", NodeItem::Type::Color3)},
383 {"diffuse_roughness", get_input_value("Diffuse Roughness", NodeItem::Type::Float)},
384 {"subsurface", get_input_value("Subsurface Weight", NodeItem::Type::Float)},
385 {"subsurface_scale", get_input_value("Subsurface Scale", NodeItem::Type::Float)},
386 {"subsurface_radius", get_input_value("Subsurface Radius", NodeItem::Type::Vector3)},
387 //{"subsurface_ior", get_input_value("Subsurface IOR", NodeItem::Type::Vector3)},
388 {"subsurface_anisotropy", get_input_value("Subsurface Anisotropy", NodeItem::Type::Float)},
389 {"metallic", get_input_value("Metallic", NodeItem::Type::Float)},
390 {"specular", get_input_value("Specular IOR Level", NodeItem::Type::Float)},
391 {"specular_tint", get_input_value("Specular Tint", NodeItem::Type::Color3)},
392 {"roughness", get_input_value("Roughness", NodeItem::Type::Float)},
393 {"anisotropic", get_input_value("Anisotropic", NodeItem::Type::Float)},
394 {"anisotropic_rotation", get_input_value("Anisotropic Rotation", NodeItem::Type::Float)},
395 {"sheen", get_input_value("Sheen Weight", NodeItem::Type::Float)},
396 {"sheen_roughness", get_input_value("Sheen Roughness", NodeItem::Type::Float)},
397 {"sheen_tint", get_input_value("Sheen Tint", NodeItem::Type::Color3)},
398 {"coat", get_input_value("Coat Weight", NodeItem::Type::Float)},
399 {"coat_roughness", get_input_value("Coat Roughness", NodeItem::Type::Float)},
400 {"coat_ior", get_input_value("Coat IOR", NodeItem::Type::Float)},
401 {"coat_tint", get_input_value("Coat Tint", NodeItem::Type::Color3)},
402 {"ior", get_input_value("IOR", NodeItem::Type::Float)},
403 {"transmission", get_input_value("Transmission Weight", NodeItem::Type::Float)},
404 {"thin_film_thickness", get_input_value("Thin Film Thickness", NodeItem::Type::Float)},
405 {"thin_film_IOR", get_input_value("Thin Film IOR", NodeItem::Type::Float)},
406 {"alpha", get_input_value("Alpha", NodeItem::Type::Float)},
407 {"normal", get_input_link("Normal", NodeItem::Type::Vector3)},
408 {"coat_normal", get_input_link("Coat Normal", NodeItem::Type::Vector3)},
409 {"tangent", get_input_link("Tangent", NodeItem::Type::Vector3)},
410 };
411 };
412
413 auto edf_inputs = [&]() -> InputsType {
414 return {
415 {"emission", get_input_value("Emission Strength", NodeItem::Type::Float)},
416 {"emission_color", get_input_value("Emission Color", NodeItem::Type::Color3)},
417 };
418 };
419
420 NodeItem res = empty();
421
422 switch (to_type_) {
423 case NodeItem::Type::BSDF: {
424 auto in = bsdf_inputs();
425
426 NodeItem roughness = in["roughness"];
427 NodeItem diffuse_roughness = in["diffuse_roughness"];
428 NodeItem anisotropy = in["anisotropic"];
429 NodeItem rotation = in["anisotropic_rotation"] * val(360.0f);
430 NodeItem base_color = in["base_color"];
431 NodeItem specular = in["specular"];
432 NodeItem coat = in["coat"];
433 NodeItem ior = in["ior"];
434 NodeItem normal = in["normal"];
435 NodeItem tangent = in["tangent"];
436 NodeItem coat_normal = in["coat_normal"];
437
438 NodeItem n_main_tangent = empty();
439 if (tangent && normal) {
440 NodeItem n_tangent_rotate_normalize = tangent.rotate(rotation, normal).normalize();
441 n_main_tangent = anisotropy.if_else(
442 NodeItem::CompareOp::Greater, val(0.0f), n_tangent_rotate_normalize, tangent);
443 }
444
445 NodeItem n_coat_roughness_vector = create_node(
446 "roughness_anisotropy",
447 NodeItem::Type::Vector2,
448 {{"roughness", in["coat_roughness"]}, {"anisotropy", anisotropy}});
449
450 NodeItem n_coat_bsdf = create_node("dielectric_bsdf",
451 NodeItem::Type::BSDF,
452 {{"weight", coat},
453 {"tint", in["coat_tint"]},
454 {"ior", in["coat_ior"]},
455 {"scatter_mode", val(std::string("R"))},
456 {"roughness", n_coat_roughness_vector},
457 {"normal", coat_normal}});
458
459 if (tangent && coat_normal) {
460 NodeItem n_coat_tangent_rotate_normalize =
461 tangent.rotate(rotation, coat_normal).normalize();
462 NodeItem n_coat_tangent = anisotropy.if_else(
463 NodeItem::CompareOp::Greater, val(0.0f), n_coat_tangent_rotate_normalize, tangent);
464
465 n_coat_bsdf.set_input("tangent", n_coat_tangent);
466 }
467
468 NodeItem thin_film_thickness = in["thin_film_thickness"];
469 NodeItem thin_film_ior = in["thin_film_IOR"];
470 NodeItem n_thin_film_bsdf = create_node(
471 "thin_film_bsdf",
472 NodeItem::Type::BSDF,
473 {{"thickness", thin_film_thickness}, {"ior", thin_film_ior}});
474
475 NodeItem n_artistic_ior = create_node(
476 "artistic_ior",
477 NodeItem::Type::Multioutput,
478 {{"reflectivity", base_color * val(1.0f)}, {"edge_color", base_color * specular}});
479
480 NodeItem n_ior_out = n_artistic_ior.add_output("ior", NodeItem::Type::Color3);
481 NodeItem n_extinction_out = n_artistic_ior.add_output("extinction", NodeItem::Type::Color3);
482
483 NodeItem n_coat_affect_roughness_multiply2 = coat * val(0.0f) * in["coat_roughness"];
484 NodeItem n_coat_affected_roughness = n_coat_affect_roughness_multiply2.mix(roughness,
485 val(1.0f));
486
487 NodeItem n_main_roughness = create_node(
488 "roughness_anisotropy",
489 NodeItem::Type::Vector2,
490 {{"roughness", n_coat_affected_roughness}, {"anisotropy", anisotropy}});
491
492 NodeItem n_metal_bsdf = create_node("conductor_bsdf",
493 NodeItem::Type::BSDF,
494 {{"ior", n_ior_out},
495 {"extinction", n_extinction_out},
496 {"roughness", n_main_roughness},
497 {"normal", normal},
498 {"tangent", n_main_tangent}});
499
500 NodeItem n_specular_bsdf = create_node("dielectric_bsdf",
501 NodeItem::Type::BSDF,
502 {{"weight", specular},
503 {"tint", in["specular_tint"]},
504 {"ior", ior},
505 {"scatter_mode", val(std::string("R"))},
506 {"roughness", n_main_roughness},
507 {"normal", normal},
508 {"tangent", n_main_tangent}});
509
510 NodeItem n_coat_affected_transmission_roughness = n_coat_affect_roughness_multiply2.mix(
511 (roughness + roughness).clamp(), val(1.0f));
512
513 NodeItem n_transmission_roughness = create_node(
514 "roughness_anisotropy",
515 NodeItem::Type::Vector2,
516 {{"roughness", n_coat_affected_transmission_roughness}, {"anisotropy", anisotropy}});
517
518 NodeItem n_transmission_bsdf = create_node("dielectric_bsdf",
519 NodeItem::Type::BSDF,
520 {{"tint", base_color},
521 {"ior", ior},
522 {"roughness", n_transmission_roughness},
523 {"normal", normal},
524 {"tangent", n_main_tangent}});
525
526 NodeItem n_coat_gamma = coat.clamp(0.0f, 1.0f) * val(0.0f) + val(1.0f);
527 NodeItem n_coat_affected_subsurface_color = base_color.max(val(0.0f)) ^ n_coat_gamma;
528 NodeItem n_translucent_bsdf = create_node(
529 "translucent_bsdf",
530 NodeItem::Type::BSDF,
531 {{"color", n_coat_affected_subsurface_color}, {"normal", normal}});
532
533 NodeItem n_subsurface_bsdf = create_node(
534 "subsurface_bsdf",
535 NodeItem::Type::BSDF,
536 {{"color", n_coat_affected_subsurface_color},
537 {"radius", in["subsurface_radius"] * in["subsurface_scale"]},
538 {"anisotropy", in["subsurface_anisotropy"]},
539 {"normal", normal}});
540
541 NodeItem n_sheen_bsdf = create_node("sheen_bsdf",
542 NodeItem::Type::BSDF,
543 {{"weight", in["sheen"]},
544 {"color", in["sheen_tint"]},
545 {"roughness", in["sheen_roughness"]},
546 {"normal", normal}});
547
548 NodeItem n_diffuse_bsdf = create_node("oren_nayar_diffuse_bsdf",
549 NodeItem::Type::BSDF,
550 {{"color", base_color.max(val(0.0f)) ^ n_coat_gamma},
551 {"roughness", diffuse_roughness},
552 {"weight", val(1.0f)},
553 {"normal", normal}});
554
555 NodeItem n_subsurface_mix = in["subsurface"].mix(n_diffuse_bsdf, n_subsurface_bsdf);
556
557 NodeItem n_sheen_layer = create_node(
558 "layer", NodeItem::Type::BSDF, {{"top", n_sheen_bsdf}, {"base", n_subsurface_mix}});
559
560 NodeItem n_transmission_mix = in["transmission"].mix(n_sheen_layer, n_transmission_bsdf);
561
562 NodeItem n_specular_layer = create_node(
563 "layer", NodeItem::Type::BSDF, {{"top", n_specular_bsdf}, {"base", n_transmission_mix}});
564
565 NodeItem n_metalness_mix = in["metallic"].mix(n_specular_layer, n_metal_bsdf);
566
567 NodeItem n_thin_film_layer = create_node(
568 "layer", NodeItem::Type::BSDF, {{"top", n_thin_film_bsdf}, {"base", n_metalness_mix}});
569
570 NodeItem n_coat_attenuation = coat.mix(val(MaterialX::Color3(1.0f, 1.0f, 1.0f)),
571 in["coat_tint"]);
572
573 res = create_node("layer",
574 NodeItem::Type::BSDF,
575 {{"top", n_coat_bsdf}, {"base", n_thin_film_layer * n_coat_attenuation}});
576 break;
577 }
578
579 case NodeItem::Type::EDF: {
580 auto in = edf_inputs();
581 res = create_node(
582 "uniform_edf", NodeItem::Type::EDF, {{"color", in["emission_color"] * in["emission"]}});
583 break;
584 }
585
586 case NodeItem::Type::SurfaceShader: {
587 auto in = bsdf_inputs();
588 auto e_in = edf_inputs();
589 in.insert(e_in.begin(), e_in.end());
590
591 NodeItem roughness = in["roughness"];
592 NodeItem base_color = in["base_color"];
593 NodeItem anisotropic = in["anisotropic"];
594 NodeItem rotation = in["anisotropic_rotation"];
595
596 res = create_node(
597 "standard_surface",
598 NodeItem::Type::SurfaceShader,
599 {{"base", val(1.0f)},
600 {"base_color", base_color},
601 {"diffuse_roughness", in["diffuse_roughness"]},
602 {"metalness", in["metallic"]},
603 {"specular", in["specular"]},
604 {"specular_color", in["specular_tint"]},
605 {"specular_roughness", roughness},
606 {"specular_IOR", in["ior"]},
607 {"specular_anisotropy", anisotropic},
608 {"specular_rotation", rotation},
609 {"transmission", in["transmission"]},
610 {"transmission_color", base_color},
611 {"transmission_extra_roughness", roughness},
612 {"subsurface", in["subsurface"]},
613 {"subsurface_color", base_color},
614 {"subsurface_radius",
615 (in["subsurface_radius"] * in["subsurface_scale"]).convert(NodeItem::Type::Color3)},
616 {"subsurface_anisotropy", in["subsurface_anisotropy"]},
617 {"sheen", in["sheen"]},
618 {"sheen_color", in["sheen_tint"]},
619 {"sheen_roughness", in["sheen_roughness"]},
620 {"coat", in["coat"]},
621 {"coat_color", in["coat_tint"]},
622 {"coat_roughness", in["coat_roughness"]},
623 {"coat_IOR", in["coat_ior"]},
624 {"coat_anisotropy", anisotropic},
625 {"coat_rotation", rotation},
626 {"coat_normal", in["coat_normal"]},
627 {"emission", in["emission"]},
628 {"emission_color", in["emission_color"]},
629 {"thin_film_thickness", in["thin_film_thickness"]},
630 {"thin_film_IOR", in["thin_film_IOR"]},
631 {"normal", in["normal"]},
632 {"tangent", in["tangent"]},
633 {"opacity", in["alpha"].convert(NodeItem::Type::Color3)}});
634 break;
635 }
636
637 case NodeItem::Type::SurfaceOpacity: {
638 res = get_input_value("Alpha", NodeItem::Type::Float);
639 break;
640 }
641
642 default:
644 }
645 return res;
646}
647#endif
649
650} // namespace blender::nodes::node_shader_bsdf_principled_cc
651
652/* node type definition */
654{
656
657 static blender::bke::bNodeType ntype;
658
659 sh_node_type_base(&ntype, SH_NODE_BSDF_PRINCIPLED, "Principled BSDF", NODE_CLASS_SHADER);
660 ntype.declare = file_ns::node_declare;
663 ntype.initfunc = file_ns::node_shader_init_principled;
664 ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_principled;
665 ntype.updatefunc = file_ns::node_shader_update_principled;
666 ntype.materialx_fn = file_ns::node_shader_materialx;
667
669}
#define NODE_CLASS_SHADER
Definition BKE_node.hh:417
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define BLT_I18NCONTEXT_ID_NODETREE
@ SHD_SUBSURFACE_BURLEY
@ SHD_SUBSURFACE_RANDOM_WALK_SKIN
@ SHD_SUBSURFACE_RANDOM_WALK
@ SHD_GLOSSY_MULTI_GGX
@ SOCK_IN
bool GPU_stack_link(GPUMaterial *mat, const bNode *node, const char *name, GPUNodeStack *in, GPUNodeStack *out,...)
GPUNodeLink * GPU_constant(const float *num)
bool GPU_material_sss_profile_create(GPUMaterial *material, float radii[3])
eGPUMaterialFlag
@ GPU_MATFLAG_GLOSSY
@ GPU_MATFLAG_COAT
@ GPU_MATFLAG_REFRACT
@ GPU_MATFLAG_DIFFUSE
@ GPU_MATFLAG_TRANSPARENT
@ GPU_MATFLAG_SUBSURFACE
void GPU_material_flag_set(GPUMaterial *mat, eGPUMaterialFlag flag)
GPUNodeLink * GPU_attribute(GPUMaterial *mat, eCustomDataType type, const char *name)
bool GPU_link(GPUMaterial *mat, const char *name,...)
@ PROP_DISTANCE
Definition RNA_types.hh:159
@ PROP_FACTOR
Definition RNA_types.hh:154
@ PROP_WAVELENGTH
Definition RNA_types.hh:190
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
@ UI_ITEM_R_SPLIT_EMPTY_NAME
DeclType::Builder & add_input(StringRef name, StringRef identifier="")
local_group_size(16, 16) .push_constant(Type b
void node_type_size_preset(bNodeType *ntype, eNodeSizePreset size)
Definition node.cc:4614
void node_set_socket_availability(bNodeTree *ntree, bNodeSocket *sock, bool is_available)
Definition node.cc:3911
void node_register_type(bNodeType *ntype)
Definition node.cc:1708
bNodeSocket * node_find_socket(bNode *node, eNodeSocketInOut in_out, StringRef identifier)
Definition node.cc:1829
void convert(SignedNormalized< StorageType > &dst, const F32 &src)
static void node_shader_init_principled(bNodeTree *, bNode *node)
static int node_shader_gpu_bsdf_principled(GPUMaterial *mat, bNode *node, bNodeExecData *, GPUNodeStack *in, GPUNodeStack *out)
static void node_declare(NodeDeclarationBuilder &b)
static void node_shader_update_principled(bNodeTree *ntree, bNode *node)
#define NODE_SHADER_MATERIALX_BEGIN
#define NODE_SHADER_MATERIALX_END
#define socket_not_one(sock)
#define SOCK_TRANSMISSION_WEIGHT_ID
#define socket_not_zero(sock)
#define SOCK_SUBSURFACE_WEIGHT_ID
#define SOCK_COAT_WEIGHT_ID
#define SOCK_METALLIC_ID
void register_node_type_sh_bsdf_principled()
#define SOCK_COAT_NORMAL_ID
#define SOCK_TANGENT_ID
#define SOCK_NORMAL_ID
#define SOCK_SUBSURFACE_RADIUS_ID
#define SOCK_SHEEN_WEIGHT_ID
#define SOCK_ALPHA_ID
void sh_node_type_base(blender::bke::bNodeType *ntype, int type, const char *name, short nclass)
bool object_shader_nodes_poll(const bContext *C)
#define min(a, b)
Definition sort.c:32
closure color sheen(normal N, float roughness) BUILTIN
void * default_value
Defines a node type.
Definition BKE_node.hh:218
NodeMaterialXFunction materialx_fn
Definition BKE_node.hh:320
bool(* add_ui_poll)(const bContext *C)
Definition BKE_node.hh:288
void(* initfunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:267
NodeGPUExecFunction gpu_fn
Definition BKE_node.hh:318
NodeDeclareFunction declare
Definition BKE_node.hh:347
void(* updatefunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:257
PointerRNA * ptr
Definition wm_files.cc:4126
uint8_t flag
Definition wm_window.cc:138