e4edc480272eef831bc2fb0b9cea462651f0fe23
[blender.git] / intern / cycles / kernel / kernel_shader.h
1 /*
2  * Copyright 2011, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18
19 /*
20  * ShaderData, used in four steps:
21  *
22  * Setup from incoming ray, sampled position and background.
23  * Execute for surface, volume or displacement.
24  * Evaluate one or more closures.
25  * Release.
26  *
27  */
28
29 #ifdef __OSL__
30
31 #include "osl_shader.h"
32
33 #else
34
35 #include "svm/bsdf.h"
36 #include "svm/emissive.h"
37 #include "svm/volume.h"
38 #include "svm/svm_bsdf.h"
39 #include "svm/svm.h"
40
41 #endif
42
43 CCL_NAMESPACE_BEGIN
44
45 /* ShaderData setup from incoming ray */
46
47 __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
48         const Intersection *isect, const Ray *ray)
49 {
50         /* fetch triangle data */
51         int prim = kernel_tex_fetch(__prim_index, isect->prim);
52         float4 Ns = kernel_tex_fetch(__tri_normal, prim);
53         float3 Ng = make_float3(Ns.x, Ns.y, Ns.z);
54         int shader = __float_as_int(Ns.w);
55
56         /* triangle */
57 #ifdef __INSTANCING__
58         sd->object = (isect->object == ~0)? kernel_tex_fetch(__prim_object, isect->prim): isect->object;
59 #endif
60         sd->prim = prim;
61 #ifdef __UV__
62         sd->u = isect->u;
63         sd->v = isect->v;
64 #endif
65
66         /* matrices and time */
67 #ifdef __MOTION__
68         sd->ob_tfm = object_fetch_transform(kg, sd->object, ray->time, OBJECT_TRANSFORM);
69         sd->ob_itfm = object_fetch_transform(kg, sd->object, ray->time, OBJECT_INVERSE_TRANSFORM);
70
71         sd->time = ray->time;
72 #endif
73
74         /* vectors */
75         sd->P = bvh_triangle_refine(kg, sd, isect, ray);
76         sd->Ng = Ng;
77         sd->N = Ng;
78         sd->I = -ray->D;
79         sd->shader = shader;
80
81         /* smooth normal */
82         if(sd->shader & SHADER_SMOOTH_NORMAL)
83                 sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
84
85         sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
86         sd->flag |= kernel_tex_fetch(__object_flag, sd->object);
87
88 #ifdef __DPDU__
89         /* dPdu/dPdv */
90         triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim);
91 #endif
92
93 #ifdef __INSTANCING__
94         if(isect->object != ~0) {
95                 /* instance transform */
96                 object_normal_transform(kg, sd, &sd->N);
97                 object_normal_transform(kg, sd, &sd->Ng);
98 #ifdef __DPDU__
99                 object_dir_transform(kg, sd, &sd->dPdu);
100                 object_dir_transform(kg, sd, &sd->dPdv);
101 #endif
102         }
103 #endif
104
105         /* backfacing test */
106         bool backfacing = (dot(sd->Ng, sd->I) < 0.0f);
107
108         if(backfacing) {
109                 sd->flag |= SD_BACKFACING;
110                 sd->Ng = -sd->Ng;
111                 sd->N = -sd->N;
112 #ifdef __DPDU__
113                 sd->dPdu = -sd->dPdu;
114                 sd->dPdv = -sd->dPdv;
115 #endif
116         }
117
118 #ifdef __RAY_DIFFERENTIALS__
119         /* differentials */
120         differential_transfer(&sd->dP, ray->dP, ray->D, ray->dD, sd->Ng, isect->t);
121         differential_incoming(&sd->dI, ray->dD);
122         differential_dudv(&sd->du, &sd->dv, sd->dPdu, sd->dPdv, sd->dP, sd->Ng);
123 #endif
124 }
125
126 /* ShaderData setup from position sampled on mesh */
127
128 __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
129         const float3 P, const float3 Ng, const float3 I,
130         int shader, int object, int prim, float u, float v, float time)
131 {
132         /* vectors */
133         sd->P = P;
134         sd->N = Ng;
135         sd->Ng = Ng;
136         sd->I = I;
137         sd->shader = shader;
138
139         /* primitive */
140 #ifdef __INSTANCING__
141         sd->object = object;
142 #endif
143         sd->prim = prim;
144 #ifdef __UV__
145         sd->u = u;
146         sd->v = v;
147 #endif
148
149         /* detect instancing, for non-instanced the object index is -object-1 */
150 #ifdef __INSTANCING__
151         bool instanced = false;
152
153         if(sd->prim != ~0) {
154                 if(sd->object >= 0)
155                         instanced = true;
156                 else
157 #endif
158                         sd->object = ~sd->object;
159 #ifdef __INSTANCING__
160         }
161 #endif
162
163 #ifdef __MOTION__
164         sd->time = time;
165
166         sd->ob_tfm = object_fetch_transform(kg, sd->object, time, OBJECT_TRANSFORM);
167         sd->ob_itfm = object_fetch_transform(kg, sd->object, time, OBJECT_INVERSE_TRANSFORM);
168 #endif
169
170         /* smooth normal */
171         if(sd->shader & SHADER_SMOOTH_NORMAL) {
172                 sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
173
174 #ifdef __INSTANCING__
175                 if(instanced)
176                         object_normal_transform(kg, sd, &sd->N);
177 #endif
178         }
179
180         sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
181         sd->flag |= kernel_tex_fetch(__object_flag, sd->object);
182
183 #ifdef __DPDU__
184         /* dPdu/dPdv */
185         if(sd->prim == ~0) {
186                 sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
187                 sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
188         }
189         else {
190                 triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim);
191
192 #ifdef __INSTANCING__
193                 if(instanced) {
194                         object_dir_transform(kg, sd, &sd->dPdu);
195                         object_dir_transform(kg, sd, &sd->dPdv);
196                 }
197 #endif
198         }
199 #endif
200
201         /* backfacing test */
202         if(sd->prim != ~0) {
203                 bool backfacing = (dot(sd->Ng, sd->I) < 0.0f);
204
205                 if(backfacing) {
206                         sd->flag |= SD_BACKFACING;
207                         sd->Ng = -sd->Ng;
208                         sd->N = -sd->N;
209 #ifdef __DPDU__
210                         sd->dPdu = -sd->dPdu;
211                         sd->dPdv = -sd->dPdv;
212 #endif
213                 }
214         }
215
216 #ifdef __RAY_DIFFERENTIALS__
217         /* no ray differentials here yet */
218         sd->dP.dx = make_float3(0.0f, 0.0f, 0.0f);
219         sd->dP.dy = make_float3(0.0f, 0.0f, 0.0f);
220         sd->dI.dx = make_float3(0.0f, 0.0f, 0.0f);
221         sd->dI.dy = make_float3(0.0f, 0.0f, 0.0f);
222         sd->du.dx = 0.0f;
223         sd->du.dy = 0.0f;
224         sd->dv.dx = 0.0f;
225         sd->dv.dy = 0.0f;
226 #endif
227 }
228
229 /* ShaderData setup for displacement */
230
231 __device void shader_setup_from_displace(KernelGlobals *kg, ShaderData *sd,
232         int object, int prim, float u, float v)
233 {
234         float3 P, Ng, I = make_float3(0.0f, 0.0f, 0.0f);
235         int shader;
236
237         P = triangle_point_MT(kg, prim, u, v);
238         Ng = triangle_normal_MT(kg, prim, &shader);
239
240         /* force smooth shading for displacement */
241         shader |= SHADER_SMOOTH_NORMAL;
242
243         /* watch out: no instance transform currently */
244
245         shader_setup_from_sample(kg, sd, P, Ng, I, shader, object, prim, u, v, TIME_INVALID);
246 }
247
248 /* ShaderData setup from ray into background */
249
250 __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData *sd, const Ray *ray)
251 {
252         /* vectors */
253         sd->P = ray->D;
254         sd->N = -sd->P;
255         sd->Ng = -sd->P;
256         sd->I = -sd->P;
257         sd->shader = kernel_data.background.shader;
258         sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
259 #ifdef __MOTION__
260         sd->time = ray->time;
261 #endif
262
263 #ifdef __INSTANCING__
264         sd->object = ~0;
265 #endif
266         sd->prim = ~0;
267 #ifdef __UV__
268         sd->u = 0.0f;
269         sd->v = 0.0f;
270 #endif
271
272 #ifdef __DPDU__
273         /* dPdu/dPdv */
274         sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
275         sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
276 #endif
277
278 #ifdef __RAY_DIFFERENTIALS__
279         /* differentials */
280         sd->dP = ray->dD;
281         differential_incoming(&sd->dI, sd->dP);
282         sd->du.dx = 0.0f;
283         sd->du.dy = 0.0f;
284         sd->dv.dx = 0.0f;
285         sd->dv.dy = 0.0f;
286 #endif
287 }
288
289 /* BSDF */
290
291 #ifdef __MULTI_CLOSURE__
292
293 __device_inline void _shader_bsdf_multi_eval(const ShaderData *sd, const float3 omega_in, float *pdf,
294         int skip_bsdf, BsdfEval *bsdf_eval, float sum_pdf, float sum_sample_weight)
295 {
296         for(int i = 0; i< sd->num_closure; i++) {
297                 if(i == skip_bsdf)
298                         continue;
299
300                 const ShaderClosure *sc = &sd->closure[i];
301
302                 if(CLOSURE_IS_BSDF(sc->type)) {
303                         float bsdf_pdf = 0.0f;
304 #ifdef __OSL__
305                         float3 eval = OSLShader::bsdf_eval(sd, sc, omega_in, bsdf_pdf);
306 #else
307                         float3 eval = svm_bsdf_eval(sd, sc, omega_in, &bsdf_pdf);
308 #endif
309
310                         if(bsdf_pdf != 0.0f) {
311                                 bsdf_eval_accum(bsdf_eval, sc->type, eval*sc->weight);
312                                 sum_pdf += bsdf_pdf*sc->sample_weight;
313                         }
314
315                         sum_sample_weight += sc->sample_weight;
316                 }
317         }
318
319         *pdf = (sum_sample_weight > 0.0f)? sum_pdf/sum_sample_weight: 0.0f;
320 }
321
322 #endif
323
324 __device void shader_bsdf_eval(KernelGlobals *kg, const ShaderData *sd,
325         const float3 omega_in, BsdfEval *eval, float *pdf)
326 {
327 #ifdef __MULTI_CLOSURE__
328         bsdf_eval_init(eval, NBUILTIN_CLOSURES, make_float3(0.0f, 0.0f, 0.0f), kernel_data.film.use_light_pass);
329
330         return _shader_bsdf_multi_eval(sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
331 #else
332         const ShaderClosure *sc = &sd->closure;
333
334         *pdf = 0.0f;
335         *eval = svm_bsdf_eval(sd, sc, omega_in, pdf)*sc->weight;
336 #endif
337 }
338
339 __device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd,
340         float randu, float randv, BsdfEval *bsdf_eval,
341         float3 *omega_in, differential3 *domega_in, float *pdf)
342 {
343 #ifdef __MULTI_CLOSURE__
344         int sampled = 0;
345
346         if(sd->num_closure > 1) {
347                 /* pick a BSDF closure based on sample weights */
348                 float sum = 0.0f;
349
350                 for(sampled = 0; sampled < sd->num_closure; sampled++) {
351                         const ShaderClosure *sc = &sd->closure[sampled];
352                         
353                         if(CLOSURE_IS_BSDF(sc->type))
354                                 sum += sc->sample_weight;
355                 }
356
357                 float r = sd->randb_closure*sum;
358                 sum = 0.0f;
359
360                 for(sampled = 0; sampled < sd->num_closure; sampled++) {
361                         const ShaderClosure *sc = &sd->closure[sampled];
362                         
363                         if(CLOSURE_IS_BSDF(sc->type)) {
364                                 sum += sd->closure[sampled].sample_weight;
365
366                                 if(r <= sum)
367                                         break;
368                         }
369                 }
370
371                 if(sampled == sd->num_closure) {
372                         *pdf = 0.0f;
373                         return LABEL_NONE;
374                 }
375         }
376
377         const ShaderClosure *sc = &sd->closure[sampled];
378         int label;
379         float3 eval;
380
381         *pdf = 0.0f;
382 #ifdef __OSL__
383         label = OSLShader::bsdf_sample(sd, sc, randu, randv, eval, *omega_in, *domega_in, *pdf);
384 #else
385         label = svm_bsdf_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
386 #endif
387         if(*pdf != 0.0f) {
388                 bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass);
389
390                 if(sd->num_closure > 1) {
391                         float sweight = sc->sample_weight;
392                         _shader_bsdf_multi_eval(sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight);
393                 }
394         }
395
396         return label;
397 #else
398         /* sample the single closure that we picked */
399         *pdf = 0.0f;
400         int label = svm_bsdf_sample(sd, &sd->closure, randu, randv, bsdf_eval, omega_in, domega_in, pdf);
401         *bsdf_eval *= sd->closure.weight;
402         return label;
403 #endif
404 }
405
406 __device void shader_bsdf_blur(KernelGlobals *kg, ShaderData *sd, float roughness)
407 {
408 #ifndef __OSL__
409 #ifdef __MULTI_CLOSURE__
410         for(int i = 0; i< sd->num_closure; i++) {
411                 ShaderClosure *sc = &sd->closure[i];
412
413                 if(CLOSURE_IS_BSDF(sc->type))
414                         svm_bsdf_blur(sc, roughness);
415         }
416 #else
417         svm_bsdf_blur(&sd->closure, roughness);
418 #endif
419 #endif
420 }
421
422 __device float3 shader_bsdf_transparency(KernelGlobals *kg, ShaderData *sd)
423 {
424 #ifdef __MULTI_CLOSURE__
425         float3 eval = make_float3(0.0f, 0.0f, 0.0f);
426
427         for(int i = 0; i< sd->num_closure; i++) {
428                 ShaderClosure *sc = &sd->closure[i];
429
430                 if(sc->type == CLOSURE_BSDF_TRANSPARENT_ID) // todo: make this work for osl
431                         eval += sc->weight;
432         }
433
434         return eval;
435 #else
436         if(sd->closure.type == CLOSURE_BSDF_TRANSPARENT_ID)
437                 return sd->closure.weight;
438         else
439                 return make_float3(0.0f, 0.0f, 0.0f);
440 #endif
441 }
442
443 __device float3 shader_bsdf_diffuse(KernelGlobals *kg, ShaderData *sd)
444 {
445 #ifdef __MULTI_CLOSURE__
446         float3 eval = make_float3(0.0f, 0.0f, 0.0f);
447
448         for(int i = 0; i< sd->num_closure; i++) {
449                 ShaderClosure *sc = &sd->closure[i];
450
451                 if(CLOSURE_IS_BSDF_DIFFUSE(sc->type))
452                         eval += sc->weight;
453         }
454
455         return eval;
456 #else
457         if(CLOSURE_IS_BSDF_DIFFUSE(sd->closure.type))
458                 return sd->closure.weight;
459         else
460                 return make_float3(0.0f, 0.0f, 0.0f);
461 #endif
462 }
463
464 __device float3 shader_bsdf_glossy(KernelGlobals *kg, ShaderData *sd)
465 {
466 #ifdef __MULTI_CLOSURE__
467         float3 eval = make_float3(0.0f, 0.0f, 0.0f);
468
469         for(int i = 0; i< sd->num_closure; i++) {
470                 ShaderClosure *sc = &sd->closure[i];
471
472                 if(CLOSURE_IS_BSDF_GLOSSY(sc->type))
473                         eval += sc->weight;
474         }
475
476         return eval;
477 #else
478         if(CLOSURE_IS_BSDF_GLOSSY(sd->closure.type))
479                 return sd->closure.weight;
480         else
481                 return make_float3(0.0f, 0.0f, 0.0f);
482 #endif
483 }
484
485 __device float3 shader_bsdf_transmission(KernelGlobals *kg, ShaderData *sd)
486 {
487 #ifdef __MULTI_CLOSURE__
488         float3 eval = make_float3(0.0f, 0.0f, 0.0f);
489
490         for(int i = 0; i< sd->num_closure; i++) {
491                 ShaderClosure *sc = &sd->closure[i];
492
493                 if(CLOSURE_IS_BSDF_TRANSMISSION(sc->type))
494                         eval += sc->weight;
495         }
496
497         return eval;
498 #else
499         if(CLOSURE_IS_BSDF_TRANSMISSION(sd->closure.type))
500                 return sd->closure.weight;
501         else
502                 return make_float3(0.0f, 0.0f, 0.0f);
503 #endif
504 }
505
506 /* Emission */
507
508 __device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
509 {
510         float3 eval;
511 #ifdef __MULTI_CLOSURE__
512         eval = make_float3(0.0f, 0.0f, 0.0f);
513
514         for(int i = 0; i < sd->num_closure; i++) {
515                 ShaderClosure *sc = &sd->closure[i];
516
517                 if(CLOSURE_IS_EMISSION(sc->type)) {
518 #ifdef __OSL__
519                         eval += OSLShader::emissive_eval(sd)*sc->weight;
520 #else
521                         eval += svm_emissive_eval(sd, sc)*sc->weight;
522 #endif
523                 }
524         }
525 #else
526         eval = svm_emissive_eval(sd, &sd->closure)*sd->closure.weight;
527 #endif
528
529         return eval;
530 }
531
532 /* Holdout */
533
534 __device float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd)
535 {
536 #ifdef __MULTI_CLOSURE__
537         float3 weight = make_float3(0.0f, 0.0f, 0.0f);
538
539         for(int i = 0; i < sd->num_closure; i++) {
540                 ShaderClosure *sc = &sd->closure[i];
541
542                 if(CLOSURE_IS_HOLDOUT(sc->type))
543                         weight += sc->weight;
544         }
545
546         return weight;
547 #else
548         if(sd->closure.type == CLOSURE_HOLDOUT_ID)
549                 return make_float3(1.0f, 1.0f, 1.0f);
550
551         return make_float3(0.0f, 0.0f, 0.0f);
552 #endif
553 }
554
555 /* Surface Evaluation */
556
557 __device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
558         float randb, int path_flag)
559 {
560 #ifdef __OSL__
561         OSLShader::eval_surface(kg, sd, randb, path_flag);
562 #else
563
564 #ifdef __SVM__
565         svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, randb, path_flag);
566 #else
567         bsdf_diffuse_setup(sd, &sd->closure);
568         sd->closure.weight = make_float3(0.8f, 0.8f, 0.8f);
569 #endif
570
571 #endif
572 }
573
574 /* Background Evaluation */
575
576 __device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag)
577 {
578 #ifdef __OSL__
579         return OSLShader::eval_background(kg, sd, path_flag);
580 #else
581
582 #ifdef __SVM__
583         svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, 0.0f, path_flag);
584
585 #ifdef __MULTI_CLOSURE__
586         float3 eval = make_float3(0.0f, 0.0f, 0.0f);
587
588         for(int i = 0; i< sd->num_closure; i++) {
589                 const ShaderClosure *sc = &sd->closure[i];
590
591                 if(CLOSURE_IS_BACKGROUND(sc->type))
592                         eval += sc->weight;
593         }
594
595         return eval;
596 #else
597         if(sd->closure.type == CLOSURE_BACKGROUND_ID)
598                 return sd->closure.weight;
599         else
600                 return make_float3(0.0f, 0.0f, 0.0f);
601 #endif
602
603 #else
604         return make_float3(0.8f, 0.8f, 0.8f);
605 #endif
606
607 #endif
608 }
609
610 /* Volume */
611
612 __device float3 shader_volume_eval_phase(KernelGlobals *kg, ShaderData *sd,
613         float3 omega_in, float3 omega_out)
614 {
615 #ifdef __MULTI_CLOSURE__
616         float3 eval = make_float3(0.0f, 0.0f, 0.0f);
617
618         for(int i = 0; i< sd->num_closure; i++) {
619                 const ShaderClosure *sc = &sd->closure[i];
620
621                 if(CLOSURE_IS_VOLUME(sc->type)) {
622 #ifdef __OSL__
623                         eval += OSLShader::volume_eval_phase(sd, omega_in, omega_out);
624 #else
625                         eval += volume_eval_phase(sd, sc, omega_in, omega_out);
626 #endif
627                 }
628         }
629
630         return eval;
631 #else
632         return volume_eval_phase(sd, &sd->closure, omega_in, omega_out);
633 #endif
634 }
635
636 /* Volume Evaluation */
637
638 __device void shader_eval_volume(KernelGlobals *kg, ShaderData *sd,
639         float randb, int path_flag)
640 {
641 #ifdef __SVM__
642 #ifdef __OSL__
643         OSLShader::eval_volume(kg, sd, randb, path_flag);
644 #else
645         svm_eval_nodes(kg, sd, SHADER_TYPE_VOLUME, randb, path_flag);
646 #endif
647 #endif
648 }
649
650 /* Displacement Evaluation */
651
652 __device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd)
653 {
654         /* this will modify sd->P */
655 #ifdef __SVM__
656 #ifdef __OSL__
657         OSLShader::eval_displacement(kg, sd);
658 #else
659         svm_eval_nodes(kg, sd, SHADER_TYPE_DISPLACEMENT, 0.0f, 0);
660 #endif
661 #endif
662 }
663
664 /* Transparent Shadows */
665
666 #ifdef __TRANSPARENT_SHADOWS__
667 __device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect)
668 {
669         int prim = kernel_tex_fetch(__prim_index, isect->prim);
670         float4 Ns = kernel_tex_fetch(__tri_normal, prim);
671         int shader = __float_as_int(Ns.w);
672         int flag = kernel_tex_fetch(__shader_flag, (shader & SHADER_MASK)*2);
673
674         return (flag & SD_HAS_SURFACE_TRANSPARENT) != 0;
675 }
676 #endif
677
678 __device int shader_pass_id(KernelGlobals *kg, ShaderData *sd)
679 {
680         return kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2 + 1);
681 }
682
683 /* Free ShaderData */
684
685 __device void shader_release(KernelGlobals *kg, ShaderData *sd)
686 {
687 #ifdef __OSL__
688         OSLShader::release(kg, sd);
689 #endif
690 }
691
692 CCL_NAMESPACE_END
693