1 /*
2 * Adapted from Open Shading Language with this license:
3 *
4 * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
5 * All Rights Reserved.
6 *
7 * Modifications Copyright 2011-2018, Blender Foundation.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are
11 * met:
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * * Neither the name of Sony Pictures Imageworks nor the names of its
18 * contributors may be used to endorse or promote products derived from
19 * this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include <OSL/genclosure.h>
34 #include <OSL/oslclosure.h>
35
36 #include "kernel/osl/osl_closures.h"
37 #include "kernel/osl/osl_shader.h"
38
39 #include "util/util_math.h"
40 #include "util/util_param.h"
41
42 // clang-format off
43 #include "kernel/kernel_types.h"
44 #include "kernel/kernel_compat_cpu.h"
45 #include "kernel/split/kernel_split_data_types.h"
46 #include "kernel/kernel_globals.h"
47 #include "kernel/kernel_montecarlo.h"
48 #include "kernel/kernel_random.h"
49
50 #include "kernel/closure/alloc.h"
51 #include "kernel/closure/bsdf_util.h"
52 #include "kernel/closure/bsdf_ashikhmin_velvet.h"
53 #include "kernel/closure/bsdf_diffuse.h"
54 #include "kernel/closure/bsdf_microfacet.h"
55 #include "kernel/closure/bsdf_microfacet_multi.h"
56 #include "kernel/closure/bsdf_oren_nayar.h"
57 #include "kernel/closure/bsdf_reflection.h"
58 #include "kernel/closure/bsdf_refraction.h"
59 #include "kernel/closure/bsdf_transparent.h"
60 #include "kernel/closure/bsdf_ashikhmin_shirley.h"
61 #include "kernel/closure/bsdf_toon.h"
62 #include "kernel/closure/bsdf_hair.h"
63 #include "kernel/closure/bsdf_hair_principled.h"
64 #include "kernel/closure/bsdf_principled_diffuse.h"
65 #include "kernel/closure/bsdf_principled_sheen.h"
66 #include "kernel/closure/volume.h"
67 // clang-format on
68
69 CCL_NAMESPACE_BEGIN
70
71 using namespace OSL;
72
73 /* BSDF class definitions */
74
75 BSDF_CLOSURE_CLASS_BEGIN(Diffuse, diffuse, DiffuseBsdf, LABEL_DIFFUSE)
76 CLOSURE_FLOAT3_PARAM(DiffuseClosure, params.N),
77 BSDF_CLOSURE_CLASS_END(Diffuse, diffuse)
78
79 BSDF_CLOSURE_CLASS_BEGIN(Translucent, translucent, DiffuseBsdf, LABEL_DIFFUSE)
80 CLOSURE_FLOAT3_PARAM(TranslucentClosure, params.N),
81 BSDF_CLOSURE_CLASS_END(Translucent, translucent)
82
83 BSDF_CLOSURE_CLASS_BEGIN(OrenNayar, oren_nayar, OrenNayarBsdf, LABEL_DIFFUSE)
84 CLOSURE_FLOAT3_PARAM(OrenNayarClosure, params.N),
85 CLOSURE_FLOAT_PARAM(OrenNayarClosure, params.roughness),
86 BSDF_CLOSURE_CLASS_END(OrenNayar, oren_nayar)
87
88 BSDF_CLOSURE_CLASS_BEGIN(Reflection, reflection, MicrofacetBsdf, LABEL_SINGULAR)
89 CLOSURE_FLOAT3_PARAM(ReflectionClosure, params.N),
90 BSDF_CLOSURE_CLASS_END(Reflection, reflection)
91
92 BSDF_CLOSURE_CLASS_BEGIN(Refraction, refraction, MicrofacetBsdf, LABEL_SINGULAR)
93 CLOSURE_FLOAT3_PARAM(RefractionClosure, params.N),
94 CLOSURE_FLOAT_PARAM(RefractionClosure, params.ior),
95 BSDF_CLOSURE_CLASS_END(Refraction, refraction)
96
97 BSDF_CLOSURE_CLASS_BEGIN(AshikhminVelvet, ashikhmin_velvet, VelvetBsdf, LABEL_DIFFUSE)
98 CLOSURE_FLOAT3_PARAM(AshikhminVelvetClosure, params.N),
99 CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, params.sigma),
100 BSDF_CLOSURE_CLASS_END(AshikhminVelvet, ashikhmin_velvet)
101
102 BSDF_CLOSURE_CLASS_BEGIN(AshikhminShirley,
103 ashikhmin_shirley,
104 MicrofacetBsdf,
105 LABEL_GLOSSY | LABEL_REFLECT)
106 CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, params.N),
107 CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, params.T),
108 CLOSURE_FLOAT_PARAM(AshikhminShirleyClosure, params.alpha_x),
109 CLOSURE_FLOAT_PARAM(AshikhminShirleyClosure, params.alpha_y),
110 BSDF_CLOSURE_CLASS_END(AshikhminShirley, ashikhmin_shirley)
111
112 BSDF_CLOSURE_CLASS_BEGIN(DiffuseToon, diffuse_toon, ToonBsdf, LABEL_DIFFUSE)
113 CLOSURE_FLOAT3_PARAM(DiffuseToonClosure, params.N),
114 CLOSURE_FLOAT_PARAM(DiffuseToonClosure, params.size),
115 CLOSURE_FLOAT_PARAM(DiffuseToonClosure, params.smooth),
116 BSDF_CLOSURE_CLASS_END(DiffuseToon, diffuse_toon)
117
118 BSDF_CLOSURE_CLASS_BEGIN(GlossyToon, glossy_toon, ToonBsdf, LABEL_GLOSSY)
119 CLOSURE_FLOAT3_PARAM(GlossyToonClosure, params.N),
120 CLOSURE_FLOAT_PARAM(GlossyToonClosure, params.size),
121 CLOSURE_FLOAT_PARAM(GlossyToonClosure, params.smooth),
122 BSDF_CLOSURE_CLASS_END(GlossyToon, glossy_toon)
123
124 BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXIsotropic,
125 microfacet_ggx_isotropic,
126 MicrofacetBsdf,
127 LABEL_GLOSSY | LABEL_REFLECT)
128 CLOSURE_FLOAT3_PARAM(MicrofacetGGXIsotropicClosure, params.N),
129 CLOSURE_FLOAT_PARAM(MicrofacetGGXIsotropicClosure, params.alpha_x),
130 BSDF_CLOSURE_CLASS_END(MicrofacetGGXIsotropic, microfacet_ggx_isotropic)
131
132 BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGX,
133 microfacet_ggx,
134 MicrofacetBsdf,
135 LABEL_GLOSSY | LABEL_REFLECT)
136 CLOSURE_FLOAT3_PARAM(MicrofacetGGXClosure, params.N),
137 CLOSURE_FLOAT3_PARAM(MicrofacetGGXClosure, params.T),
138 CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, params.alpha_x),
139 CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, params.alpha_y),
140 BSDF_CLOSURE_CLASS_END(MicrofacetGGX, microfacet_ggx)
141
142 BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannIsotropic,
143 microfacet_beckmann_isotropic,
144 MicrofacetBsdf,
145 LABEL_GLOSSY | LABEL_REFLECT)
146 CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannIsotropicClosure, params.N),
147 CLOSURE_FLOAT_PARAM(MicrofacetBeckmannIsotropicClosure, params.alpha_x),
148 BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannIsotropic, microfacet_beckmann_isotropic)
149
150 BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmann,
151 microfacet_beckmann,
152 MicrofacetBsdf,
153 LABEL_GLOSSY | LABEL_REFLECT)
154 CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannClosure, params.N),
155 CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannClosure, params.T),
156 CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, params.alpha_x),
157 CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, params.alpha_y),
158 BSDF_CLOSURE_CLASS_END(MicrofacetBeckmann, microfacet_beckmann)
159
160 BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXRefraction,
161 microfacet_ggx_refraction,
162 MicrofacetBsdf,
163 LABEL_GLOSSY | LABEL_TRANSMIT)
164 CLOSURE_FLOAT3_PARAM(MicrofacetGGXRefractionClosure, params.N),
165 CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, params.alpha_x),
166 CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, params.ior),
167 BSDF_CLOSURE_CLASS_END(MicrofacetGGXRefraction, microfacet_ggx_refraction)
168
169 BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannRefraction,
170 microfacet_beckmann_refraction,
171 MicrofacetBsdf,
172 LABEL_GLOSSY | LABEL_TRANSMIT)
173 CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannRefractionClosure, params.N),
174 CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, params.alpha_x),
175 CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, params.ior),
176 BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction)
177
178 BSDF_CLOSURE_CLASS_BEGIN(HairReflection, hair_reflection, HairBsdf, LABEL_GLOSSY)
179 CLOSURE_FLOAT3_PARAM(HairReflectionClosure, params.N),
180 CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.roughness1),
181 CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.roughness2),
182 CLOSURE_FLOAT3_PARAM(HairReflectionClosure, params.T),
183 CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.offset),
184 BSDF_CLOSURE_CLASS_END(HairReflection, hair_reflection)
185
186 BSDF_CLOSURE_CLASS_BEGIN(HairTransmission, hair_transmission, HairBsdf, LABEL_GLOSSY)
187 CLOSURE_FLOAT3_PARAM(HairTransmissionClosure, params.N),
188 CLOSURE_FLOAT_PARAM(HairTransmissionClosure, params.roughness1),
189 CLOSURE_FLOAT_PARAM(HairTransmissionClosure, params.roughness2),
190 CLOSURE_FLOAT3_PARAM(HairReflectionClosure, params.T),
191 CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.offset),
192 BSDF_CLOSURE_CLASS_END(HairTransmission, hair_transmission)
193
194 BSDF_CLOSURE_CLASS_BEGIN(PrincipledDiffuse,
195 principled_diffuse,
196 PrincipledDiffuseBsdf,
197 LABEL_DIFFUSE)
198 CLOSURE_FLOAT3_PARAM(PrincipledDiffuseClosure, params.N),
199 CLOSURE_FLOAT_PARAM(PrincipledDiffuseClosure, params.roughness),
200 BSDF_CLOSURE_CLASS_END(PrincipledDiffuse, principled_diffuse)
201
202 class PrincipledSheenClosure : public CBSDFClosure {
203 public:
204 PrincipledSheenBsdf params;
205
setup(ShaderData * sd,int path_flag,float3 weight)206 void setup(ShaderData *sd, int path_flag, float3 weight)
207 {
208 if (!skip(sd, path_flag, LABEL_DIFFUSE)) {
209 PrincipledSheenBsdf *bsdf = (PrincipledSheenBsdf *)bsdf_alloc_osl(
210 sd, sizeof(PrincipledSheenBsdf), weight, ¶ms);
211 sd->flag |= (bsdf) ? bsdf_principled_sheen_setup(sd, bsdf) : 0;
212 }
213 }
214 };
215
bsdf_principled_sheen_params()216 static ClosureParam *bsdf_principled_sheen_params()
217 {
218 static ClosureParam params[] = {CLOSURE_FLOAT3_PARAM(PrincipledSheenClosure, params.N),
219 CLOSURE_STRING_KEYPARAM(PrincipledSheenClosure, label, "label"),
220 CLOSURE_FINISH_PARAM(PrincipledSheenClosure)};
221 return params;
222 }
223
224 CCLOSURE_PREPARE_STATIC(closure_bsdf_principled_sheen_prepare, PrincipledSheenClosure)
225
226 /* PRINCIPLED HAIR BSDF */
227 class PrincipledHairClosure : public CBSDFClosure {
228 public:
229 PrincipledHairBSDF params;
230
alloc(ShaderData * sd,int path_flag,float3 weight)231 PrincipledHairBSDF *alloc(ShaderData *sd, int path_flag, float3 weight)
232 {
233 PrincipledHairBSDF *bsdf = (PrincipledHairBSDF *)bsdf_alloc_osl(
234 sd, sizeof(PrincipledHairBSDF), weight, ¶ms);
235 if (!bsdf) {
236 return NULL;
237 }
238
239 PrincipledHairExtra *extra = (PrincipledHairExtra *)closure_alloc_extra(
240 sd, sizeof(PrincipledHairExtra));
241 if (!extra) {
242 return NULL;
243 }
244
245 bsdf->extra = extra;
246 return bsdf;
247 }
248
setup(ShaderData * sd,int path_flag,float3 weight)249 void setup(ShaderData *sd, int path_flag, float3 weight)
250 {
251 if (!skip(sd, path_flag, LABEL_GLOSSY)) {
252 PrincipledHairBSDF *bsdf = (PrincipledHairBSDF *)alloc(sd, path_flag, weight);
253 if (!bsdf) {
254 return;
255 }
256
257 sd->flag |= (bsdf) ? bsdf_principled_hair_setup(sd, bsdf) : 0;
258 }
259 }
260 };
261
closure_bsdf_principled_hair_params()262 static ClosureParam *closure_bsdf_principled_hair_params()
263 {
264 static ClosureParam params[] = {CLOSURE_FLOAT3_PARAM(PrincipledHairClosure, params.N),
265 CLOSURE_FLOAT3_PARAM(PrincipledHairClosure, params.sigma),
266 CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.v),
267 CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.s),
268 CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.m0_roughness),
269 CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.alpha),
270 CLOSURE_FLOAT_PARAM(PrincipledHairClosure, params.eta),
271 CLOSURE_STRING_KEYPARAM(PrincipledHairClosure, label, "label"),
272 CLOSURE_FINISH_PARAM(PrincipledHairClosure)};
273
274 return params;
275 }
276
277 CCLOSURE_PREPARE(closure_bsdf_principled_hair_prepare, PrincipledHairClosure)
278
279 /* DISNEY PRINCIPLED CLEARCOAT */
280 class PrincipledClearcoatClosure : public CBSDFClosure {
281 public:
282 MicrofacetBsdf params;
283 float clearcoat, clearcoat_roughness;
284
alloc(ShaderData * sd,int path_flag,float3 weight)285 MicrofacetBsdf *alloc(ShaderData *sd, int path_flag, float3 weight)
286 {
287 MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl(
288 sd, sizeof(MicrofacetBsdf), weight, ¶ms);
289 if (!bsdf) {
290 return NULL;
291 }
292
293 MicrofacetExtra *extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
294 if (!extra) {
295 return NULL;
296 }
297
298 bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
299 bsdf->extra = extra;
300 bsdf->ior = 1.5f;
301 bsdf->alpha_x = clearcoat_roughness;
302 bsdf->alpha_y = clearcoat_roughness;
303 bsdf->extra->color = make_float3(0.0f, 0.0f, 0.0f);
304 bsdf->extra->cspec0 = make_float3(0.04f, 0.04f, 0.04f);
305 bsdf->extra->clearcoat = clearcoat;
306 return bsdf;
307 }
308
setup(ShaderData * sd,int path_flag,float3 weight)309 void setup(ShaderData *sd, int path_flag, float3 weight)
310 {
311 MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
312 if (!bsdf) {
313 return;
314 }
315
316 sd->flag |= bsdf_microfacet_ggx_clearcoat_setup(bsdf, sd);
317 }
318 };
319
closure_bsdf_principled_clearcoat_params()320 ClosureParam *closure_bsdf_principled_clearcoat_params()
321 {
322 static ClosureParam params[] = {
323 CLOSURE_FLOAT3_PARAM(PrincipledClearcoatClosure, params.N),
324 CLOSURE_FLOAT_PARAM(PrincipledClearcoatClosure, clearcoat),
325 CLOSURE_FLOAT_PARAM(PrincipledClearcoatClosure, clearcoat_roughness),
326 CLOSURE_STRING_KEYPARAM(PrincipledClearcoatClosure, label, "label"),
327 CLOSURE_FINISH_PARAM(PrincipledClearcoatClosure)};
328 return params;
329 }
CCLOSURE_PREPARE(closure_bsdf_principled_clearcoat_prepare,PrincipledClearcoatClosure)330 CCLOSURE_PREPARE(closure_bsdf_principled_clearcoat_prepare, PrincipledClearcoatClosure)
331
332 /* Registration */
333
334 static void register_closure(OSL::ShadingSystem *ss,
335 const char *name,
336 int id,
337 OSL::ClosureParam *params,
338 OSL::PrepareClosureFunc prepare)
339 {
340 /* optimization: it's possible to not use a prepare function at all and
341 * only initialize the actual class when accessing the closure component
342 * data, but then we need to map the id to the class somehow */
343 #if OSL_LIBRARY_VERSION_CODE >= 10900
344 ss->register_closure(name, id, params, prepare, NULL);
345 #else
346 ss->register_closure(name, id, params, prepare, NULL, 16);
347 #endif
348 }
349
register_closures(OSLShadingSystem * ss_)350 void OSLShader::register_closures(OSLShadingSystem *ss_)
351 {
352 OSL::ShadingSystem *ss = (OSL::ShadingSystem *)ss_;
353 int id = 0;
354
355 register_closure(ss, "diffuse", id++, bsdf_diffuse_params(), bsdf_diffuse_prepare);
356 register_closure(ss, "oren_nayar", id++, bsdf_oren_nayar_params(), bsdf_oren_nayar_prepare);
357 register_closure(ss, "translucent", id++, bsdf_translucent_params(), bsdf_translucent_prepare);
358 register_closure(ss, "reflection", id++, bsdf_reflection_params(), bsdf_reflection_prepare);
359 register_closure(ss, "refraction", id++, bsdf_refraction_params(), bsdf_refraction_prepare);
360 register_closure(ss,
361 "transparent",
362 id++,
363 closure_bsdf_transparent_params(),
364 closure_bsdf_transparent_prepare);
365
366 register_closure(
367 ss, "microfacet", id++, closure_bsdf_microfacet_params(), closure_bsdf_microfacet_prepare);
368 register_closure(ss,
369 "microfacet_ggx",
370 id++,
371 bsdf_microfacet_ggx_isotropic_params(),
372 bsdf_microfacet_ggx_isotropic_prepare);
373 register_closure(
374 ss, "microfacet_ggx_aniso", id++, bsdf_microfacet_ggx_params(), bsdf_microfacet_ggx_prepare);
375 register_closure(ss,
376 "microfacet_ggx_refraction",
377 id++,
378 bsdf_microfacet_ggx_refraction_params(),
379 bsdf_microfacet_ggx_refraction_prepare);
380 register_closure(ss,
381 "microfacet_multi_ggx",
382 id++,
383 closure_bsdf_microfacet_multi_ggx_params(),
384 closure_bsdf_microfacet_multi_ggx_prepare);
385 register_closure(ss,
386 "microfacet_multi_ggx_glass",
387 id++,
388 closure_bsdf_microfacet_multi_ggx_glass_params(),
389 closure_bsdf_microfacet_multi_ggx_glass_prepare);
390 register_closure(ss,
391 "microfacet_multi_ggx_aniso",
392 id++,
393 closure_bsdf_microfacet_multi_ggx_aniso_params(),
394 closure_bsdf_microfacet_multi_ggx_aniso_prepare);
395 register_closure(ss,
396 "microfacet_ggx_fresnel",
397 id++,
398 closure_bsdf_microfacet_ggx_fresnel_params(),
399 closure_bsdf_microfacet_ggx_fresnel_prepare);
400 register_closure(ss,
401 "microfacet_ggx_aniso_fresnel",
402 id++,
403 closure_bsdf_microfacet_ggx_aniso_fresnel_params(),
404 closure_bsdf_microfacet_ggx_aniso_fresnel_prepare);
405 register_closure(ss,
406 "microfacet_multi_ggx_fresnel",
407 id++,
408 closure_bsdf_microfacet_multi_ggx_fresnel_params(),
409 closure_bsdf_microfacet_multi_ggx_fresnel_prepare);
410 register_closure(ss,
411 "microfacet_multi_ggx_glass_fresnel",
412 id++,
413 closure_bsdf_microfacet_multi_ggx_glass_fresnel_params(),
414 closure_bsdf_microfacet_multi_ggx_glass_fresnel_prepare);
415 register_closure(ss,
416 "microfacet_multi_ggx_aniso_fresnel",
417 id++,
418 closure_bsdf_microfacet_multi_ggx_aniso_fresnel_params(),
419 closure_bsdf_microfacet_multi_ggx_aniso_fresnel_prepare);
420 register_closure(ss,
421 "microfacet_beckmann",
422 id++,
423 bsdf_microfacet_beckmann_isotropic_params(),
424 bsdf_microfacet_beckmann_isotropic_prepare);
425 register_closure(ss,
426 "microfacet_beckmann_aniso",
427 id++,
428 bsdf_microfacet_beckmann_params(),
429 bsdf_microfacet_beckmann_prepare);
430 register_closure(ss,
431 "microfacet_beckmann_refraction",
432 id++,
433 bsdf_microfacet_beckmann_refraction_params(),
434 bsdf_microfacet_beckmann_refraction_prepare);
435 register_closure(ss,
436 "ashikhmin_shirley",
437 id++,
438 bsdf_ashikhmin_shirley_params(),
439 bsdf_ashikhmin_shirley_prepare);
440 register_closure(
441 ss, "ashikhmin_velvet", id++, bsdf_ashikhmin_velvet_params(), bsdf_ashikhmin_velvet_prepare);
442 register_closure(
443 ss, "diffuse_toon", id++, bsdf_diffuse_toon_params(), bsdf_diffuse_toon_prepare);
444 register_closure(ss, "glossy_toon", id++, bsdf_glossy_toon_params(), bsdf_glossy_toon_prepare);
445 register_closure(ss,
446 "principled_diffuse",
447 id++,
448 bsdf_principled_diffuse_params(),
449 bsdf_principled_diffuse_prepare);
450 register_closure(ss,
451 "principled_sheen",
452 id++,
453 bsdf_principled_sheen_params(),
454 closure_bsdf_principled_sheen_prepare);
455 register_closure(ss,
456 "principled_clearcoat",
457 id++,
458 closure_bsdf_principled_clearcoat_params(),
459 closure_bsdf_principled_clearcoat_prepare);
460
461 register_closure(ss, "emission", id++, closure_emission_params(), closure_emission_prepare);
462 register_closure(
463 ss, "background", id++, closure_background_params(), closure_background_prepare);
464 register_closure(ss, "holdout", id++, closure_holdout_params(), closure_holdout_prepare);
465 register_closure(ss,
466 "diffuse_ramp",
467 id++,
468 closure_bsdf_diffuse_ramp_params(),
469 closure_bsdf_diffuse_ramp_prepare);
470 register_closure(
471 ss, "phong_ramp", id++, closure_bsdf_phong_ramp_params(), closure_bsdf_phong_ramp_prepare);
472 register_closure(ss, "bssrdf", id++, closure_bssrdf_params(), closure_bssrdf_prepare);
473
474 register_closure(
475 ss, "hair_reflection", id++, bsdf_hair_reflection_params(), bsdf_hair_reflection_prepare);
476 register_closure(ss,
477 "hair_transmission",
478 id++,
479 bsdf_hair_transmission_params(),
480 bsdf_hair_transmission_prepare);
481
482 register_closure(ss,
483 "principled_hair",
484 id++,
485 closure_bsdf_principled_hair_params(),
486 closure_bsdf_principled_hair_prepare);
487
488 register_closure(ss,
489 "henyey_greenstein",
490 id++,
491 closure_henyey_greenstein_params(),
492 closure_henyey_greenstein_prepare);
493 register_closure(
494 ss, "absorption", id++, closure_absorption_params(), closure_absorption_prepare);
495 }
496
497 /* BSDF Closure */
498
skip(const ShaderData * sd,int path_flag,int scattering)499 bool CBSDFClosure::skip(const ShaderData *sd, int path_flag, int scattering)
500 {
501 /* caustic options */
502 if ((scattering & LABEL_GLOSSY) && (path_flag & PATH_RAY_DIFFUSE)) {
503 KernelGlobals *kg = sd->osl_globals;
504
505 if ((!kernel_data.integrator.caustics_reflective && (scattering & LABEL_REFLECT)) ||
506 (!kernel_data.integrator.caustics_refractive && (scattering & LABEL_TRANSMIT))) {
507 return true;
508 }
509 }
510
511 return false;
512 }
513
514 /* Standard Microfacet Closure */
515
516 class MicrofacetClosure : public CBSDFClosure {
517 public:
518 MicrofacetBsdf params;
519 ustring distribution;
520 int refract;
521
setup(ShaderData * sd,int path_flag,float3 weight)522 void setup(ShaderData *sd, int path_flag, float3 weight)
523 {
524 static ustring u_ggx("ggx");
525 static ustring u_default("default");
526
527 const int label = (refract) ? LABEL_TRANSMIT : LABEL_REFLECT;
528 if (skip(sd, path_flag, LABEL_GLOSSY | label)) {
529 return;
530 }
531
532 MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl(
533 sd, sizeof(MicrofacetBsdf), weight, ¶ms);
534
535 if (!bsdf) {
536 return;
537 }
538
539 /* GGX */
540 if (distribution == u_ggx || distribution == u_default) {
541 if (!refract) {
542 if (params.alpha_x == params.alpha_y) {
543 /* Isotropic */
544 sd->flag |= bsdf_microfacet_ggx_isotropic_setup(bsdf);
545 }
546 else {
547 /* Anisotropic */
548 sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
549 }
550 }
551 else {
552 sd->flag |= bsdf_microfacet_ggx_refraction_setup(bsdf);
553 }
554 }
555 /* Beckmann */
556 else {
557 if (!refract) {
558 if (params.alpha_x == params.alpha_y) {
559 /* Isotropic */
560 sd->flag |= bsdf_microfacet_beckmann_isotropic_setup(bsdf);
561 }
562 else {
563 /* Anisotropic */
564 sd->flag |= bsdf_microfacet_beckmann_setup(bsdf);
565 }
566 }
567 else {
568 sd->flag |= bsdf_microfacet_beckmann_refraction_setup(bsdf);
569 }
570 }
571 }
572 };
573
closure_bsdf_microfacet_params()574 ClosureParam *closure_bsdf_microfacet_params()
575 {
576 static ClosureParam params[] = {CLOSURE_STRING_PARAM(MicrofacetClosure, distribution),
577 CLOSURE_FLOAT3_PARAM(MicrofacetClosure, params.N),
578 CLOSURE_FLOAT3_PARAM(MicrofacetClosure, params.T),
579 CLOSURE_FLOAT_PARAM(MicrofacetClosure, params.alpha_x),
580 CLOSURE_FLOAT_PARAM(MicrofacetClosure, params.alpha_y),
581 CLOSURE_FLOAT_PARAM(MicrofacetClosure, params.ior),
582 CLOSURE_INT_PARAM(MicrofacetClosure, refract),
583 CLOSURE_STRING_KEYPARAM(MicrofacetClosure, label, "label"),
584 CLOSURE_FINISH_PARAM(MicrofacetClosure)};
585
586 return params;
587 }
588 CCLOSURE_PREPARE(closure_bsdf_microfacet_prepare, MicrofacetClosure)
589
590 /* GGX closures with Fresnel */
591
592 class MicrofacetFresnelClosure : public CBSDFClosure {
593 public:
594 MicrofacetBsdf params;
595 float3 color;
596 float3 cspec0;
597
alloc(ShaderData * sd,int path_flag,float3 weight)598 MicrofacetBsdf *alloc(ShaderData *sd, int path_flag, float3 weight)
599 {
600 /* Technically, the MultiGGX Glass closure may also transmit. However,
601 * since this is set statically and only used for caustic flags, this
602 * is probably as good as it gets. */
603 if (skip(sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
604 return NULL;
605 }
606
607 MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl(
608 sd, sizeof(MicrofacetBsdf), weight, ¶ms);
609 if (!bsdf) {
610 return NULL;
611 }
612
613 MicrofacetExtra *extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
614 if (!extra) {
615 return NULL;
616 }
617
618 bsdf->extra = extra;
619 bsdf->extra->color = color;
620 bsdf->extra->cspec0 = cspec0;
621 bsdf->extra->clearcoat = 0.0f;
622 return bsdf;
623 }
624 };
625
626 class MicrofacetGGXFresnelClosure : public MicrofacetFresnelClosure {
627 public:
setup(ShaderData * sd,int path_flag,float3 weight)628 void setup(ShaderData *sd, int path_flag, float3 weight)
629 {
630 MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
631 if (!bsdf) {
632 return;
633 }
634
635 bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
636 bsdf->alpha_y = bsdf->alpha_x;
637 sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd);
638 }
639 };
640
closure_bsdf_microfacet_ggx_fresnel_params()641 ClosureParam *closure_bsdf_microfacet_ggx_fresnel_params()
642 {
643 static ClosureParam params[] = {
644 CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, params.N),
645 CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.alpha_x),
646 CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.ior),
647 CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, color),
648 CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, cspec0),
649 CLOSURE_STRING_KEYPARAM(MicrofacetGGXFresnelClosure, label, "label"),
650 CLOSURE_FINISH_PARAM(MicrofacetGGXFresnelClosure)};
651 return params;
652 }
653 CCLOSURE_PREPARE(closure_bsdf_microfacet_ggx_fresnel_prepare, MicrofacetGGXFresnelClosure);
654
655 class MicrofacetGGXAnisoFresnelClosure : public MicrofacetFresnelClosure {
656 public:
setup(ShaderData * sd,int path_flag,float3 weight)657 void setup(ShaderData *sd, int path_flag, float3 weight)
658 {
659 MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
660 if (!bsdf) {
661 return;
662 }
663
664 sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd);
665 }
666 };
667
closure_bsdf_microfacet_ggx_aniso_fresnel_params()668 ClosureParam *closure_bsdf_microfacet_ggx_aniso_fresnel_params()
669 {
670 static ClosureParam params[] = {
671 CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, params.N),
672 CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, params.T),
673 CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.alpha_x),
674 CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.alpha_y),
675 CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.ior),
676 CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, color),
677 CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, cspec0),
678 CLOSURE_STRING_KEYPARAM(MicrofacetGGXFresnelClosure, label, "label"),
679 CLOSURE_FINISH_PARAM(MicrofacetGGXFresnelClosure)};
680 return params;
681 }
682 CCLOSURE_PREPARE(closure_bsdf_microfacet_ggx_aniso_fresnel_prepare,
683 MicrofacetGGXAnisoFresnelClosure);
684
685 /* Multiscattering GGX closures */
686
687 class MicrofacetMultiClosure : public CBSDFClosure {
688 public:
689 MicrofacetBsdf params;
690 float3 color;
691
alloc(ShaderData * sd,int path_flag,float3 weight)692 MicrofacetBsdf *alloc(ShaderData *sd, int path_flag, float3 weight)
693 {
694 /* Technically, the MultiGGX closure may also transmit. However,
695 * since this is set statically and only used for caustic flags, this
696 * is probably as good as it gets. */
697 if (skip(sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
698 return NULL;
699 }
700
701 MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl(
702 sd, sizeof(MicrofacetBsdf), weight, ¶ms);
703 if (!bsdf) {
704 return NULL;
705 }
706
707 MicrofacetExtra *extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
708 if (!extra) {
709 return NULL;
710 }
711
712 bsdf->extra = extra;
713 bsdf->extra->color = color;
714 bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
715 bsdf->extra->clearcoat = 0.0f;
716 return bsdf;
717 }
718 };
719
720 class MicrofacetMultiGGXClosure : public MicrofacetMultiClosure {
721 public:
setup(ShaderData * sd,int path_flag,float3 weight)722 void setup(ShaderData *sd, int path_flag, float3 weight)
723 {
724 MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
725 if (!bsdf) {
726 return;
727 }
728
729 bsdf->ior = 0.0f;
730 bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
731 bsdf->alpha_y = bsdf->alpha_x;
732 sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf);
733 }
734 };
735
closure_bsdf_microfacet_multi_ggx_params()736 ClosureParam *closure_bsdf_microfacet_multi_ggx_params()
737 {
738 static ClosureParam params[] = {
739 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, params.N),
740 CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_x),
741 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, color),
742 CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXClosure, label, "label"),
743 CLOSURE_FINISH_PARAM(MicrofacetMultiGGXClosure)};
744 return params;
745 }
746 CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_prepare, MicrofacetMultiGGXClosure);
747
748 class MicrofacetMultiGGXAnisoClosure : public MicrofacetMultiClosure {
749 public:
setup(ShaderData * sd,int path_flag,float3 weight)750 void setup(ShaderData *sd, int path_flag, float3 weight)
751 {
752 MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
753 if (!bsdf) {
754 return;
755 }
756
757 bsdf->ior = 0.0f;
758 sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf);
759 }
760 };
761
closure_bsdf_microfacet_multi_ggx_aniso_params()762 ClosureParam *closure_bsdf_microfacet_multi_ggx_aniso_params()
763 {
764 static ClosureParam params[] = {
765 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, params.N),
766 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, params.T),
767 CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_x),
768 CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_y),
769 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, color),
770 CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXClosure, label, "label"),
771 CLOSURE_FINISH_PARAM(MicrofacetMultiGGXClosure)};
772 return params;
773 }
774 CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_aniso_prepare, MicrofacetMultiGGXAnisoClosure);
775
776 class MicrofacetMultiGGXGlassClosure : public MicrofacetMultiClosure {
777 public:
MicrofacetMultiGGXGlassClosure()778 MicrofacetMultiGGXGlassClosure() : MicrofacetMultiClosure()
779 {
780 }
781
setup(ShaderData * sd,int path_flag,float3 weight)782 void setup(ShaderData *sd, int path_flag, float3 weight)
783 {
784 MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
785 if (!bsdf) {
786 return;
787 }
788
789 bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
790 bsdf->alpha_y = bsdf->alpha_x;
791 sd->flag |= bsdf_microfacet_multi_ggx_glass_setup(bsdf);
792 }
793 };
794
closure_bsdf_microfacet_multi_ggx_glass_params()795 ClosureParam *closure_bsdf_microfacet_multi_ggx_glass_params()
796 {
797 static ClosureParam params[] = {
798 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, params.N),
799 CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_x),
800 CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.ior),
801 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, color),
802 CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXClosure, label, "label"),
803 CLOSURE_FINISH_PARAM(MicrofacetMultiGGXClosure)};
804 return params;
805 }
806 CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_glass_prepare, MicrofacetMultiGGXGlassClosure);
807
808 /* Multiscattering GGX closures with Fresnel */
809
810 class MicrofacetMultiFresnelClosure : public CBSDFClosure {
811 public:
812 MicrofacetBsdf params;
813 float3 color;
814 float3 cspec0;
815
alloc(ShaderData * sd,int path_flag,float3 weight)816 MicrofacetBsdf *alloc(ShaderData *sd, int path_flag, float3 weight)
817 {
818 /* Technically, the MultiGGX closure may also transmit. However,
819 * since this is set statically and only used for caustic flags, this
820 * is probably as good as it gets. */
821 if (skip(sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
822 return NULL;
823 }
824
825 MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc_osl(
826 sd, sizeof(MicrofacetBsdf), weight, ¶ms);
827 if (!bsdf) {
828 return NULL;
829 }
830
831 MicrofacetExtra *extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
832 if (!extra) {
833 return NULL;
834 }
835
836 bsdf->extra = extra;
837 bsdf->extra->color = color;
838 bsdf->extra->cspec0 = cspec0;
839 bsdf->extra->clearcoat = 0.0f;
840 return bsdf;
841 }
842 };
843
844 class MicrofacetMultiGGXFresnelClosure : public MicrofacetMultiFresnelClosure {
845 public:
setup(ShaderData * sd,int path_flag,float3 weight)846 void setup(ShaderData *sd, int path_flag, float3 weight)
847 {
848 MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
849 if (!bsdf) {
850 return;
851 }
852
853 bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
854 bsdf->alpha_y = bsdf->alpha_x;
855 sd->flag |= bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd);
856 }
857 };
858
closure_bsdf_microfacet_multi_ggx_fresnel_params()859 ClosureParam *closure_bsdf_microfacet_multi_ggx_fresnel_params()
860 {
861 static ClosureParam params[] = {
862 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, params.N),
863 CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_x),
864 CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.ior),
865 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, color),
866 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, cspec0),
867 CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXFresnelClosure, label, "label"),
868 CLOSURE_FINISH_PARAM(MicrofacetMultiGGXFresnelClosure)};
869 return params;
870 }
871 CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_fresnel_prepare,
872 MicrofacetMultiGGXFresnelClosure);
873
874 class MicrofacetMultiGGXAnisoFresnelClosure : public MicrofacetMultiFresnelClosure {
875 public:
setup(ShaderData * sd,int path_flag,float3 weight)876 void setup(ShaderData *sd, int path_flag, float3 weight)
877 {
878 MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
879 if (!bsdf) {
880 return;
881 }
882
883 sd->flag |= bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd);
884 }
885 };
886
closure_bsdf_microfacet_multi_ggx_aniso_fresnel_params()887 ClosureParam *closure_bsdf_microfacet_multi_ggx_aniso_fresnel_params()
888 {
889 static ClosureParam params[] = {
890 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, params.N),
891 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, params.T),
892 CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_x),
893 CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_y),
894 CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.ior),
895 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, color),
896 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, cspec0),
897 CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXFresnelClosure, label, "label"),
898 CLOSURE_FINISH_PARAM(MicrofacetMultiGGXFresnelClosure)};
899 return params;
900 }
901 CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_aniso_fresnel_prepare,
902 MicrofacetMultiGGXAnisoFresnelClosure);
903
904 class MicrofacetMultiGGXGlassFresnelClosure : public MicrofacetMultiFresnelClosure {
905 public:
MicrofacetMultiGGXGlassFresnelClosure()906 MicrofacetMultiGGXGlassFresnelClosure() : MicrofacetMultiFresnelClosure()
907 {
908 }
909
setup(ShaderData * sd,int path_flag,float3 weight)910 void setup(ShaderData *sd, int path_flag, float3 weight)
911 {
912 MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
913 if (!bsdf) {
914 return;
915 }
916
917 bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
918 bsdf->alpha_y = bsdf->alpha_x;
919 sd->flag |= bsdf_microfacet_multi_ggx_glass_fresnel_setup(bsdf, sd);
920 }
921 };
922
closure_bsdf_microfacet_multi_ggx_glass_fresnel_params()923 ClosureParam *closure_bsdf_microfacet_multi_ggx_glass_fresnel_params()
924 {
925 static ClosureParam params[] = {
926 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, params.N),
927 CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_x),
928 CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.ior),
929 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, color),
930 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, cspec0),
931 CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXFresnelClosure, label, "label"),
932 CLOSURE_FINISH_PARAM(MicrofacetMultiGGXFresnelClosure)};
933 return params;
934 }
935 CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_glass_fresnel_prepare,
936 MicrofacetMultiGGXGlassFresnelClosure);
937
938 /* Transparent */
939
940 class TransparentClosure : public CBSDFClosure {
941 public:
942 ShaderClosure params;
943 float3 unused;
944
setup(ShaderData * sd,int path_flag,float3 weight)945 void setup(ShaderData *sd, int path_flag, float3 weight)
946 {
947 bsdf_transparent_setup(sd, weight, path_flag);
948 }
949 };
950
closure_bsdf_transparent_params()951 ClosureParam *closure_bsdf_transparent_params()
952 {
953 static ClosureParam params[] = {CLOSURE_STRING_KEYPARAM(TransparentClosure, label, "label"),
954 CLOSURE_FINISH_PARAM(TransparentClosure)};
955 return params;
956 }
957
958 CCLOSURE_PREPARE(closure_bsdf_transparent_prepare, TransparentClosure)
959
960 /* Volume */
961
962 class VolumeAbsorptionClosure : public CBSDFClosure {
963 public:
setup(ShaderData * sd,int path_flag,float3 weight)964 void setup(ShaderData *sd, int path_flag, float3 weight)
965 {
966 volume_extinction_setup(sd, weight);
967 }
968 };
969
closure_absorption_params()970 ClosureParam *closure_absorption_params()
971 {
972 static ClosureParam params[] = {CLOSURE_STRING_KEYPARAM(VolumeAbsorptionClosure, label, "label"),
973 CLOSURE_FINISH_PARAM(VolumeAbsorptionClosure)};
974 return params;
975 }
976
977 CCLOSURE_PREPARE(closure_absorption_prepare, VolumeAbsorptionClosure)
978
979 class VolumeHenyeyGreensteinClosure : public CBSDFClosure {
980 public:
981 HenyeyGreensteinVolume params;
982
setup(ShaderData * sd,int path_flag,float3 weight)983 void setup(ShaderData *sd, int path_flag, float3 weight)
984 {
985 volume_extinction_setup(sd, weight);
986
987 HenyeyGreensteinVolume *volume = (HenyeyGreensteinVolume *)bsdf_alloc_osl(
988 sd, sizeof(HenyeyGreensteinVolume), weight, ¶ms);
989 if (!volume) {
990 return;
991 }
992
993 sd->flag |= volume_henyey_greenstein_setup(volume);
994 }
995 };
996
closure_henyey_greenstein_params()997 ClosureParam *closure_henyey_greenstein_params()
998 {
999 static ClosureParam params[] = {
1000 CLOSURE_FLOAT_PARAM(VolumeHenyeyGreensteinClosure, params.g),
1001 CLOSURE_STRING_KEYPARAM(VolumeHenyeyGreensteinClosure, label, "label"),
1002 CLOSURE_FINISH_PARAM(VolumeHenyeyGreensteinClosure)};
1003 return params;
1004 }
1005
1006 CCLOSURE_PREPARE(closure_henyey_greenstein_prepare, VolumeHenyeyGreensteinClosure)
1007
1008 CCL_NAMESPACE_END
1009