Blender  V3.3
closures.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Adapted from Open Shading Language
4  * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
5  * All Rights Reserved.
6  *
7  * Modifications Copyright 2011-2022 Blender Foundation. */
8 
9 #include <OSL/genclosure.h>
10 #include <OSL/oslclosure.h>
11 
12 #include "kernel/osl/closures.h"
13 #include "kernel/osl/shader.h"
14 
15 #include "util/math.h"
16 #include "util/param.h"
17 
18 // clang-format off
21 
22 #include "kernel/types.h"
23 
24 #include "kernel/closure/alloc.h"
40 #include "kernel/closure/volume.h"
41 // clang-format on
42 
44 
45 using namespace OSL;
46 
47 /* BSDF class definitions */
48 
50  BSDF_CLOSURE_FLOAT3_PARAM(DiffuseClosure, params.N)
51 BSDF_CLOSURE_CLASS_END(Diffuse, diffuse)
52 
53 BSDF_CLOSURE_CLASS_BEGIN(Translucent, translucent, DiffuseBsdf, LABEL_DIFFUSE)
54  BSDF_CLOSURE_FLOAT3_PARAM(TranslucentClosure, params.N)
55 BSDF_CLOSURE_CLASS_END(Translucent, translucent)
56 
58  BSDF_CLOSURE_FLOAT3_PARAM(OrenNayarClosure, params.N)
59  BSDF_CLOSURE_FLOAT_PARAM(OrenNayarClosure, params.roughness)
60 BSDF_CLOSURE_CLASS_END(OrenNayar, oren_nayar)
61 
63  BSDF_CLOSURE_FLOAT3_PARAM(ReflectionClosure, params.N)
64 BSDF_CLOSURE_CLASS_END(Reflection, reflection)
65 
67  BSDF_CLOSURE_FLOAT3_PARAM(RefractionClosure, params.N)
68  BSDF_CLOSURE_FLOAT_PARAM(RefractionClosure, params.ior)
69 BSDF_CLOSURE_CLASS_END(Refraction, refraction)
70 
72  BSDF_CLOSURE_FLOAT3_PARAM(AshikhminVelvetClosure, params.N)
73  BSDF_CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, params.sigma)
75 
76 BSDF_CLOSURE_CLASS_BEGIN(AshikhminShirley,
80  BSDF_CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, params.N)
81  BSDF_CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, params.T)
82  BSDF_CLOSURE_FLOAT_PARAM(AshikhminShirleyClosure, params.alpha_x)
83  BSDF_CLOSURE_FLOAT_PARAM(AshikhminShirleyClosure, params.alpha_y)
85 
87  BSDF_CLOSURE_FLOAT3_PARAM(DiffuseToonClosure, params.N)
88  BSDF_CLOSURE_FLOAT_PARAM(DiffuseToonClosure, params.size)
89  BSDF_CLOSURE_FLOAT_PARAM(DiffuseToonClosure, params.smooth)
91 
93  BSDF_CLOSURE_FLOAT3_PARAM(GlossyToonClosure, params.N)
94  BSDF_CLOSURE_FLOAT_PARAM(GlossyToonClosure, params.size)
95  BSDF_CLOSURE_FLOAT_PARAM(GlossyToonClosure, params.smooth)
97 
98 BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXIsotropic,
102  BSDF_CLOSURE_FLOAT3_PARAM(MicrofacetGGXIsotropicClosure, params.N)
103  BSDF_CLOSURE_FLOAT_PARAM(MicrofacetGGXIsotropicClosure, params.alpha_x)
104 BSDF_CLOSURE_CLASS_END(MicrofacetGGXIsotropic, microfacet_ggx_isotropic)
105 
110  BSDF_CLOSURE_FLOAT3_PARAM(MicrofacetGGXClosure, params.N)
111  BSDF_CLOSURE_FLOAT3_PARAM(MicrofacetGGXClosure, params.T)
112  BSDF_CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, params.alpha_x)
113  BSDF_CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, params.alpha_y)
115 
116 BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannIsotropic,
120  BSDF_CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannIsotropicClosure, params.N)
121  BSDF_CLOSURE_FLOAT_PARAM(MicrofacetBeckmannIsotropicClosure, params.alpha_x)
122 BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannIsotropic, microfacet_beckmann_isotropic)
123 
124 BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmann,
128  BSDF_CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannClosure, params.N)
129  BSDF_CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannClosure, params.T)
130  BSDF_CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, params.alpha_x)
131  BSDF_CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, params.alpha_y)
132 BSDF_CLOSURE_CLASS_END(MicrofacetBeckmann, microfacet_beckmann)
133 
134 BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXRefraction,
138  BSDF_CLOSURE_FLOAT3_PARAM(MicrofacetGGXRefractionClosure, params.N)
139  BSDF_CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, params.alpha_x)
140  BSDF_CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, params.ior)
141 BSDF_CLOSURE_CLASS_END(MicrofacetGGXRefraction, microfacet_ggx_refraction)
142 
143 BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannRefraction,
147  BSDF_CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannRefractionClosure, params.N)
148  BSDF_CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, params.alpha_x)
149  BSDF_CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, params.ior)
150 BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction)
151 
153  BSDF_CLOSURE_FLOAT3_PARAM(HairReflectionClosure, params.N)
154  BSDF_CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.roughness1)
155  BSDF_CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.roughness2)
156  BSDF_CLOSURE_FLOAT3_PARAM(HairReflectionClosure, params.T)
157  BSDF_CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.offset)
159 
161  BSDF_CLOSURE_FLOAT3_PARAM(HairTransmissionClosure, params.N)
162  BSDF_CLOSURE_FLOAT_PARAM(HairTransmissionClosure, params.roughness1)
163  BSDF_CLOSURE_FLOAT_PARAM(HairTransmissionClosure, params.roughness2)
164  BSDF_CLOSURE_FLOAT3_PARAM(HairReflectionClosure, params.T)
165  BSDF_CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.offset)
166 BSDF_CLOSURE_CLASS_END(HairTransmission, hair_transmission)
167 
168 BSDF_CLOSURE_CLASS_BEGIN(PrincipledDiffuse,
172  BSDF_CLOSURE_FLOAT3_PARAM(PrincipledDiffuseClosure, params.N)
173  BSDF_CLOSURE_FLOAT_PARAM(PrincipledDiffuseClosure, params.roughness)
174 BSDF_CLOSURE_CLASS_END(PrincipledDiffuse, principled_diffuse)
175 
177  public:
179 
180  void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
181  {
182  if (!skip(sd, path_flag, LABEL_DIFFUSE)) {
183  params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
184 
185  PrincipledSheenBsdf *bsdf = (PrincipledSheenBsdf *)bsdf_alloc_osl(
186  sd, sizeof(PrincipledSheenBsdf), weight, &params);
187  sd->flag |= (bsdf) ? bsdf_principled_sheen_setup(sd, bsdf) : 0;
188  }
189  }
190 };
191 
192 static ClosureParam *bsdf_principled_sheen_params()
193 {
194  static ClosureParam params[] = {CLOSURE_FLOAT3_PARAM(PrincipledSheenClosure, params.N),
195  CLOSURE_STRING_KEYPARAM(PrincipledSheenClosure, label, "label"),
196  CLOSURE_FINISH_PARAM(PrincipledSheenClosure)};
197  return params;
198 }
199 
200 CCLOSURE_PREPARE_STATIC(closure_bsdf_principled_sheen_prepare, PrincipledSheenClosure)
201 
202 /* PRINCIPLED HAIR BSDF */
204  public:
206 
208  {
209  PrincipledHairBSDF *bsdf = (PrincipledHairBSDF *)bsdf_alloc_osl(
210  sd, sizeof(PrincipledHairBSDF), weight, &params);
211  if (!bsdf) {
212  return NULL;
213  }
214 
216  sd, sizeof(PrincipledHairExtra));
217  if (!extra) {
218  return NULL;
219  }
220 
221  bsdf->extra = extra;
222  return bsdf;
223  }
224 
225  void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
226  {
227  if (!skip(sd, path_flag, LABEL_GLOSSY)) {
228  params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
229 
230  PrincipledHairBSDF *bsdf = (PrincipledHairBSDF *)alloc(sd, path_flag, weight);
231  if (!bsdf) {
232  return;
233  }
234 
235  sd->flag |= (bsdf) ? bsdf_principled_hair_setup(sd, bsdf) : 0;
236  }
237  }
238 };
239 
241 {
242  static ClosureParam params[] = {CLOSURE_FLOAT3_PARAM(PrincipledHairClosure, params.N),
244  CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.v),
245  CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.s),
246  CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.m0_roughness),
247  CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.alpha),
248  CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.eta),
249  CLOSURE_STRING_KEYPARAM(PrincipledHairClosure, label, "label"),
250  CLOSURE_FINISH_PARAM(PrincipledHairClosure)};
251 
252  return params;
253 }
254 
256 
257 /* DISNEY PRINCIPLED CLEARCOAT */
259  public:
261  float clearcoat, clearcoat_roughness;
262 
263  MicrofacetBsdf *alloc(ShaderData *sd, uint32_t path_flag, float3 weight)
264  {
265  MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl(
266  sd, sizeof(MicrofacetBsdf), weight, &params);
267  if (!bsdf) {
268  return NULL;
269  }
270 
272  if (!extra) {
273  return NULL;
274  }
275 
276  bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
277  bsdf->extra = extra;
278  bsdf->ior = 1.5f;
279  bsdf->alpha_x = clearcoat_roughness;
280  bsdf->alpha_y = clearcoat_roughness;
281  bsdf->extra->color = make_float3(0.0f, 0.0f, 0.0f);
282  bsdf->extra->cspec0 = make_float3(0.04f, 0.04f, 0.04f);
283  bsdf->extra->clearcoat = clearcoat;
284  return bsdf;
285  }
286 
287  void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
288  {
289  params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
290  MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
291  if (!bsdf) {
292  return;
293  }
294 
295  sd->flag |= bsdf_microfacet_ggx_clearcoat_setup(bsdf, sd);
296  }
297 };
298 
300 {
301  static ClosureParam params[] = {
303  CLOSURE_FLOAT_PARAM(PrincipledClearcoatClosure, clearcoat),
304  CLOSURE_FLOAT_PARAM(PrincipledClearcoatClosure, clearcoat_roughness),
305  CLOSURE_STRING_KEYPARAM(PrincipledClearcoatClosure, label, "label"),
306  CLOSURE_FINISH_PARAM(PrincipledClearcoatClosure)};
307  return params;
308 }
310 
311 /* Registration */
312 
313 static void register_closure(OSL::ShadingSystem *ss,
314  const char *name,
315  int id,
316  OSL::ClosureParam *params,
317  OSL::PrepareClosureFunc prepare)
318 {
319  /* optimization: it's possible to not use a prepare function at all and
320  * only initialize the actual class when accessing the closure component
321  * data, but then we need to map the id to the class somehow */
322 #if OSL_LIBRARY_VERSION_CODE >= 10900
323  ss->register_closure(name, id, params, prepare, NULL);
324 #else
325  ss->register_closure(name, id, params, prepare, NULL, 16);
326 #endif
327 }
328 
329 void OSLShader::register_closures(OSLShadingSystem *ss_)
330 {
332  int id = 0;
333 
334  register_closure(ss, "diffuse", id++, bsdf_diffuse_params(), bsdf_diffuse_prepare);
335  register_closure(ss, "oren_nayar", id++, bsdf_oren_nayar_params(), bsdf_oren_nayar_prepare);
336  register_closure(ss, "translucent", id++, bsdf_translucent_params(), bsdf_translucent_prepare);
337  register_closure(ss, "reflection", id++, bsdf_reflection_params(), bsdf_reflection_prepare);
338  register_closure(ss, "refraction", id++, bsdf_refraction_params(), bsdf_refraction_prepare);
339  register_closure(ss,
340  "transparent",
341  id++,
344 
347  register_closure(ss,
348  "microfacet_ggx",
349  id++,
350  bsdf_microfacet_ggx_isotropic_params(),
351  bsdf_microfacet_ggx_isotropic_prepare);
353  ss, "microfacet_ggx_aniso", id++, bsdf_microfacet_ggx_params(), bsdf_microfacet_ggx_prepare);
354  register_closure(ss,
355  "microfacet_ggx_refraction",
356  id++,
357  bsdf_microfacet_ggx_refraction_params(),
358  bsdf_microfacet_ggx_refraction_prepare);
359  register_closure(ss,
360  "microfacet_multi_ggx",
361  id++,
364  register_closure(ss,
365  "microfacet_multi_ggx_glass",
366  id++,
369  register_closure(ss,
370  "microfacet_multi_ggx_aniso",
371  id++,
374  register_closure(ss,
375  "microfacet_ggx_fresnel",
376  id++,
379  register_closure(ss,
380  "microfacet_ggx_aniso_fresnel",
381  id++,
384  register_closure(ss,
385  "microfacet_multi_ggx_fresnel",
386  id++,
389  register_closure(ss,
390  "microfacet_multi_ggx_glass_fresnel",
391  id++,
394  register_closure(ss,
395  "microfacet_multi_ggx_aniso_fresnel",
396  id++,
399  register_closure(ss,
400  "microfacet_beckmann",
401  id++,
402  bsdf_microfacet_beckmann_isotropic_params(),
403  bsdf_microfacet_beckmann_isotropic_prepare);
404  register_closure(ss,
405  "microfacet_beckmann_aniso",
406  id++,
407  bsdf_microfacet_beckmann_params(),
408  bsdf_microfacet_beckmann_prepare);
409  register_closure(ss,
410  "microfacet_beckmann_refraction",
411  id++,
412  bsdf_microfacet_beckmann_refraction_params(),
413  bsdf_microfacet_beckmann_refraction_prepare);
414  register_closure(ss,
415  "ashikhmin_shirley",
416  id++,
417  bsdf_ashikhmin_shirley_params(),
418  bsdf_ashikhmin_shirley_prepare);
420  ss, "ashikhmin_velvet", id++, bsdf_ashikhmin_velvet_params(), bsdf_ashikhmin_velvet_prepare);
422  ss, "diffuse_toon", id++, bsdf_diffuse_toon_params(), bsdf_diffuse_toon_prepare);
423  register_closure(ss, "glossy_toon", id++, bsdf_glossy_toon_params(), bsdf_glossy_toon_prepare);
424  register_closure(ss,
425  "principled_diffuse",
426  id++,
427  bsdf_principled_diffuse_params(),
428  bsdf_principled_diffuse_prepare);
429  register_closure(ss,
430  "principled_sheen",
431  id++,
433  closure_bsdf_principled_sheen_prepare);
434  register_closure(ss,
435  "principled_clearcoat",
436  id++,
439 
442  ss, "background", id++, closure_background_params(), closure_background_prepare);
444  register_closure(ss,
445  "diffuse_ramp",
446  id++,
452 
454  ss, "hair_reflection", id++, bsdf_hair_reflection_params(), bsdf_hair_reflection_prepare);
455  register_closure(ss,
456  "hair_transmission",
457  id++,
458  bsdf_hair_transmission_params(),
459  bsdf_hair_transmission_prepare);
460 
461  register_closure(ss,
462  "principled_hair",
463  id++,
466 
467  register_closure(ss,
468  "henyey_greenstein",
469  id++,
473  ss, "absorption", id++, closure_absorption_params(), closure_absorption_prepare);
474 }
475 
476 /* BSDF Closure */
477 
478 bool CBSDFClosure::skip(const ShaderData *sd, uint32_t path_flag, int scattering)
479 {
480  /* caustic options */
481  if ((scattering & LABEL_GLOSSY) && (path_flag & PATH_RAY_DIFFUSE)) {
482  const KernelGlobalsCPU *kg = sd->osl_globals;
483 
484  if ((!kernel_data.integrator.caustics_reflective && (scattering & LABEL_REFLECT)) ||
485  (!kernel_data.integrator.caustics_refractive && (scattering & LABEL_TRANSMIT))) {
486  return true;
487  }
488  }
489 
490  return false;
491 }
492 
493 /* Standard Microfacet Closure */
494 
496  public:
498  ustring distribution;
499  int refract;
500 
501  void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
502  {
503  static ustring u_ggx("ggx");
504  static ustring u_default("default");
505 
506  const int label = (refract) ? LABEL_TRANSMIT : LABEL_REFLECT;
507  if (skip(sd, path_flag, LABEL_GLOSSY | label)) {
508  return;
509  }
510 
511  params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
512 
513  MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl(
514  sd, sizeof(MicrofacetBsdf), weight, &params);
515 
516  if (!bsdf) {
517  return;
518  }
519 
520  /* GGX */
521  if (distribution == u_ggx || distribution == u_default) {
522  if (!refract) {
523  if (params.alpha_x == params.alpha_y) {
524  /* Isotropic */
525  sd->flag |= bsdf_microfacet_ggx_isotropic_setup(bsdf);
526  }
527  else {
528  /* Anisotropic */
529  sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
530  }
531  }
532  else {
533  sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf);
534  }
535  }
536  /* Beckmann */
537  else {
538  if (!refract) {
539  if (params.alpha_x == params.alpha_y) {
540  /* Isotropic */
542  }
543  else {
544  /* Anisotropic */
545  sd->flag |= bsdf_microfacet_beckmann_setup(bsdf);
546  }
547  }
548  else {
550  }
551  }
552  }
553 };
554 
556 {
557  static ClosureParam params[] = {CLOSURE_STRING_PARAM(MicrofacetClosure, distribution),
560  CLOSURE_FLOAT_PARAM(MicrofacetClosure, params.alpha_x),
561  CLOSURE_FLOAT_PARAM(MicrofacetClosure, params.alpha_y),
562  CLOSURE_FLOAT_PARAM(MicrofacetClosure, params.ior),
563  CLOSURE_INT_PARAM(MicrofacetClosure, refract),
564  CLOSURE_STRING_KEYPARAM(MicrofacetClosure, label, "label"),
565  CLOSURE_FINISH_PARAM(MicrofacetClosure)};
566 
567  return params;
568 }
570 
571 /* GGX closures with Fresnel */
572 
574  public:
578 
579  MicrofacetBsdf *alloc(ShaderData *sd, uint32_t path_flag, float3 weight)
580  {
581  /* Technically, the MultiGGX Glass closure may also transmit. However,
582  * since this is set statically and only used for caustic flags, this
583  * is probably as good as it gets. */
584  if (skip(sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
585  return NULL;
586  }
587 
588  MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl(
589  sd, sizeof(MicrofacetBsdf), weight, &params);
590  if (!bsdf) {
591  return NULL;
592  }
593 
595  if (!extra) {
596  return NULL;
597  }
598 
599  bsdf->extra = extra;
600  bsdf->extra->color = color;
601  bsdf->extra->cspec0 = cspec0;
602  bsdf->extra->clearcoat = 0.0f;
603  return bsdf;
604  }
605 };
606 
608  public:
609  void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
610  {
611  params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
612 
613  MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
614  if (!bsdf) {
615  return;
616  }
617 
618  bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
619  bsdf->alpha_y = bsdf->alpha_x;
620  sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd);
621  }
622 };
623 
625 {
626  static ClosureParam params[] = {
628  CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.alpha_x),
629  CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.ior),
632  CLOSURE_STRING_KEYPARAM(MicrofacetGGXFresnelClosure, label, "label"),
633  CLOSURE_FINISH_PARAM(MicrofacetGGXFresnelClosure)};
634  return params;
635 }
637 
639  public:
640  void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
641  {
642  params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
643 
644  MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
645  if (!bsdf) {
646  return;
647  }
648 
649  sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd);
650  }
651 };
652 
654 {
655  static ClosureParam params[] = {
658  CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.alpha_x),
659  CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.alpha_y),
660  CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.ior),
663  CLOSURE_STRING_KEYPARAM(MicrofacetGGXFresnelClosure, label, "label"),
664  CLOSURE_FINISH_PARAM(MicrofacetGGXFresnelClosure)};
665  return params;
666 }
669 
670 /* Multiscattering GGX closures */
671 
673  public:
676 
677  MicrofacetBsdf *alloc(ShaderData *sd, uint32_t path_flag, float3 weight)
678  {
679  /* Technically, the MultiGGX closure may also transmit. However,
680  * since this is set statically and only used for caustic flags, this
681  * is probably as good as it gets. */
682  if (skip(sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
683  return NULL;
684  }
685 
686  MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl(
687  sd, sizeof(MicrofacetBsdf), weight, &params);
688  if (!bsdf) {
689  return NULL;
690  }
691 
693  if (!extra) {
694  return NULL;
695  }
696 
697  bsdf->extra = extra;
698  bsdf->extra->color = color;
699  bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
700  bsdf->extra->clearcoat = 0.0f;
701  return bsdf;
702  }
703 };
704 
706  public:
707  void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
708  {
709  params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
710 
711  MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
712  if (!bsdf) {
713  return;
714  }
715 
716  bsdf->ior = 0.0f;
717  bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
718  bsdf->alpha_y = bsdf->alpha_x;
719  sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf);
720  }
721 };
722 
724 {
725  static ClosureParam params[] = {
727  CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_x),
729  CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXClosure, label, "label"),
730  CLOSURE_FINISH_PARAM(MicrofacetMultiGGXClosure)};
731  return params;
732 }
734 
736  public:
737  void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
738  {
739  params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
740 
741  MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
742  if (!bsdf) {
743  return;
744  }
745 
746  bsdf->ior = 0.0f;
747  sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf);
748  }
749 };
750 
752 {
753  static ClosureParam params[] = {
756  CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_x),
757  CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_y),
759  CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXClosure, label, "label"),
760  CLOSURE_FINISH_PARAM(MicrofacetMultiGGXClosure)};
761  return params;
762 }
764 
766  public:
768  {
769  }
770 
771  void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
772  {
773  params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
774 
775  MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
776  if (!bsdf) {
777  return;
778  }
779 
780  bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
781  bsdf->alpha_y = bsdf->alpha_x;
782  sd->flag |= bsdf_microfacet_multi_ggx_glass_setup(bsdf);
783  }
784 };
785 
787 {
788  static ClosureParam params[] = {
790  CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_x),
791  CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.ior),
793  CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXClosure, label, "label"),
794  CLOSURE_FINISH_PARAM(MicrofacetMultiGGXClosure)};
795  return params;
796 }
798 
799 /* Multiscattering GGX closures with Fresnel */
800 
802  public:
806 
807  MicrofacetBsdf *alloc(ShaderData *sd, uint32_t path_flag, float3 weight)
808  {
809  /* Technically, the MultiGGX closure may also transmit. However,
810  * since this is set statically and only used for caustic flags, this
811  * is probably as good as it gets. */
812  if (skip(sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
813  return NULL;
814  }
815 
816  MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl(
817  sd, sizeof(MicrofacetBsdf), weight, &params);
818  if (!bsdf) {
819  return NULL;
820  }
821 
823  if (!extra) {
824  return NULL;
825  }
826 
827  bsdf->extra = extra;
828  bsdf->extra->color = color;
829  bsdf->extra->cspec0 = cspec0;
830  bsdf->extra->clearcoat = 0.0f;
831  return bsdf;
832  }
833 };
834 
836  public:
837  void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
838  {
839  params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
840 
841  MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
842  if (!bsdf) {
843  return;
844  }
845 
846  bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
847  bsdf->alpha_y = bsdf->alpha_x;
848  sd->flag |= bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd);
849  }
850 };
851 
853 {
854  static ClosureParam params[] = {
856  CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_x),
857  CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.ior),
860  CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXFresnelClosure, label, "label"),
861  CLOSURE_FINISH_PARAM(MicrofacetMultiGGXFresnelClosure)};
862  return params;
863 }
866 
868  public:
869  void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
870  {
871  params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
872 
873  MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
874  if (!bsdf) {
875  return;
876  }
877 
878  sd->flag |= bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd);
879  }
880 };
881 
883 {
884  static ClosureParam params[] = {
887  CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_x),
888  CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_y),
889  CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.ior),
892  CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXFresnelClosure, label, "label"),
893  CLOSURE_FINISH_PARAM(MicrofacetMultiGGXFresnelClosure)};
894  return params;
895 }
898 
900  public:
902  {
903  }
904 
905  void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
906  {
907  params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
908 
909  MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
910  if (!bsdf) {
911  return;
912  }
913 
914  bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
915  bsdf->alpha_y = bsdf->alpha_x;
916  sd->flag |= bsdf_microfacet_multi_ggx_glass_fresnel_setup(bsdf, sd);
917  }
918 };
919 
921 {
922  static ClosureParam params[] = {
924  CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_x),
925  CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.ior),
928  CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXFresnelClosure, label, "label"),
929  CLOSURE_FINISH_PARAM(MicrofacetMultiGGXFresnelClosure)};
930  return params;
931 }
934 
935 /* Transparent */
936 
938  public:
941 
942  void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
943  {
944  bsdf_transparent_setup(sd, weight, path_flag);
945  }
946 };
947 
949 {
950  static ClosureParam params[] = {CLOSURE_STRING_KEYPARAM(TransparentClosure, label, "label"),
951  CLOSURE_FINISH_PARAM(TransparentClosure)};
952  return params;
953 }
954 
956 
957 /* Volume */
958 
960  public:
961  void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
962  {
963  volume_extinction_setup(sd, weight);
964  }
965 };
966 
968 {
969  static ClosureParam params[] = {CLOSURE_STRING_KEYPARAM(VolumeAbsorptionClosure, label, "label"),
970  CLOSURE_FINISH_PARAM(VolumeAbsorptionClosure)};
971  return params;
972 }
973 
975 
977  public:
979 
980  void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
981  {
982  volume_extinction_setup(sd, weight);
983 
984  HenyeyGreensteinVolume *volume = (HenyeyGreensteinVolume *)bsdf_alloc_osl(
985  sd, sizeof(HenyeyGreensteinVolume), weight, &params);
986  if (!volume) {
987  return;
988  }
989 
990  sd->flag |= volume_henyey_greenstein_setup(volume);
991  }
992 };
993 
995 {
996  static ClosureParam params[] = {
997  CLOSURE_FLOAT_PARAM(VolumeHenyeyGreensteinClosure, params.g),
998  CLOSURE_STRING_KEYPARAM(VolumeHenyeyGreensteinClosure, label, "label"),
999  CLOSURE_FINISH_PARAM(VolumeHenyeyGreensteinClosure)};
1000  return params;
1001 }
1002 
1004 
static void prepare(Render *re, ViewLayer *view_layer, Depsgraph *depsgraph)
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 a value between a minimum and a maximum Vector Perform vector math operation Invert a color
ccl_device ccl_private void * closure_alloc_extra(ccl_private ShaderData *sd, int size)
Definition: alloc.h:29
ClosureParam * closure_bsdf_diffuse_ramp_params()
ccl_device int bsdf_microfacet_beckmann_isotropic_setup(ccl_private MicrofacetBsdf *bsdf)
ccl_device int bsdf_microfacet_beckmann_setup(ccl_private MicrofacetBsdf *bsdf)
ccl_device int bsdf_microfacet_ggx_fresnel_setup(ccl_private MicrofacetBsdf *bsdf, ccl_private const ShaderData *sd)
ccl_device int bsdf_microfacet_ggx_clearcoat_setup(ccl_private MicrofacetBsdf *bsdf, ccl_private const ShaderData *sd)
ccl_device int bsdf_microfacet_beckmann_refraction_setup(ccl_private MicrofacetBsdf *bsdf)
ccl_device int bsdf_microfacet_ggx_setup(ccl_private MicrofacetBsdf *bsdf)
ccl_device int bsdf_microfacet_ggx_isotropic_setup(ccl_private MicrofacetBsdf *bsdf)
ccl_device int bsdf_microfacet_ggx_refraction_setup(ccl_private MicrofacetBsdf *bsdf)
ccl_device int bsdf_microfacet_multi_ggx_glass_fresnel_setup(ccl_private MicrofacetBsdf *bsdf, ccl_private const ShaderData *sd)
ccl_device int bsdf_microfacet_multi_ggx_setup(ccl_private MicrofacetBsdf *bsdf)
ccl_device int bsdf_microfacet_multi_ggx_glass_setup(ccl_private MicrofacetBsdf *bsdf)
ccl_device int bsdf_microfacet_multi_ggx_fresnel_setup(ccl_private MicrofacetBsdf *bsdf, ccl_private const ShaderData *sd)
ClosureParam * closure_bsdf_phong_ramp_params()
ccl_device int bsdf_principled_sheen_setup(ccl_private const ShaderData *sd, ccl_private PrincipledSheenBsdf *bsdf)
CCL_NAMESPACE_BEGIN ccl_device void bsdf_transparent_setup(ccl_private ShaderData *sd, const float3 weight, uint32_t path_flag)
ccl_device float3 ensure_valid_reflection(float3 Ng, float3 I, float3 N)
Definition: bsdf_util.h:127
ClosureParam * closure_bssrdf_params()
Definition: bssrdf.cpp:83
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
bool skip(const ShaderData *sd, uint32_t path_flag, int scattering)
Definition: closures.cpp:478
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
Definition: closures.cpp:501
ustring distribution
Definition: closures.cpp:498
MicrofacetBsdf params
Definition: closures.cpp:497
MicrofacetBsdf * alloc(ShaderData *sd, uint32_t path_flag, float3 weight)
Definition: closures.cpp:579
MicrofacetBsdf params
Definition: closures.cpp:575
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
Definition: closures.cpp:640
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
Definition: closures.cpp:609
MicrofacetBsdf * alloc(ShaderData *sd, uint32_t path_flag, float3 weight)
Definition: closures.cpp:677
MicrofacetBsdf params
Definition: closures.cpp:674
MicrofacetBsdf * alloc(ShaderData *sd, uint32_t path_flag, float3 weight)
Definition: closures.cpp:807
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
Definition: closures.cpp:737
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
Definition: closures.cpp:869
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
Definition: closures.cpp:707
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
Definition: closures.cpp:837
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
Definition: closures.cpp:771
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
Definition: closures.cpp:905
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
Definition: closures.cpp:287
MicrofacetBsdf * alloc(ShaderData *sd, uint32_t path_flag, float3 weight)
Definition: closures.cpp:263
PrincipledHairBSDF * alloc(ShaderData *sd, uint32_t path_flag, float3 weight)
Definition: closures.cpp:207
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
Definition: closures.cpp:225
PrincipledHairBSDF params
Definition: closures.cpp:205
PrincipledSheenBsdf params
Definition: closures.cpp:178
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
Definition: closures.cpp:180
ShaderClosure params
Definition: closures.cpp:939
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
Definition: closures.cpp:942
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
Definition: closures.cpp:961
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
Definition: closures.cpp:980
HenyeyGreensteinVolume params
Definition: closures.cpp:978
ClosureParam * closure_bsdf_microfacet_multi_ggx_aniso_params()
Definition: closures.cpp:751
BSDF_CLOSURE_CLASS_BEGIN(AshikhminShirley, ashikhmin_shirley, MicrofacetBsdf, LABEL_GLOSSY|LABEL_REFLECT) BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXIsotropic
ClosureParam * closure_bsdf_microfacet_multi_ggx_params()
Definition: closures.cpp:723
static ClosureParam * bsdf_principled_sheen_params()
Definition: closures.cpp:192
ClosureParam * closure_bsdf_transparent_params()
Definition: closures.cpp:948
LABEL_GLOSSY LABEL_REFLECT LABEL_GLOSSY LABEL_REFLECT microfacet_ggx_refraction
Definition: closures.cpp:135
ClosureParam * closure_bsdf_principled_clearcoat_params()
Definition: closures.cpp:299
ClosureParam * closure_bsdf_microfacet_multi_ggx_glass_params()
Definition: closures.cpp:786
ClosureParam * closure_absorption_params()
Definition: closures.cpp:967
ClosureParam * closure_henyey_greenstein_params()
Definition: closures.cpp:994
LABEL_GLOSSY LABEL_REFLECT microfacet_beckmann_isotropic
Definition: closures.cpp:117
CCLOSURE_PREPARE(closure_bsdf_microfacet_ggx_fresnel_prepare, MicrofacetGGXFresnelClosure)
static void register_closure(OSL::ShadingSystem *ss, const char *name, int id, OSL::ClosureParam *params, OSL::PrepareClosureFunc prepare)
Definition: closures.cpp:313
static ClosureParam * closure_bsdf_principled_hair_params()
Definition: closures.cpp:240
ClosureParam * closure_bsdf_microfacet_multi_ggx_aniso_fresnel_params()
Definition: closures.cpp:882
ClosureParam * closure_bsdf_microfacet_params()
Definition: closures.cpp:555
LABEL_GLOSSY LABEL_REFLECT LABEL_GLOSSY LABEL_REFLECT LABEL_GLOSSY LABEL_TRANSMIT principled_diffuse
Definition: closures.cpp:169
microfacet_ggx_isotropic
Definition: closures.cpp:99
ClosureParam * closure_bsdf_microfacet_ggx_fresnel_params()
Definition: closures.cpp:624
ClosureParam * closure_bsdf_microfacet_multi_ggx_glass_fresnel_params()
Definition: closures.cpp:920
ClosureParam * closure_bsdf_microfacet_ggx_aniso_fresnel_params()
Definition: closures.cpp:653
ClosureParam * closure_bsdf_microfacet_multi_ggx_fresnel_params()
Definition: closures.cpp:852
#define CCLOSURE_PREPARE_STATIC(name, classname)
Definition: closures.h:77
void closure_bssrdf_prepare(OSL::RendererServices *, int id, void *data)
void closure_emission_prepare(OSL::RendererServices *, int id, void *data)
#define CLOSURE_FLOAT3_PARAM(st, fld)
Definition: closures.h:79
CCL_NAMESPACE_BEGIN OSL::ClosureParam * closure_emission_params()
Definition: emissive.cpp:41
void closure_bsdf_transparent_prepare(OSL::RendererServices *, int id, void *data)
void closure_bsdf_microfacet_multi_ggx_prepare(OSL::RendererServices *, int id, void *data)
void closure_bsdf_microfacet_prepare(OSL::RendererServices *, int id, void *data)
void closure_bsdf_principled_clearcoat_prepare(OSL::RendererServices *, int id, void *data)
void closure_bsdf_microfacet_ggx_fresnel_prepare(OSL::RendererServices *, int id, void *data)
#define BSDF_CLOSURE_FLOAT3_PARAM(st, fld)
Definition: closures.h:85
void closure_bsdf_microfacet_multi_ggx_fresnel_prepare(OSL::RendererServices *, int id, void *data)
void closure_bsdf_microfacet_ggx_aniso_fresnel_prepare(OSL::RendererServices *, int id, void *data)
#define BSDF_CLOSURE_FLOAT_PARAM(st, fld)
Definition: closures.h:84
void closure_henyey_greenstein_prepare(OSL::RendererServices *, int id, void *data)
void closure_bsdf_principled_hair_prepare(OSL::RendererServices *, int id, void *data)
void closure_background_prepare(OSL::RendererServices *, int id, void *data)
void closure_absorption_prepare(OSL::RendererServices *, int id, void *data)
void closure_bsdf_phong_ramp_prepare(OSL::RendererServices *, int id, void *data)
void closure_bsdf_microfacet_multi_ggx_aniso_prepare(OSL::RendererServices *, int id, void *data)
#define BSDF_CLOSURE_CLASS_END(Upper, lower)
Definition: closures.h:130
void closure_holdout_prepare(OSL::RendererServices *, int id, void *data)
void closure_bsdf_microfacet_multi_ggx_glass_fresnel_prepare(OSL::RendererServices *, int id, void *data)
void closure_bsdf_diffuse_ramp_prepare(OSL::RendererServices *, int id, void *data)
void closure_bsdf_microfacet_multi_ggx_glass_prepare(OSL::RendererServices *, int id, void *data)
void closure_bsdf_microfacet_multi_ggx_aniso_fresnel_prepare(OSL::RendererServices *, int id, void *data)
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
const char * label
#define kernel_data
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
ccl_device int volume_henyey_greenstein_setup(ccl_private HenyeyGreensteinVolume *volume)
CCL_NAMESPACE_BEGIN ccl_device void volume_extinction_setup(ccl_private ShaderData *sd, float3 weight)
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
ClosureParam * closure_holdout_params()
ClosureParam * closure_background_params()
@ PATH_RAY_DIFFUSE
Definition: kernel/types.h:197
ShaderData
Definition: kernel/types.h:925
@ LABEL_TRANSMIT
Definition: kernel/types.h:317
@ LABEL_DIFFUSE
Definition: kernel/types.h:319
@ LABEL_SINGULAR
Definition: kernel/types.h:321
@ LABEL_GLOSSY
Definition: kernel/types.h:320
@ LABEL_REFLECT
Definition: kernel/types.h:318
ShaderClosure
Definition: kernel/types.h:726
ccl_device_inline float3 refract(const float3 incident, const float3 normal, const float eta)
Definition: math_float3.h:435
#define N
#define T
#define make_float3(x, y, z)
Definition: metal/compat.h:204
static const pxr::TfToken clearcoat("clearcoat", pxr::TfToken::Immortal)
static const pxr::TfToken ior("ior", pxr::TfToken::Immortal)
static const pxr::TfToken roughness("roughness", pxr::TfToken::Immortal)
smooth(Type::FLOAT, "mask_weight")
ShadingSystem
Definition: scene/shader.h:34
closure color microfacet_ggx(normal N, float ag) BUILTIN
closure color diffuse_toon(normal N, float size, float smooth) BUILTIN
closure color hair_transmission(normal N, float roughnessu, float roughnessv, vector T, float offset) BUILTIN
closure color ashikhmin_velvet(normal N, float sigma) BUILTIN
closure color hair_reflection(normal N, float roughnessu, float roughnessv, vector T, float offset) BUILTIN
closure color microfacet_beckmann(normal N, float ab) BUILTIN
closure color ashikhmin_shirley(normal N, vector T, float ax, float ay) BUILTIN
closure color glossy_toon(normal N, float size, float smooth) BUILTIN
closure color microfacet_beckmann_refraction(normal N, float ab, float eta) BUILTIN
unsigned int uint32_t
Definition: stdint.h:80
ccl_private MicrofacetExtra * extra
ccl_private PrincipledHairExtra * extra