Enable compilation of the SVM backend for Cycles even when OSL is enabled. The switch...
[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 #endif
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
42 CCL_NAMESPACE_BEGIN
43
44 /* ShaderData setup from incoming ray */
45
46 __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
47         const Intersection *isect, const Ray *ray)
48 {
49         /* fetch triangle data */
50         int prim = kernel_tex_fetch(__prim_index, isect->prim);
51         float4 Ns = kernel_tex_fetch(__tri_normal, prim);
52         float3 Ng = make_float3(Ns.x, Ns.y, Ns.z);
53         int shader = __float_as_int(Ns.w);
54
55         /* triangle */
56 #ifdef __INSTANCING__
57         sd->object = (isect->object == ~0)? kernel_tex_fetch(__prim_object, isect->prim): isect->object;
58 #endif
59         sd->prim = prim;
60 #ifdef __UV__
61         sd->u = isect->u;
62         sd->v = isect->v;
63 #endif
64
65         /* matrices and time */
66 #ifdef __MOTION__
67         sd->ob_tfm = object_fetch_transform(kg, sd->object, ray->time, OBJECT_TRANSFORM);
68         sd->ob_itfm = object_fetch_transform(kg, sd->object, ray->time, OBJECT_INVERSE_TRANSFORM);
69
70         sd->time = ray->time;
71 #endif
72
73         /* vectors */
74         sd->P = bvh_triangle_refine(kg, sd, isect, ray);
75         sd->Ng = Ng;
76         sd->N = Ng;
77         sd->I = -ray->D;
78         sd->shader = shader;
79         sd->ray_length = isect->t;
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 t, 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         sd->ray_length = t;
149
150         /* detect instancing, for non-instanced the object index is -object-1 */
151 #ifdef __INSTANCING__
152         bool instanced = false;
153
154         if(sd->prim != ~0) {
155                 if(sd->object >= 0)
156                         instanced = true;
157                 else
158 #endif
159                         sd->object = ~sd->object;
160 #ifdef __INSTANCING__
161         }
162 #endif
163
164 #ifdef __MOTION__
165         sd->time = time;
166
167         sd->ob_tfm = object_fetch_transform(kg, sd->object, time, OBJECT_TRANSFORM);
168         sd->ob_itfm = object_fetch_transform(kg, sd->object, time, OBJECT_INVERSE_TRANSFORM);
169 #endif
170
171         /* smooth normal */
172         if(sd->shader & SHADER_SMOOTH_NORMAL) {
173                 sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
174
175 #ifdef __INSTANCING__
176                 if(instanced)
177                         object_normal_transform(kg, sd, &sd->N);
178 #endif
179         }
180
181         sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
182         if(sd->object != -1)
183                 sd->flag |= kernel_tex_fetch(__object_flag, sd->object);
184
185 #ifdef __DPDU__
186         /* dPdu/dPdv */
187         if(sd->prim == ~0) {
188                 sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
189                 sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
190         }
191         else {
192                 triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim);
193
194 #ifdef __INSTANCING__
195                 if(instanced) {
196                         object_dir_transform(kg, sd, &sd->dPdu);
197                         object_dir_transform(kg, sd, &sd->dPdv);
198                 }
199 #endif
200         }
201 #endif
202
203         /* backfacing test */
204         if(sd->prim != ~0) {
205                 bool backfacing = (dot(sd->Ng, sd->I) < 0.0f);
206
207                 if(backfacing) {
208                         sd->flag |= SD_BACKFACING;
209                         sd->Ng = -sd->Ng;
210                         sd->N = -sd->N;
211 #ifdef __DPDU__
212                         sd->dPdu = -sd->dPdu;
213                         sd->dPdv = -sd->dPdv;
214 #endif
215                 }
216         }
217
218 #ifdef __RAY_DIFFERENTIALS__
219         /* no ray differentials here yet */
220         sd->dP.dx = make_float3(0.0f, 0.0f, 0.0f);
221         sd->dP.dy = make_float3(0.0f, 0.0f, 0.0f);
222         sd->dI.dx = make_float3(0.0f, 0.0f, 0.0f);
223         sd->dI.dy = make_float3(0.0f, 0.0f, 0.0f);
224         sd->du.dx = 0.0f;
225         sd->du.dy = 0.0f;
226         sd->dv.dx = 0.0f;
227         sd->dv.dy = 0.0f;
228 #endif
229 }
230
231 /* ShaderData setup for displacement */
232
233 __device void shader_setup_from_displace(KernelGlobals *kg, ShaderData *sd,
234         int object, int prim, float u, float v)
235 {
236         float3 P, Ng, I = make_float3(0.0f, 0.0f, 0.0f);
237         int shader;
238
239         P = triangle_point_MT(kg, prim, u, v);
240         Ng = triangle_normal_MT(kg, prim, &shader);
241
242         /* force smooth shading for displacement */
243         shader |= SHADER_SMOOTH_NORMAL;
244
245         /* watch out: no instance transform currently */
246
247         shader_setup_from_sample(kg, sd, P, Ng, I, shader, object, prim, u, v, 0.0f, TIME_INVALID);
248 }
249
250 /* ShaderData setup from ray into background */
251
252 __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData *sd, const Ray *ray)
253 {
254         /* vectors */
255         sd->P = ray->D;
256         sd->N = -sd->P;
257         sd->Ng = -sd->P;
258         sd->I = -sd->P;
259         sd->shader = kernel_data.background.shader;
260         sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
261 #ifdef __MOTION__
262         sd->time = ray->time;
263 #endif
264         sd->ray_length = 0.0f;
265
266 #ifdef __INSTANCING__
267         sd->object = ~0;
268 #endif
269         sd->prim = ~0;
270 #ifdef __UV__
271         sd->u = 0.0f;
272         sd->v = 0.0f;
273 #endif
274
275 #ifdef __DPDU__
276         /* dPdu/dPdv */
277         sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
278         sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
279 #endif
280
281 #ifdef __RAY_DIFFERENTIALS__
282         /* differentials */
283         sd->dP = ray->dD;
284         differential_incoming(&sd->dI, sd->dP);
285         sd->du.dx = 0.0f;
286         sd->du.dy = 0.0f;
287         sd->dv.dx = 0.0f;
288         sd->dv.dy = 0.0f;
289 #endif
290 }
291
292 /* BSDF */
293
294 #ifdef __MULTI_CLOSURE__
295
296 #ifdef __OSL__
297 __device_inline void _shader_bsdf_multi_eval_osl(const ShaderData *sd, const float3 omega_in, float *pdf,
298         int skip_bsdf, BsdfEval *bsdf_eval, float sum_pdf, float sum_sample_weight)
299 {
300         for(int i = 0; i< sd->num_closure; i++) {
301                 if(i == skip_bsdf)
302                         continue;
303
304                 const ShaderClosure *sc = &sd->closure[i];
305
306                 if(CLOSURE_IS_BSDF(sc->type)) {
307                         float bsdf_pdf = 0.0f;
308
309                         float3 eval = OSLShader::bsdf_eval(sd, sc, omega_in, bsdf_pdf);
310
311                         if(bsdf_pdf != 0.0f) {
312                                 bsdf_eval_accum(bsdf_eval, sc->type, eval*sc->weight);
313                                 sum_pdf += bsdf_pdf*sc->sample_weight;
314                         }
315
316                         sum_sample_weight += sc->sample_weight;
317                 }
318         }
319
320         *pdf = (sum_sample_weight > 0.0f)? sum_pdf/sum_sample_weight: 0.0f;
321 }
322 #endif
323
324 __device_inline void _shader_bsdf_multi_eval_svm(const ShaderData *sd, const float3 omega_in, float *pdf,
325         int skip_bsdf, BsdfEval *bsdf_eval, float sum_pdf, float sum_sample_weight)
326 {
327         for(int i = 0; i< sd->num_closure; i++) {
328                 if(i == skip_bsdf)
329                         continue;
330
331                 const ShaderClosure *sc = &sd->closure[i];
332
333                 if(CLOSURE_IS_BSDF(sc->type)) {
334                         float bsdf_pdf = 0.0f;
335
336                         float3 eval = svm_bsdf_eval(sd, sc, omega_in, &bsdf_pdf);
337
338                         if(bsdf_pdf != 0.0f) {
339                                 bsdf_eval_accum(bsdf_eval, sc->type, eval*sc->weight);
340                                 sum_pdf += bsdf_pdf*sc->sample_weight;
341                         }
342
343                         sum_sample_weight += sc->sample_weight;
344                 }
345         }
346
347         *pdf = (sum_sample_weight > 0.0f)? sum_pdf/sum_sample_weight: 0.0f;
348 }
349
350 #endif
351
352 __device void shader_bsdf_eval(KernelGlobals *kg, const ShaderData *sd,
353         const float3 omega_in, BsdfEval *eval, float *pdf)
354 {
355 #ifdef __MULTI_CLOSURE__
356         bsdf_eval_init(eval, NBUILTIN_CLOSURES, make_float3(0.0f, 0.0f, 0.0f), kernel_data.film.use_light_pass);
357
358 #ifdef __OSL__
359         if (kernel_osl_use(kg))
360                 return _shader_bsdf_multi_eval_osl(sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
361         else
362 #endif
363                 return _shader_bsdf_multi_eval_svm(sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
364 #else
365         const ShaderClosure *sc = &sd->closure;
366
367         *pdf = 0.0f;
368         *eval = svm_bsdf_eval(sd, sc, omega_in, pdf)*sc->weight;
369 #endif
370 }
371
372 __device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd,
373         float randu, float randv, BsdfEval *bsdf_eval,
374         float3 *omega_in, differential3 *domega_in, float *pdf)
375 {
376 #ifdef __MULTI_CLOSURE__
377         int sampled = 0;
378
379         if(sd->num_closure > 1) {
380                 /* pick a BSDF closure based on sample weights */
381                 float sum = 0.0f;
382
383                 for(sampled = 0; sampled < sd->num_closure; sampled++) {
384                         const ShaderClosure *sc = &sd->closure[sampled];
385                         
386                         if(CLOSURE_IS_BSDF(sc->type))
387                                 sum += sc->sample_weight;
388                 }
389
390                 float r = sd->randb_closure*sum;
391                 sum = 0.0f;
392
393                 for(sampled = 0; sampled < sd->num_closure; sampled++) {
394                         const ShaderClosure *sc = &sd->closure[sampled];
395                         
396                         if(CLOSURE_IS_BSDF(sc->type)) {
397                                 sum += sd->closure[sampled].sample_weight;
398
399                                 if(r <= sum)
400                                         break;
401                         }
402                 }
403
404                 if(sampled == sd->num_closure) {
405                         *pdf = 0.0f;
406                         return LABEL_NONE;
407                 }
408         }
409
410         const ShaderClosure *sc = &sd->closure[sampled];
411         int label;
412         float3 eval;
413
414         *pdf = 0.0f;
415 #ifdef __OSL__
416         if (kernel_osl_use(kg))
417                 label = OSLShader::bsdf_sample(sd, sc, randu, randv, eval, *omega_in, *domega_in, *pdf);
418         else
419 #endif
420                 label = svm_bsdf_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
421
422         if(*pdf != 0.0f) {
423                 bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass);
424
425                 if(sd->num_closure > 1) {
426                         float sweight = sc->sample_weight;
427 #ifdef __OSL__
428                         if (kernel_osl_use(kg))
429                                 _shader_bsdf_multi_eval_osl(sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight);
430                         else
431 #endif
432                                 _shader_bsdf_multi_eval_svm(sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight);
433                 }
434         }
435
436         return label;
437 #else
438         /* sample the single closure that we picked */
439         *pdf = 0.0f;
440         int label = svm_bsdf_sample(sd, &sd->closure, randu, randv, bsdf_eval, omega_in, domega_in, pdf);
441         *bsdf_eval *= sd->closure.weight;
442         return label;
443 #endif
444 }
445
446 __device int shader_bsdf_sample_closure(KernelGlobals *kg, const ShaderData *sd,
447         const ShaderClosure *sc, float randu, float randv, BsdfEval *bsdf_eval,
448         float3 *omega_in, differential3 *domega_in, float *pdf)
449 {
450         int label;
451         float3 eval;
452
453         *pdf = 0.0f;
454 #ifdef __OSL__
455         if (kernel_osl_use(kg))
456                 label = OSLShader::bsdf_sample(sd, sc, randu, randv, eval, *omega_in, *domega_in, *pdf);
457         else
458 #endif
459                 label = svm_bsdf_sample(sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
460
461         if(*pdf != 0.0f)
462                 bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass);
463
464         return label;
465 }
466
467 __device void shader_bsdf_blur(KernelGlobals *kg, ShaderData *sd, float roughness)
468 {
469 #ifndef __OSL__
470 #ifdef __MULTI_CLOSURE__
471         for(int i = 0; i< sd->num_closure; i++) {
472                 ShaderClosure *sc = &sd->closure[i];
473
474                 if(CLOSURE_IS_BSDF(sc->type))
475                         svm_bsdf_blur(sc, roughness);
476         }
477 #else
478         svm_bsdf_blur(&sd->closure, roughness);
479 #endif
480 #endif
481 }
482
483 __device float3 shader_bsdf_transparency(KernelGlobals *kg, ShaderData *sd)
484 {
485 #ifdef __MULTI_CLOSURE__
486         float3 eval = make_float3(0.0f, 0.0f, 0.0f);
487
488         for(int i = 0; i< sd->num_closure; i++) {
489                 ShaderClosure *sc = &sd->closure[i];
490
491                 if(sc->type == CLOSURE_BSDF_TRANSPARENT_ID) // todo: make this work for osl
492                         eval += sc->weight;
493         }
494
495         return eval;
496 #else
497         if(sd->closure.type == CLOSURE_BSDF_TRANSPARENT_ID)
498                 return sd->closure.weight;
499         else
500                 return make_float3(0.0f, 0.0f, 0.0f);
501 #endif
502 }
503
504 __device float3 shader_bsdf_diffuse(KernelGlobals *kg, ShaderData *sd)
505 {
506 #ifdef __MULTI_CLOSURE__
507         float3 eval = make_float3(0.0f, 0.0f, 0.0f);
508
509         for(int i = 0; i< sd->num_closure; i++) {
510                 ShaderClosure *sc = &sd->closure[i];
511
512                 if(CLOSURE_IS_BSDF_DIFFUSE(sc->type))
513                         eval += sc->weight;
514         }
515
516         return eval;
517 #else
518         if(CLOSURE_IS_BSDF_DIFFUSE(sd->closure.type))
519                 return sd->closure.weight;
520         else
521                 return make_float3(0.0f, 0.0f, 0.0f);
522 #endif
523 }
524
525 __device float3 shader_bsdf_glossy(KernelGlobals *kg, ShaderData *sd)
526 {
527 #ifdef __MULTI_CLOSURE__
528         float3 eval = make_float3(0.0f, 0.0f, 0.0f);
529
530         for(int i = 0; i< sd->num_closure; i++) {
531                 ShaderClosure *sc = &sd->closure[i];
532
533                 if(CLOSURE_IS_BSDF_GLOSSY(sc->type))
534                         eval += sc->weight;
535         }
536
537         return eval;
538 #else
539         if(CLOSURE_IS_BSDF_GLOSSY(sd->closure.type))
540                 return sd->closure.weight;
541         else
542                 return make_float3(0.0f, 0.0f, 0.0f);
543 #endif
544 }
545
546 __device float3 shader_bsdf_transmission(KernelGlobals *kg, ShaderData *sd)
547 {
548 #ifdef __MULTI_CLOSURE__
549         float3 eval = make_float3(0.0f, 0.0f, 0.0f);
550
551         for(int i = 0; i< sd->num_closure; i++) {
552                 ShaderClosure *sc = &sd->closure[i];
553
554                 if(CLOSURE_IS_BSDF_TRANSMISSION(sc->type))
555                         eval += sc->weight;
556         }
557
558         return eval;
559 #else
560         if(CLOSURE_IS_BSDF_TRANSMISSION(sd->closure.type))
561                 return sd->closure.weight;
562         else
563                 return make_float3(0.0f, 0.0f, 0.0f);
564 #endif
565 }
566
567 /* Emission */
568
569 __device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
570 {
571         float3 eval;
572 #ifdef __MULTI_CLOSURE__
573         eval = make_float3(0.0f, 0.0f, 0.0f);
574
575         for(int i = 0; i < sd->num_closure; i++) {
576                 ShaderClosure *sc = &sd->closure[i];
577
578                 if(CLOSURE_IS_EMISSION(sc->type)) {
579 #ifdef __OSL__
580                         if (kernel_osl_use(kg))
581                                 eval += OSLShader::emissive_eval(sd, sc)*sc->weight;
582                         else
583 #endif
584                                 eval += svm_emissive_eval(sd, sc)*sc->weight;
585
586                 }
587         }
588 #else
589         eval = svm_emissive_eval(sd, &sd->closure)*sd->closure.weight;
590 #endif
591
592         return eval;
593 }
594
595 /* Holdout */
596
597 __device float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd)
598 {
599 #ifdef __MULTI_CLOSURE__
600         float3 weight = make_float3(0.0f, 0.0f, 0.0f);
601
602         for(int i = 0; i < sd->num_closure; i++) {
603                 ShaderClosure *sc = &sd->closure[i];
604
605                 if(CLOSURE_IS_HOLDOUT(sc->type))
606                         weight += sc->weight;
607         }
608
609         return weight;
610 #else
611         if(sd->closure.type == CLOSURE_HOLDOUT_ID)
612                 return make_float3(1.0f, 1.0f, 1.0f);
613
614         return make_float3(0.0f, 0.0f, 0.0f);
615 #endif
616 }
617
618 /* Surface Evaluation */
619
620 __device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
621         float randb, int path_flag)
622 {
623 #ifdef __OSL__
624         if (kernel_osl_use(kg))
625                 OSLShader::eval_surface(kg, sd, randb, path_flag);
626         else
627 #endif
628         {
629 #ifdef __SVM__
630                 svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, randb, path_flag);
631 #else
632                 bsdf_diffuse_setup(sd, &sd->closure);
633                 sd->closure.weight = make_float3(0.8f, 0.8f, 0.8f);
634 #endif
635         }
636 }
637
638 /* Background Evaluation */
639
640 __device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag)
641 {
642 #ifdef __OSL__
643         if (kernel_osl_use(kg))
644                 return OSLShader::eval_background(kg, sd, path_flag);
645         else
646 #endif
647
648         {
649 #ifdef __SVM__
650                 svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, 0.0f, path_flag);
651
652 #ifdef __MULTI_CLOSURE__
653                 float3 eval = make_float3(0.0f, 0.0f, 0.0f);
654
655                 for(int i = 0; i< sd->num_closure; i++) {
656                         const ShaderClosure *sc = &sd->closure[i];
657
658                         if(CLOSURE_IS_BACKGROUND(sc->type))
659                                 eval += sc->weight;
660                 }
661
662                 return eval;
663 #else
664                 if(sd->closure.type == CLOSURE_BACKGROUND_ID)
665                         return sd->closure.weight;
666                 else
667                         return make_float3(0.0f, 0.0f, 0.0f);
668 #endif
669
670 #else
671                 return make_float3(0.8f, 0.8f, 0.8f);
672 #endif
673         }
674 }
675
676 /* Volume */
677
678 __device float3 shader_volume_eval_phase(KernelGlobals *kg, ShaderData *sd,
679         float3 omega_in, float3 omega_out)
680 {
681 #ifdef __MULTI_CLOSURE__
682         float3 eval = make_float3(0.0f, 0.0f, 0.0f);
683
684         for(int i = 0; i< sd->num_closure; i++) {
685                 const ShaderClosure *sc = &sd->closure[i];
686
687                 if(CLOSURE_IS_VOLUME(sc->type)) {
688 #ifdef __OSL__
689                         if (kernel_osl_use(kg))
690                                 eval += OSLShader::volume_eval_phase(sd, sc, omega_in, omega_out);
691                         else
692 #endif
693                                 eval += volume_eval_phase(sd, sc, omega_in, omega_out);
694                 }
695         }
696
697         return eval;
698 #else
699         return volume_eval_phase(sd, &sd->closure, omega_in, omega_out);
700 #endif
701 }
702
703 /* Volume Evaluation */
704
705 __device void shader_eval_volume(KernelGlobals *kg, ShaderData *sd,
706         float randb, int path_flag)
707 {
708 #ifdef __SVM__
709 #ifdef __OSL__
710         if (kernel_osl_use(kg))
711                 OSLShader::eval_volume(kg, sd, randb, path_flag);
712         else
713 #endif
714                 svm_eval_nodes(kg, sd, SHADER_TYPE_VOLUME, randb, path_flag);
715 #endif
716 }
717
718 /* Displacement Evaluation */
719
720 __device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd)
721 {
722         /* this will modify sd->P */
723 #ifdef __SVM__
724 #ifdef __OSL__
725         if (kernel_osl_use(kg))
726                 OSLShader::eval_displacement(kg, sd);
727         else
728 #endif
729                 svm_eval_nodes(kg, sd, SHADER_TYPE_DISPLACEMENT, 0.0f, 0);
730 #endif
731 }
732
733 /* Transparent Shadows */
734
735 #ifdef __TRANSPARENT_SHADOWS__
736 __device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect)
737 {
738         int prim = kernel_tex_fetch(__prim_index, isect->prim);
739         float4 Ns = kernel_tex_fetch(__tri_normal, prim);
740         int shader = __float_as_int(Ns.w);
741         int flag = kernel_tex_fetch(__shader_flag, (shader & SHADER_MASK)*2);
742
743         return (flag & SD_HAS_SURFACE_TRANSPARENT) != 0;
744 }
745 #endif
746
747 /* Merging */
748
749 #ifdef __NON_PROGRESSIVE__
750 __device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd)
751 {
752 #ifndef __OSL__
753         /* merge identical closures, better when we sample a single closure at a time */
754         for(int i = 0; i < sd->num_closure; i++) {
755                 ShaderClosure *sci = &sd->closure[i];
756
757                 for(int j = i + 1; j < sd->num_closure; j++) {
758                         ShaderClosure *scj = &sd->closure[j];
759
760                         if(sci->type == scj->type && sci->data0 == scj->data0 && sci->data1 == scj->data1) {
761                                 sci->weight += scj->weight;
762                                 sci->sample_weight += scj->sample_weight;
763
764                                 int size = sd->num_closure - (j+1);
765                                 if(size > 0)
766                                         memmove(scj, scj+1, size*sizeof(ShaderClosure));
767
768                                 sd->num_closure--;
769                         }
770                 }
771         }
772 #endif
773 }
774 #endif
775
776 /* Free ShaderData */
777
778 __device void shader_release(KernelGlobals *kg, ShaderData *sd)
779 {
780 #ifdef __OSL__
781         if (kernel_osl_use(kg))
782                 OSLShader::release(kg, sd);
783 #endif
784 }
785
786 CCL_NAMESPACE_END
787