Remove redundant check for armature mode
[blender.git] / intern / cycles / kernel / osl / osl_closures.cpp
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, 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 #include "kernel/kernel_types.h"
43 #include "kernel/kernel_compat_cpu.h"
44 #include "kernel/split/kernel_split_data_types.h"
45 #include "kernel/kernel_globals.h"
46 #include "kernel/kernel_montecarlo.h"
47 #include "kernel/kernel_random.h"
48
49 #include "kernel/closure/alloc.h"
50 #include "kernel/closure/bsdf_util.h"
51 #include "kernel/closure/bsdf_ashikhmin_velvet.h"
52 #include "kernel/closure/bsdf_diffuse.h"
53 #include "kernel/closure/bsdf_microfacet.h"
54 #include "kernel/closure/bsdf_microfacet_multi.h"
55 #include "kernel/closure/bsdf_oren_nayar.h"
56 #include "kernel/closure/bsdf_reflection.h"
57 #include "kernel/closure/bsdf_refraction.h"
58 #include "kernel/closure/bsdf_transparent.h"
59 #include "kernel/closure/bsdf_ashikhmin_shirley.h"
60 #include "kernel/closure/bsdf_toon.h"
61 #include "kernel/closure/bsdf_hair.h"
62 #include "kernel/closure/bsdf_principled_diffuse.h"
63 #include "kernel/closure/bsdf_principled_sheen.h"
64 #include "kernel/closure/volume.h"
65
66 CCL_NAMESPACE_BEGIN
67
68 using namespace OSL;
69
70 /* BSDF class definitions */
71
72 BSDF_CLOSURE_CLASS_BEGIN(Diffuse, diffuse, DiffuseBsdf, LABEL_DIFFUSE)
73         CLOSURE_FLOAT3_PARAM(DiffuseClosure, params.N),
74 BSDF_CLOSURE_CLASS_END(Diffuse, diffuse)
75
76 BSDF_CLOSURE_CLASS_BEGIN(Translucent, translucent, DiffuseBsdf, LABEL_DIFFUSE)
77         CLOSURE_FLOAT3_PARAM(TranslucentClosure, params.N),
78 BSDF_CLOSURE_CLASS_END(Translucent, translucent)
79
80 BSDF_CLOSURE_CLASS_BEGIN(OrenNayar, oren_nayar, OrenNayarBsdf, LABEL_DIFFUSE)
81         CLOSURE_FLOAT3_PARAM(OrenNayarClosure, params.N),
82         CLOSURE_FLOAT_PARAM(OrenNayarClosure, params.roughness),
83 BSDF_CLOSURE_CLASS_END(OrenNayar, oren_nayar)
84
85 BSDF_CLOSURE_CLASS_BEGIN(Reflection, reflection, MicrofacetBsdf, LABEL_SINGULAR)
86         CLOSURE_FLOAT3_PARAM(ReflectionClosure, params.N),
87 BSDF_CLOSURE_CLASS_END(Reflection, reflection)
88
89 BSDF_CLOSURE_CLASS_BEGIN(Refraction, refraction, MicrofacetBsdf, LABEL_SINGULAR)
90         CLOSURE_FLOAT3_PARAM(RefractionClosure, params.N),
91         CLOSURE_FLOAT_PARAM(RefractionClosure, params.ior),
92 BSDF_CLOSURE_CLASS_END(Refraction, refraction)
93
94 BSDF_CLOSURE_CLASS_BEGIN(AshikhminVelvet, ashikhmin_velvet, VelvetBsdf, LABEL_DIFFUSE)
95         CLOSURE_FLOAT3_PARAM(AshikhminVelvetClosure, params.N),
96         CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, params.sigma),
97 BSDF_CLOSURE_CLASS_END(AshikhminVelvet, ashikhmin_velvet)
98
99 BSDF_CLOSURE_CLASS_BEGIN(AshikhminShirley, ashikhmin_shirley_aniso, MicrofacetBsdf, LABEL_GLOSSY|LABEL_REFLECT)
100         CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, params.N),
101         CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, params.T),
102         CLOSURE_FLOAT_PARAM(AshikhminShirleyClosure, params.alpha_x),
103         CLOSURE_FLOAT_PARAM(AshikhminShirleyClosure, params.alpha_y),
104 BSDF_CLOSURE_CLASS_END(AshikhminShirley, ashikhmin_shirley_aniso)
105
106 BSDF_CLOSURE_CLASS_BEGIN(DiffuseToon, diffuse_toon, ToonBsdf, LABEL_DIFFUSE)
107         CLOSURE_FLOAT3_PARAM(DiffuseToonClosure, params.N),
108         CLOSURE_FLOAT_PARAM(DiffuseToonClosure, params.size),
109         CLOSURE_FLOAT_PARAM(DiffuseToonClosure, params.smooth),
110 BSDF_CLOSURE_CLASS_END(DiffuseToon, diffuse_toon)
111
112 BSDF_CLOSURE_CLASS_BEGIN(GlossyToon, glossy_toon, ToonBsdf, LABEL_GLOSSY)
113         CLOSURE_FLOAT3_PARAM(GlossyToonClosure, params.N),
114         CLOSURE_FLOAT_PARAM(GlossyToonClosure, params.size),
115         CLOSURE_FLOAT_PARAM(GlossyToonClosure, params.smooth),
116 BSDF_CLOSURE_CLASS_END(GlossyToon, glossy_toon)
117
118 BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGX, microfacet_ggx, MicrofacetBsdf, LABEL_GLOSSY|LABEL_REFLECT)
119         CLOSURE_FLOAT3_PARAM(MicrofacetGGXClosure, params.N),
120         CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, params.alpha_x),
121 BSDF_CLOSURE_CLASS_END(MicrofacetGGX, microfacet_ggx)
122
123 BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXAniso, microfacet_ggx_aniso, MicrofacetBsdf, LABEL_GLOSSY|LABEL_REFLECT)
124         CLOSURE_FLOAT3_PARAM(MicrofacetGGXAnisoClosure, params.N),
125         CLOSURE_FLOAT3_PARAM(MicrofacetGGXAnisoClosure, params.T),
126         CLOSURE_FLOAT_PARAM(MicrofacetGGXAnisoClosure, params.alpha_x),
127         CLOSURE_FLOAT_PARAM(MicrofacetGGXAnisoClosure, params.alpha_y),
128 BSDF_CLOSURE_CLASS_END(MicrofacetGGXAniso, microfacet_ggx_aniso)
129
130 BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmann, microfacet_beckmann, MicrofacetBsdf, LABEL_GLOSSY|LABEL_REFLECT)
131         CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannClosure, params.N),
132         CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, params.alpha_x),
133 BSDF_CLOSURE_CLASS_END(MicrofacetBeckmann, microfacet_beckmann)
134
135 BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannAniso, microfacet_beckmann_aniso, MicrofacetBsdf, LABEL_GLOSSY|LABEL_REFLECT)
136         CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannAnisoClosure, params.N),
137         CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannAnisoClosure, params.T),
138         CLOSURE_FLOAT_PARAM(MicrofacetBeckmannAnisoClosure, params.alpha_x),
139         CLOSURE_FLOAT_PARAM(MicrofacetBeckmannAnisoClosure, params.alpha_y),
140 BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannAniso, microfacet_beckmann_aniso)
141
142 BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXRefraction, microfacet_ggx_refraction, MicrofacetBsdf, LABEL_GLOSSY|LABEL_TRANSMIT)
143         CLOSURE_FLOAT3_PARAM(MicrofacetGGXRefractionClosure, params.N),
144         CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, params.alpha_x),
145         CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, params.ior),
146 BSDF_CLOSURE_CLASS_END(MicrofacetGGXRefraction, microfacet_ggx_refraction)
147
148 BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction, MicrofacetBsdf, LABEL_GLOSSY|LABEL_TRANSMIT)
149         CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannRefractionClosure, params.N),
150         CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, params.alpha_x),
151         CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, params.ior),
152 BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction)
153
154 BSDF_CLOSURE_CLASS_BEGIN(HairReflection, hair_reflection, HairBsdf, LABEL_GLOSSY)
155         CLOSURE_FLOAT3_PARAM(HairReflectionClosure, params.N),
156         CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.roughness1),
157         CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.roughness2),
158         CLOSURE_FLOAT3_PARAM(HairReflectionClosure, params.T),
159         CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.offset),
160 BSDF_CLOSURE_CLASS_END(HairReflection, hair_reflection)
161
162 BSDF_CLOSURE_CLASS_BEGIN(HairTransmission, hair_transmission, HairBsdf, LABEL_GLOSSY)
163         CLOSURE_FLOAT3_PARAM(HairTransmissionClosure, params.N),
164         CLOSURE_FLOAT_PARAM(HairTransmissionClosure, params.roughness1),
165         CLOSURE_FLOAT_PARAM(HairTransmissionClosure, params.roughness2),
166         CLOSURE_FLOAT3_PARAM(HairReflectionClosure, params.T),
167         CLOSURE_FLOAT_PARAM(HairReflectionClosure, params.offset),
168 BSDF_CLOSURE_CLASS_END(HairTransmission, hair_transmission)
169
170 BSDF_CLOSURE_CLASS_BEGIN(PrincipledDiffuse, principled_diffuse, PrincipledDiffuseBsdf, LABEL_DIFFUSE)
171         CLOSURE_FLOAT3_PARAM(PrincipledDiffuseClosure, params.N),
172         CLOSURE_FLOAT_PARAM(PrincipledDiffuseClosure, params.roughness),
173 BSDF_CLOSURE_CLASS_END(PrincipledDiffuse, principled_diffuse)
174
175 BSDF_CLOSURE_CLASS_BEGIN(PrincipledSheen, principled_sheen, PrincipledSheenBsdf, LABEL_DIFFUSE)
176         CLOSURE_FLOAT3_PARAM(PrincipledSheenClosure, params.N),
177 BSDF_CLOSURE_CLASS_END(PrincipledSheen, principled_sheen)
178
179 /* DISNEY PRINCIPLED CLEARCOAT */
180 class PrincipledClearcoatClosure : public CBSDFClosure {
181 public:
182         MicrofacetBsdf params;
183         float clearcoat, clearcoat_roughness;
184
185         MicrofacetBsdf *alloc(ShaderData *sd, int path_flag, float3 weight)
186         {
187                 MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc_osl(sd, sizeof(MicrofacetBsdf), weight, &params);
188                 if(!bsdf) {
189                         return NULL;
190                 }
191
192                 MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
193                 if(!extra) {
194                         return NULL;
195                 }
196
197                 bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
198                 bsdf->extra = extra;
199                 bsdf->ior = 1.5f;
200                 bsdf->alpha_x = clearcoat_roughness;
201                 bsdf->alpha_y = clearcoat_roughness;
202                 bsdf->extra->color = make_float3(0.0f, 0.0f, 0.0f);
203                 bsdf->extra->cspec0 = make_float3(0.04f, 0.04f, 0.04f);
204                 bsdf->extra->clearcoat = clearcoat;
205                 return bsdf;
206         }
207
208         void setup(ShaderData *sd, int path_flag, float3 weight)
209         {
210                 MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
211                 if(!bsdf) {
212                         return;
213                 }
214
215                 sd->flag |= bsdf_microfacet_ggx_clearcoat_setup(bsdf, sd);
216         }
217 };
218
219 ClosureParam *closure_bsdf_principled_clearcoat_params()
220 {
221         static ClosureParam params[] = {
222                 CLOSURE_FLOAT3_PARAM(PrincipledClearcoatClosure, params.N),
223                 CLOSURE_FLOAT_PARAM(PrincipledClearcoatClosure, clearcoat),
224                 CLOSURE_FLOAT_PARAM(PrincipledClearcoatClosure, clearcoat_roughness),
225                 CLOSURE_STRING_KEYPARAM(PrincipledClearcoatClosure, label, "label"),
226                 CLOSURE_FINISH_PARAM(PrincipledClearcoatClosure)
227         };
228         return params;
229 }
230 CCLOSURE_PREPARE(closure_bsdf_principled_clearcoat_prepare, PrincipledClearcoatClosure)
231
232
233 /* Registration */
234
235 static void register_closure(OSL::ShadingSystem *ss, const char *name, int id, OSL::ClosureParam *params, OSL::PrepareClosureFunc prepare)
236 {
237         /* optimization: it's possible to not use a prepare function at all and
238          * only initialize the actual class when accessing the closure component
239          * data, but then we need to map the id to the class somehow */
240 #if OSL_LIBRARY_VERSION_CODE >= 10900
241         ss->register_closure(name, id, params, prepare, NULL);
242 #else
243         ss->register_closure(name, id, params, prepare, NULL, 16);
244 #endif
245 }
246
247 void OSLShader::register_closures(OSLShadingSystem *ss_)
248 {
249         OSL::ShadingSystem *ss = (OSL::ShadingSystem*)ss_;
250         int id = 0;
251
252         register_closure(ss, "diffuse", id++,
253                 bsdf_diffuse_params(), bsdf_diffuse_prepare);
254         register_closure(ss, "oren_nayar", id++,
255                 bsdf_oren_nayar_params(), bsdf_oren_nayar_prepare);
256         register_closure(ss, "translucent", id++,
257                 bsdf_translucent_params(), bsdf_translucent_prepare);
258         register_closure(ss, "reflection", id++,
259                 bsdf_reflection_params(), bsdf_reflection_prepare);
260         register_closure(ss, "refraction", id++,
261                 bsdf_refraction_params(), bsdf_refraction_prepare);
262         register_closure(ss, "transparent", id++,
263                 closure_bsdf_transparent_params(), closure_bsdf_transparent_prepare);
264         register_closure(ss, "microfacet_ggx", id++,
265                 bsdf_microfacet_ggx_params(), bsdf_microfacet_ggx_prepare);
266         register_closure(ss, "microfacet_ggx_aniso", id++,
267                 bsdf_microfacet_ggx_aniso_params(), bsdf_microfacet_ggx_aniso_prepare);
268         register_closure(ss, "microfacet_ggx_refraction", id++,
269                 bsdf_microfacet_ggx_refraction_params(), bsdf_microfacet_ggx_refraction_prepare);
270         register_closure(ss, "microfacet_multi_ggx", id++,
271                 closure_bsdf_microfacet_multi_ggx_params(), closure_bsdf_microfacet_multi_ggx_prepare);
272         register_closure(ss, "microfacet_multi_ggx_glass", id++,
273                 closure_bsdf_microfacet_multi_ggx_glass_params(), closure_bsdf_microfacet_multi_ggx_glass_prepare);
274         register_closure(ss, "microfacet_multi_ggx_aniso", id++,
275                 closure_bsdf_microfacet_multi_ggx_aniso_params(), closure_bsdf_microfacet_multi_ggx_aniso_prepare);
276         register_closure(ss, "microfacet_ggx_fresnel", id++,
277                 closure_bsdf_microfacet_ggx_fresnel_params(), closure_bsdf_microfacet_ggx_fresnel_prepare);
278         register_closure(ss, "microfacet_ggx_aniso_fresnel", id++,
279                 closure_bsdf_microfacet_ggx_aniso_fresnel_params(), closure_bsdf_microfacet_ggx_aniso_fresnel_prepare);
280         register_closure(ss, "microfacet_multi_ggx_fresnel", id++,
281                 closure_bsdf_microfacet_multi_ggx_fresnel_params(), closure_bsdf_microfacet_multi_ggx_fresnel_prepare);
282         register_closure(ss, "microfacet_multi_ggx_glass_fresnel", id++,
283                 closure_bsdf_microfacet_multi_ggx_glass_fresnel_params(), closure_bsdf_microfacet_multi_ggx_glass_fresnel_prepare);
284         register_closure(ss, "microfacet_multi_ggx_aniso_fresnel", id++,
285                 closure_bsdf_microfacet_multi_ggx_aniso_fresnel_params(), closure_bsdf_microfacet_multi_ggx_aniso_fresnel_prepare);
286         register_closure(ss, "microfacet_beckmann", id++,
287                 bsdf_microfacet_beckmann_params(), bsdf_microfacet_beckmann_prepare);
288         register_closure(ss, "microfacet_beckmann_aniso", id++,
289                 bsdf_microfacet_beckmann_aniso_params(), bsdf_microfacet_beckmann_aniso_prepare);
290         register_closure(ss, "microfacet_beckmann_refraction", id++,
291                 bsdf_microfacet_beckmann_refraction_params(), bsdf_microfacet_beckmann_refraction_prepare);
292         register_closure(ss, "ashikhmin_shirley", id++,
293                 bsdf_ashikhmin_shirley_aniso_params(), bsdf_ashikhmin_shirley_aniso_prepare);
294         register_closure(ss, "ashikhmin_velvet", id++,
295                 bsdf_ashikhmin_velvet_params(), bsdf_ashikhmin_velvet_prepare);
296         register_closure(ss, "diffuse_toon", id++,
297                 bsdf_diffuse_toon_params(), bsdf_diffuse_toon_prepare);
298         register_closure(ss, "glossy_toon", id++,
299                 bsdf_glossy_toon_params(), bsdf_glossy_toon_prepare);
300         register_closure(ss, "principled_diffuse", id++,
301                 bsdf_principled_diffuse_params(), bsdf_principled_diffuse_prepare);
302         register_closure(ss, "principled_sheen", id++,
303                 bsdf_principled_sheen_params(), bsdf_principled_sheen_prepare);
304         register_closure(ss, "principled_clearcoat", id++,
305                 closure_bsdf_principled_clearcoat_params(), closure_bsdf_principled_clearcoat_prepare);
306
307         register_closure(ss, "emission", id++,
308                 closure_emission_params(), closure_emission_prepare);
309         register_closure(ss, "background", id++,
310                 closure_background_params(), closure_background_prepare);
311         register_closure(ss, "holdout", id++,
312                 closure_holdout_params(), closure_holdout_prepare);
313         register_closure(ss, "ambient_occlusion", id++,
314                 closure_ambient_occlusion_params(), closure_ambient_occlusion_prepare);
315         register_closure(ss, "diffuse_ramp", id++,
316                 closure_bsdf_diffuse_ramp_params(), closure_bsdf_diffuse_ramp_prepare);
317         register_closure(ss, "phong_ramp", id++,
318                 closure_bsdf_phong_ramp_params(), closure_bsdf_phong_ramp_prepare);
319         register_closure(ss, "bssrdf_cubic", id++,
320                 closure_bssrdf_cubic_params(), closure_bssrdf_cubic_prepare);
321         register_closure(ss, "bssrdf_gaussian", id++,
322                 closure_bssrdf_gaussian_params(), closure_bssrdf_gaussian_prepare);
323         register_closure(ss, "bssrdf_burley", id++,
324                 closure_bssrdf_burley_params(), closure_bssrdf_burley_prepare);
325         register_closure(ss, "bssrdf_principled", id++,
326                 closure_bssrdf_principled_params(), closure_bssrdf_principled_prepare);
327
328         register_closure(ss, "hair_reflection", id++,
329                 bsdf_hair_reflection_params(), bsdf_hair_reflection_prepare);
330         register_closure(ss, "hair_transmission", id++,
331                 bsdf_hair_transmission_params(), bsdf_hair_transmission_prepare);
332
333         register_closure(ss, "henyey_greenstein", id++,
334                 closure_henyey_greenstein_params(), closure_henyey_greenstein_prepare);
335         register_closure(ss, "absorption", id++,
336                 closure_absorption_params(), closure_absorption_prepare);
337 }
338
339 /* BSDF Closure */
340
341 bool CBSDFClosure::skip(const ShaderData *sd, int path_flag, int scattering)
342 {
343         /* caustic options */
344         if((scattering & LABEL_GLOSSY) && (path_flag & PATH_RAY_DIFFUSE)) {
345                 KernelGlobals *kg = sd->osl_globals;
346
347                 if((!kernel_data.integrator.caustics_reflective && (scattering & LABEL_REFLECT)) ||
348                    (!kernel_data.integrator.caustics_refractive && (scattering & LABEL_TRANSMIT)))
349                 {
350                         return true;
351                 }
352         }
353
354         return false;
355 }
356
357
358 /* GGX closures with Fresnel */
359
360 class MicrofacetFresnelClosure : public CBSDFClosure {
361 public:
362         MicrofacetBsdf params;
363         float3 color;
364         float3 cspec0;
365
366         MicrofacetBsdf *alloc(ShaderData *sd, int path_flag, float3 weight)
367         {
368                 /* Technically, the MultiGGX Glass closure may also transmit. However,
369                 * since this is set statically and only used for caustic flags, this
370                 * is probably as good as it gets. */
371                 if(skip(sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
372                         return NULL;
373                 }
374
375                 MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc_osl(sd, sizeof(MicrofacetBsdf), weight, &params);
376                 if(!bsdf) {
377                         return NULL;
378                 }
379
380                 MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
381                 if(!extra) {
382                         return NULL;
383                 }
384
385                 bsdf->extra = extra;
386                 bsdf->extra->color = color;
387                 bsdf->extra->cspec0 = cspec0;
388                 bsdf->extra->clearcoat = 0.0f;
389                 return bsdf;
390         }
391 };
392
393 class MicrofacetGGXFresnelClosure : public MicrofacetFresnelClosure {
394 public:
395         void setup(ShaderData *sd, int path_flag, float3 weight)
396         {
397                 MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
398                 if(!bsdf) {
399                         return;
400                 }
401
402                 bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
403                 bsdf->alpha_y = bsdf->alpha_x;
404                 sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd);
405         }
406 };
407
408 ClosureParam *closure_bsdf_microfacet_ggx_fresnel_params()
409 {
410         static ClosureParam params[] = {
411                 CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, params.N),
412                 CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.alpha_x),
413                 CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.ior),
414                 CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, color),
415                 CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, cspec0),
416                 CLOSURE_STRING_KEYPARAM(MicrofacetGGXFresnelClosure, label, "label"),
417                 CLOSURE_FINISH_PARAM(MicrofacetGGXFresnelClosure)
418         };
419         return params;
420 }
421 CCLOSURE_PREPARE(closure_bsdf_microfacet_ggx_fresnel_prepare, MicrofacetGGXFresnelClosure);
422
423 class MicrofacetGGXAnisoFresnelClosure : public MicrofacetFresnelClosure {
424 public:
425         void setup(ShaderData *sd, int path_flag, float3 weight)
426         {
427                 MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
428                 if(!bsdf) {
429                         return;
430                 }
431
432                 sd->flag |= bsdf_microfacet_ggx_aniso_fresnel_setup(bsdf, sd);
433         }
434 };
435
436 ClosureParam *closure_bsdf_microfacet_ggx_aniso_fresnel_params()
437 {
438         static ClosureParam params[] = {
439                 CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, params.N),
440                 CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, params.T),
441                 CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.alpha_x),
442                 CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.alpha_y),
443                 CLOSURE_FLOAT_PARAM(MicrofacetGGXFresnelClosure, params.ior),
444                 CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, color),
445                 CLOSURE_FLOAT3_PARAM(MicrofacetGGXFresnelClosure, cspec0),
446                 CLOSURE_STRING_KEYPARAM(MicrofacetGGXFresnelClosure, label, "label"),
447                 CLOSURE_FINISH_PARAM(MicrofacetGGXFresnelClosure)
448         };
449         return params;
450 }
451 CCLOSURE_PREPARE(closure_bsdf_microfacet_ggx_aniso_fresnel_prepare, MicrofacetGGXAnisoFresnelClosure);
452
453
454 /* Multiscattering GGX closures */
455
456 class MicrofacetMultiClosure : public CBSDFClosure {
457 public:
458         MicrofacetBsdf params;
459         float3 color;
460
461         MicrofacetBsdf *alloc(ShaderData *sd, int path_flag, float3 weight)
462         {
463                 /* Technically, the MultiGGX closure may also transmit. However,
464                  * since this is set statically and only used for caustic flags, this
465                  * is probably as good as it gets. */
466             if(skip(sd, path_flag, LABEL_GLOSSY|LABEL_REFLECT)) {
467                         return NULL;
468                 }
469
470                 MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc_osl(sd, sizeof(MicrofacetBsdf), weight, &params);
471                 if(!bsdf) {
472                         return NULL;
473                 }
474
475                 MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
476                 if(!extra) {
477                         return NULL;
478                 }
479
480                 bsdf->extra = extra;
481                 bsdf->extra->color = color;
482                 bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
483                 bsdf->extra->clearcoat = 0.0f;
484                 return bsdf;
485         }
486 };
487
488 class MicrofacetMultiGGXClosure : public MicrofacetMultiClosure {
489 public:
490         void setup(ShaderData *sd, int path_flag, float3 weight)
491         {
492                 MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
493                 if(!bsdf) {
494                         return;
495                 }
496
497                 bsdf->ior = 0.0f;
498                 bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
499                 bsdf->alpha_y = bsdf->alpha_x;
500                 sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf);
501         }
502 };
503
504 ClosureParam *closure_bsdf_microfacet_multi_ggx_params()
505 {
506         static ClosureParam params[] = {
507                 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, params.N),
508                 CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_x),
509                 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, color),
510                 CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXClosure, label, "label"),
511                 CLOSURE_FINISH_PARAM(MicrofacetMultiGGXClosure)
512         };
513         return params;
514 }
515 CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_prepare, MicrofacetMultiGGXClosure);
516
517 class MicrofacetMultiGGXAnisoClosure : public MicrofacetMultiClosure {
518 public:
519         void setup(ShaderData *sd, int path_flag, float3 weight)
520         {
521                 MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
522                 if(!bsdf) {
523                         return;
524                 }
525
526                 bsdf->ior = 0.0f;
527                 sd->flag |= bsdf_microfacet_multi_ggx_aniso_setup(bsdf);
528         }
529 };
530
531 ClosureParam *closure_bsdf_microfacet_multi_ggx_aniso_params()
532 {
533         static ClosureParam params[] = {
534                 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, params.N),
535                 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, params.T),
536                 CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_x),
537                 CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_y),
538                 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, color),
539                 CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXClosure, label, "label"),
540                 CLOSURE_FINISH_PARAM(MicrofacetMultiGGXClosure)
541         };
542         return params;
543 }
544 CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_aniso_prepare, MicrofacetMultiGGXAnisoClosure);
545
546 class MicrofacetMultiGGXGlassClosure : public MicrofacetMultiClosure {
547 public:
548         MicrofacetMultiGGXGlassClosure() : MicrofacetMultiClosure() {}
549
550         void setup(ShaderData *sd, int path_flag, float3 weight)
551         {
552                 MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
553                 if(!bsdf) {
554                         return;
555                 }
556
557                 bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
558                 bsdf->alpha_y = bsdf->alpha_x;
559                 sd->flag |= bsdf_microfacet_multi_ggx_glass_setup(bsdf);
560         }
561 };
562
563 ClosureParam *closure_bsdf_microfacet_multi_ggx_glass_params()
564 {
565         static ClosureParam params[] = {
566                 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, params.N),
567                 CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.alpha_x),
568                 CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXClosure, params.ior),
569                 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXClosure, color),
570                 CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXClosure, label, "label"),
571                 CLOSURE_FINISH_PARAM(MicrofacetMultiGGXClosure)
572         };
573         return params;
574 }
575 CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_glass_prepare, MicrofacetMultiGGXGlassClosure);
576
577
578 /* Multiscattering GGX closures with Fresnel */
579
580 class MicrofacetMultiFresnelClosure : public CBSDFClosure {
581 public:
582         MicrofacetBsdf params;
583         float3 color;
584         float3 cspec0;
585
586         MicrofacetBsdf *alloc(ShaderData *sd, int path_flag, float3 weight)
587         {
588                 /* Technically, the MultiGGX closure may also transmit. However,
589                 * since this is set statically and only used for caustic flags, this
590                 * is probably as good as it gets. */
591                 if(skip(sd, path_flag, LABEL_GLOSSY | LABEL_REFLECT)) {
592                         return NULL;
593                 }
594
595                 MicrofacetBsdf *bsdf = (MicrofacetBsdf*)bsdf_alloc_osl(sd, sizeof(MicrofacetBsdf), weight, &params);
596                 if(!bsdf) {
597                         return NULL;
598                 }
599
600                 MicrofacetExtra *extra = (MicrofacetExtra*)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
601                 if(!extra) {
602                         return NULL;
603                 }
604
605                 bsdf->extra = extra;
606                 bsdf->extra->color = color;
607                 bsdf->extra->cspec0 = cspec0;
608                 bsdf->extra->clearcoat = 0.0f;
609                 return bsdf;
610         }
611 };
612
613 class MicrofacetMultiGGXFresnelClosure : public MicrofacetMultiFresnelClosure {
614 public:
615         void setup(ShaderData *sd, int path_flag, float3 weight)
616         {
617                 MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
618                 if(!bsdf) {
619                         return;
620                 }
621
622                 bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
623                 bsdf->alpha_y = bsdf->alpha_x;
624                 sd->flag |= bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd);
625         }
626 };
627
628 ClosureParam *closure_bsdf_microfacet_multi_ggx_fresnel_params()
629 {
630         static ClosureParam params[] = {
631                 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, params.N),
632                 CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_x),
633                 CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.ior),
634                 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, color),
635                 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, cspec0),
636                 CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXFresnelClosure, label, "label"),
637                 CLOSURE_FINISH_PARAM(MicrofacetMultiGGXFresnelClosure)
638         };
639         return params;
640 }
641 CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_fresnel_prepare, MicrofacetMultiGGXFresnelClosure);
642
643 class MicrofacetMultiGGXAnisoFresnelClosure : public MicrofacetMultiFresnelClosure {
644 public:
645         void setup(ShaderData *sd, int path_flag, float3 weight)
646         {
647                 MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
648                 if(!bsdf) {
649                         return;
650                 }
651
652                 sd->flag |= bsdf_microfacet_multi_ggx_aniso_fresnel_setup(bsdf, sd);
653         }
654 };
655
656 ClosureParam *closure_bsdf_microfacet_multi_ggx_aniso_fresnel_params()
657 {
658         static ClosureParam params[] = {
659                 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, params.N),
660                 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, params.T),
661                 CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_x),
662                 CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_y),
663                 CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.ior),
664                 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, color),
665                 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, cspec0),
666                 CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXFresnelClosure, label, "label"),
667                 CLOSURE_FINISH_PARAM(MicrofacetMultiGGXFresnelClosure)
668         };
669         return params;
670 }
671 CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_aniso_fresnel_prepare, MicrofacetMultiGGXAnisoFresnelClosure);
672
673 class MicrofacetMultiGGXGlassFresnelClosure : public MicrofacetMultiFresnelClosure {
674 public:
675         MicrofacetMultiGGXGlassFresnelClosure() : MicrofacetMultiFresnelClosure() {}
676
677         void setup(ShaderData *sd, int path_flag, float3 weight)
678         {
679                 MicrofacetBsdf *bsdf = alloc(sd, path_flag, weight);
680                 if(!bsdf) {
681                         return;
682                 }
683
684                 bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
685                 bsdf->alpha_y = bsdf->alpha_x;
686                 sd->flag |= bsdf_microfacet_multi_ggx_glass_fresnel_setup(bsdf, sd);
687         }
688 };
689
690 ClosureParam *closure_bsdf_microfacet_multi_ggx_glass_fresnel_params()
691 {
692         static ClosureParam params[] = {
693                 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, params.N),
694                 CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.alpha_x),
695                 CLOSURE_FLOAT_PARAM(MicrofacetMultiGGXFresnelClosure, params.ior),
696                 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, color),
697                 CLOSURE_FLOAT3_PARAM(MicrofacetMultiGGXFresnelClosure, cspec0),
698                 CLOSURE_STRING_KEYPARAM(MicrofacetMultiGGXFresnelClosure, label, "label"),
699                 CLOSURE_FINISH_PARAM(MicrofacetMultiGGXFresnelClosure)
700         };
701         return params;
702 }
703 CCLOSURE_PREPARE(closure_bsdf_microfacet_multi_ggx_glass_fresnel_prepare, MicrofacetMultiGGXGlassFresnelClosure);
704
705 /* Transparent */
706
707 class TransparentClosure : public CBSDFClosure {
708 public:
709         ShaderClosure params;
710         float3 unused;
711
712         void setup(ShaderData *sd, int path_flag, float3 weight)
713         {
714                 bsdf_transparent_setup(sd, weight);
715         }
716 };
717
718 ClosureParam *closure_bsdf_transparent_params()
719 {
720         static ClosureParam params[] = {
721                 CLOSURE_STRING_KEYPARAM(TransparentClosure, label, "label"),
722                 CLOSURE_FINISH_PARAM(TransparentClosure)
723         };
724         return params;
725 }
726
727 CCLOSURE_PREPARE(closure_bsdf_transparent_prepare, TransparentClosure)
728
729 /* Volume */
730
731 class VolumeAbsorptionClosure : public CBSDFClosure {
732 public:
733         void setup(ShaderData *sd, int path_flag, float3 weight)
734         {
735                 volume_extinction_setup(sd, weight);
736         }
737 };
738
739 ClosureParam *closure_absorption_params()
740 {
741         static ClosureParam params[] = {
742                 CLOSURE_STRING_KEYPARAM(VolumeAbsorptionClosure, label, "label"),
743                 CLOSURE_FINISH_PARAM(VolumeAbsorptionClosure)
744         };
745         return params;
746 }
747
748 CCLOSURE_PREPARE(closure_absorption_prepare, VolumeAbsorptionClosure)
749
750 class VolumeHenyeyGreensteinClosure : public CBSDFClosure {
751 public:
752         HenyeyGreensteinVolume params;
753
754         void setup(ShaderData *sd, int path_flag, float3 weight)
755         {
756                 volume_extinction_setup(sd, weight);
757
758             HenyeyGreensteinVolume *volume = (HenyeyGreensteinVolume*)bsdf_alloc_osl(sd, sizeof(HenyeyGreensteinVolume), weight, &params);
759                 if(!volume) {
760                         return;
761                 }
762
763                 sd->flag |= volume_henyey_greenstein_setup(volume);
764         }
765 };
766
767 ClosureParam *closure_henyey_greenstein_params()
768 {
769         static ClosureParam params[] = {
770                 CLOSURE_FLOAT_PARAM(VolumeHenyeyGreensteinClosure, params.g),
771                 CLOSURE_STRING_KEYPARAM(VolumeHenyeyGreensteinClosure, label, "label"),
772                 CLOSURE_FINISH_PARAM(VolumeHenyeyGreensteinClosure)
773         };
774         return params;
775 }
776
777 CCLOSURE_PREPARE(closure_henyey_greenstein_prepare, VolumeHenyeyGreensteinClosure)
778
779
780 CCL_NAMESPACE_END
781