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