Code cleanup: libmv C API
[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 #if defined(__KERNEL_CUDA_VERSION__) && __KERNEL_CUDA_VERSION__ <= 42
42 __device_noinline
43 #else
44 __device
45 #endif
46 void shader_setup_object_transforms(KernelGlobals *kg, ShaderData *sd, float time)
47 {
48         /* note that this is a separate non-inlined function to work around crash
49          * on CUDA sm 2.0, otherwise kernel execution crashes (compiler bug?) */
50         if(sd->flag & SD_OBJECT_MOTION) {
51                 sd->ob_tfm = object_fetch_transform_motion(kg, sd->object, time);
52                 sd->ob_itfm= transform_quick_inverse(sd->ob_tfm);
53         }
54         else {
55                 sd->ob_tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
56                 sd->ob_itfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
57         }
58 }
59 #endif
60
61 #if defined(__KERNEL_CUDA_VERSION__) && __KERNEL_CUDA_VERSION__ <= 42
62 __device_noinline
63 #else
64 __device
65 #endif
66 void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
67         const Intersection *isect, const Ray *ray)
68 {
69 #ifdef __INSTANCING__
70         sd->object = (isect->object == ~0)? kernel_tex_fetch(__prim_object, isect->prim): isect->object;
71 #endif
72
73         sd->flag = kernel_tex_fetch(__object_flag, sd->object);
74
75         /* matrices and time */
76 #ifdef __OBJECT_MOTION__
77         shader_setup_object_transforms(kg, sd, ray->time);
78         sd->time = ray->time;
79 #endif
80
81         sd->prim = kernel_tex_fetch(__prim_index, isect->prim);
82         sd->ray_length = isect->t;
83
84 #ifdef __HAIR__
85         if(kernel_tex_fetch(__prim_segment, isect->prim) != ~0) {
86                 /* Strand Shader setting*/
87                 float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
88
89                 sd->shader = __float_as_int(curvedata.z);
90                 sd->segment = isect->segment;
91
92                 float tcorr = isect->t;
93                 if(kernel_data.curve_kernel_data.curveflags & CURVE_KN_POSTINTERSECTCORRECTION) {
94                         tcorr = (isect->u < 0)? tcorr + sqrtf(isect->v) : tcorr - sqrtf(isect->v);
95                         sd->ray_length = tcorr;
96                 }
97
98                 sd->P = bvh_curve_refine(kg, sd, isect, ray, tcorr);
99         }
100         else {
101 #endif
102                 /* fetch triangle data */
103                 float4 Ns = kernel_tex_fetch(__tri_normal, sd->prim);
104                 float3 Ng = make_float3(Ns.x, Ns.y, Ns.z);
105                 sd->shader = __float_as_int(Ns.w);
106
107 #ifdef __HAIR__
108                 sd->segment = ~0;
109                 /*elements for minimum hair width using transparency bsdf*/
110                 /*sd->curve_transparency = 0.0f;*/
111                 /*sd->curve_radius = 0.0f;*/
112 #endif
113
114 #ifdef __UV__
115                 sd->u = isect->u;
116                 sd->v = isect->v;
117 #endif
118
119                 /* vectors */
120                 sd->P = bvh_triangle_refine(kg, sd, isect, ray);
121                 sd->Ng = Ng;
122                 sd->N = Ng;
123                 
124                 /* smooth normal */
125                 if(sd->shader & SHADER_SMOOTH_NORMAL)
126                         sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
127
128 #ifdef __DPDU__
129                 /* dPdu/dPdv */
130                 triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim);
131 #endif
132
133 #ifdef __HAIR__
134         }
135 #endif
136
137         sd->I = -ray->D;
138
139         sd->flag |= kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
140
141 #ifdef __INSTANCING__
142         if(isect->object != ~0) {
143                 /* instance transform */
144                 object_normal_transform(kg, sd, &sd->N);
145                 object_normal_transform(kg, sd, &sd->Ng);
146 #ifdef __DPDU__
147                 object_dir_transform(kg, sd, &sd->dPdu);
148                 object_dir_transform(kg, sd, &sd->dPdv);
149 #endif
150         }
151 #endif
152
153         /* backfacing test */
154         bool backfacing = (dot(sd->Ng, sd->I) < 0.0f);
155
156         if(backfacing) {
157                 sd->flag |= SD_BACKFACING;
158                 sd->Ng = -sd->Ng;
159                 sd->N = -sd->N;
160 #ifdef __DPDU__
161                 sd->dPdu = -sd->dPdu;
162                 sd->dPdv = -sd->dPdv;
163 #endif
164         }
165
166 #ifdef __RAY_DIFFERENTIALS__
167         /* differentials */
168         differential_transfer(&sd->dP, ray->dP, ray->D, ray->dD, sd->Ng, isect->t);
169         differential_incoming(&sd->dI, ray->dD);
170         differential_dudv(&sd->du, &sd->dv, sd->dPdu, sd->dPdv, sd->dP, sd->Ng);
171 #endif
172 }
173
174 /* ShaderData setup from BSSRDF scatter */
175
176 #ifdef __SUBSURFACE__
177 __device_inline void shader_setup_from_subsurface(KernelGlobals *kg, ShaderData *sd,
178         const Intersection *isect, const Ray *ray)
179 {
180         bool backfacing = sd->flag & SD_BACKFACING;
181
182         /* object, matrices, time, ray_length stay the same */
183         sd->flag = kernel_tex_fetch(__object_flag, sd->object);
184         sd->prim = kernel_tex_fetch(__prim_index, isect->prim);
185
186 #ifdef __HAIR__
187         if(kernel_tex_fetch(__prim_segment, isect->prim) != ~0) {
188                 /* Strand Shader setting*/
189                 float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
190
191                 sd->shader = __float_as_int(curvedata.z);
192                 sd->segment = isect->segment;
193
194                 float tcorr = isect->t;
195                 if(kernel_data.curve_kernel_data.curveflags & CURVE_KN_POSTINTERSECTCORRECTION)
196                         tcorr = (isect->u < 0)? tcorr + sqrtf(isect->v) : tcorr - sqrtf(isect->v);
197
198                 sd->P = bvh_curve_refine(kg, sd, isect, ray, tcorr);
199         }
200         else {
201 #endif
202                 /* fetch triangle data */
203                 float4 Ns = kernel_tex_fetch(__tri_normal, sd->prim);
204                 float3 Ng = make_float3(Ns.x, Ns.y, Ns.z);
205                 sd->shader = __float_as_int(Ns.w);
206
207 #ifdef __HAIR__
208                 sd->segment = ~0;
209 #endif
210
211 #ifdef __UV__
212                 sd->u = isect->u;
213                 sd->v = isect->v;
214 #endif
215
216                 /* vectors */
217                 sd->P = bvh_triangle_refine(kg, sd, isect, ray);
218                 sd->Ng = Ng;
219                 sd->N = Ng;
220                 
221                 /* smooth normal */
222                 if(sd->shader & SHADER_SMOOTH_NORMAL)
223                         sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
224
225 #ifdef __DPDU__
226                 /* dPdu/dPdv */
227                 triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim);
228 #endif
229
230 #ifdef __HAIR__
231         }
232 #endif
233
234         sd->flag |= kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
235
236 #ifdef __INSTANCING__
237         if(isect->object != ~0) {
238                 /* instance transform */
239                 object_normal_transform(kg, sd, &sd->N);
240                 object_normal_transform(kg, sd, &sd->Ng);
241 #ifdef __DPDU__
242                 object_dir_transform(kg, sd, &sd->dPdu);
243                 object_dir_transform(kg, sd, &sd->dPdv);
244 #endif
245         }
246 #endif
247
248         /* backfacing test */
249         if(backfacing) {
250                 sd->flag |= SD_BACKFACING;
251                 sd->Ng = -sd->Ng;
252                 sd->N = -sd->N;
253 #ifdef __DPDU__
254                 sd->dPdu = -sd->dPdu;
255                 sd->dPdv = -sd->dPdv;
256 #endif
257         }
258
259         /* should not get used in principle as the shading will only use a diffuse
260          * BSDF, but the shader might still access it */
261         sd->I = sd->N;
262
263 #ifdef __RAY_DIFFERENTIALS__
264         /* differentials */
265         differential_dudv(&sd->du, &sd->dv, sd->dPdu, sd->dPdv, sd->dP, sd->Ng);
266         /* don't modify dP and dI */
267 #endif
268 }
269 #endif
270
271 /* ShaderData setup from position sampled on mesh */
272
273 #if defined(__KERNEL_CUDA_VERSION__) && __KERNEL_CUDA_VERSION__ <= 42
274 __device_noinline
275 #else
276 __device
277 #endif
278 void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
279         const float3 P, const float3 Ng, const float3 I,
280         int shader, int object, int prim, float u, float v, float t, float time, int segment)
281 {
282         /* vectors */
283         sd->P = P;
284         sd->N = Ng;
285         sd->Ng = Ng;
286         sd->I = I;
287         sd->shader = shader;
288 #ifdef __HAIR__
289         sd->segment = segment;
290 #endif
291
292         /* primitive */
293 #ifdef __INSTANCING__
294         sd->object = object;
295 #endif
296         /* currently no access to bvh prim index for strand sd->prim - this will cause errors with needs fixing*/
297         sd->prim = prim;
298 #ifdef __UV__
299         sd->u = u;
300         sd->v = v;
301 #endif
302         sd->ray_length = t;
303
304         /* detect instancing, for non-instanced the object index is -object-1 */
305 #ifdef __INSTANCING__
306         bool instanced = false;
307
308         if(sd->prim != ~0) {
309                 if(sd->object >= 0)
310                         instanced = true;
311                 else
312 #endif
313                         sd->object = ~sd->object;
314 #ifdef __INSTANCING__
315         }
316 #endif
317
318         sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
319         if(sd->object != -1) {
320                 sd->flag |= kernel_tex_fetch(__object_flag, sd->object);
321
322 #ifdef __OBJECT_MOTION__
323                 shader_setup_object_transforms(kg, sd, time);
324         }
325
326         sd->time = time;
327 #else
328         }
329 #endif
330
331         /* smooth normal */
332 #ifdef __HAIR__
333         if(sd->shader & SHADER_SMOOTH_NORMAL && sd->segment == ~0) {
334                 sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
335 #else
336         if(sd->shader & SHADER_SMOOTH_NORMAL) {
337                 sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
338 #endif
339
340 #ifdef __INSTANCING__
341                 if(instanced)
342                         object_normal_transform(kg, sd, &sd->N);
343 #endif
344         }
345
346 #ifdef __DPDU__
347         /* dPdu/dPdv */
348 #ifdef __HAIR__
349         if(sd->prim == ~0 || sd->segment != ~0) {
350                 sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
351                 sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
352         }
353 #else
354         if(sd->prim == ~0) {
355                 sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
356                 sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
357         }
358 #endif
359         else {
360                 triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim);
361
362 #ifdef __INSTANCING__
363                 if(instanced) {
364                         object_dir_transform(kg, sd, &sd->dPdu);
365                         object_dir_transform(kg, sd, &sd->dPdv);
366                 }
367 #endif
368         }
369 #endif
370
371         /* backfacing test */
372         if(sd->prim != ~0) {
373                 bool backfacing = (dot(sd->Ng, sd->I) < 0.0f);
374
375                 if(backfacing) {
376                         sd->flag |= SD_BACKFACING;
377                         sd->Ng = -sd->Ng;
378                         sd->N = -sd->N;
379 #ifdef __DPDU__
380                         sd->dPdu = -sd->dPdu;
381                         sd->dPdv = -sd->dPdv;
382 #endif
383                 }
384         }
385
386 #ifdef __RAY_DIFFERENTIALS__
387         /* no ray differentials here yet */
388         sd->dP = differential3_zero();
389         sd->dI = differential3_zero();
390         sd->du = differential_zero();
391         sd->dv = differential_zero();
392 #endif
393 }
394
395 /* ShaderData setup for displacement */
396
397 __device void shader_setup_from_displace(KernelGlobals *kg, ShaderData *sd,
398         int object, int prim, float u, float v)
399 {
400         float3 P, Ng, I = make_float3(0.0f, 0.0f, 0.0f);
401         int shader;
402
403         P = triangle_point_MT(kg, prim, u, v);
404         Ng = triangle_normal_MT(kg, prim, &shader);
405
406         /* force smooth shading for displacement */
407         shader |= SHADER_SMOOTH_NORMAL;
408
409         /* watch out: no instance transform currently */
410
411         shader_setup_from_sample(kg, sd, P, Ng, I, shader, object, prim, u, v, 0.0f, TIME_INVALID, ~0);
412 }
413
414 /* ShaderData setup from ray into background */
415
416 __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData *sd, const Ray *ray)
417 {
418         /* vectors */
419         sd->P = ray->D;
420         sd->N = -ray->D;
421         sd->Ng = -ray->D;
422         sd->I = -ray->D;
423         sd->shader = kernel_data.background.shader;
424         sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
425 #ifdef __OBJECT_MOTION__
426         sd->time = ray->time;
427 #endif
428         sd->ray_length = 0.0f;
429
430 #ifdef __INSTANCING__
431         sd->object = ~0;
432 #endif
433         sd->prim = ~0;
434 #ifdef __HAIR__
435         sd->segment = ~0;
436 #endif
437 #ifdef __UV__
438         sd->u = 0.0f;
439         sd->v = 0.0f;
440 #endif
441
442 #ifdef __DPDU__
443         /* dPdu/dPdv */
444         sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
445         sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
446 #endif
447
448 #ifdef __RAY_DIFFERENTIALS__
449         /* differentials */
450         sd->dP = ray->dD;
451         differential_incoming(&sd->dI, sd->dP);
452         sd->du = differential_zero();
453         sd->dv = differential_zero();
454 #endif
455
456         /* for NDC coordinates */
457         sd->ray_P = ray->P;
458         sd->ray_dP = ray->dP;
459 }
460
461 /* BSDF */
462
463 #ifdef __MULTI_CLOSURE__
464
465 __device_inline void _shader_bsdf_multi_eval(KernelGlobals *kg, const ShaderData *sd, const float3 omega_in, float *pdf,
466         int skip_bsdf, BsdfEval *result_eval, float sum_pdf, float sum_sample_weight)
467 {
468         for(int i = 0; i< sd->num_closure; i++) {
469                 if(i == skip_bsdf)
470                         continue;
471
472                 const ShaderClosure *sc = &sd->closure[i];
473
474                 if(CLOSURE_IS_BSDF(sc->type)) {
475                         float bsdf_pdf = 0.0f;
476                         float3 eval = bsdf_eval(kg, sd, sc, omega_in, &bsdf_pdf);
477
478                         if(bsdf_pdf != 0.0f) {
479                                 bsdf_eval_accum(result_eval, sc->type, eval*sc->weight);
480                                 sum_pdf += bsdf_pdf*sc->sample_weight;
481                         }
482
483                         sum_sample_weight += sc->sample_weight;
484                 }
485         }
486
487         *pdf = (sum_sample_weight > 0.0f)? sum_pdf/sum_sample_weight: 0.0f;
488 }
489
490 #endif
491
492 __device void shader_bsdf_eval(KernelGlobals *kg, const ShaderData *sd,
493         const float3 omega_in, BsdfEval *eval, float *pdf)
494 {
495 #ifdef __MULTI_CLOSURE__
496         bsdf_eval_init(eval, NBUILTIN_CLOSURES, make_float3(0.0f, 0.0f, 0.0f), kernel_data.film.use_light_pass);
497
498         return _shader_bsdf_multi_eval(kg, sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
499 #else
500         const ShaderClosure *sc = &sd->closure;
501
502         *pdf = 0.0f;
503         *eval = bsdf_eval(kg, sd, sc, omega_in, pdf)*sc->weight;
504 #endif
505 }
506
507 __device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd,
508         float randu, float randv, BsdfEval *bsdf_eval,
509         float3 *omega_in, differential3 *domega_in, float *pdf)
510 {
511 #ifdef __MULTI_CLOSURE__
512         int sampled = 0;
513
514         if(sd->num_closure > 1) {
515                 /* pick a BSDF closure based on sample weights */
516                 float sum = 0.0f;
517
518                 for(sampled = 0; sampled < sd->num_closure; sampled++) {
519                         const ShaderClosure *sc = &sd->closure[sampled];
520                         
521                         if(CLOSURE_IS_BSDF(sc->type))
522                                 sum += sc->sample_weight;
523                 }
524
525                 float r = sd->randb_closure*sum;
526                 sum = 0.0f;
527
528                 for(sampled = 0; sampled < sd->num_closure; sampled++) {
529                         const ShaderClosure *sc = &sd->closure[sampled];
530                         
531                         if(CLOSURE_IS_BSDF(sc->type)) {
532                                 sum += sc->sample_weight;
533
534                                 if(r <= sum)
535                                         break;
536                         }
537                 }
538
539                 if(sampled == sd->num_closure) {
540                         *pdf = 0.0f;
541                         return LABEL_NONE;
542                 }
543         }
544
545         const ShaderClosure *sc = &sd->closure[sampled];
546         int label;
547         float3 eval;
548
549         *pdf = 0.0f;
550         label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
551
552         if(*pdf != 0.0f) {
553                 bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass);
554
555                 if(sd->num_closure > 1) {
556                         float sweight = sc->sample_weight;
557                         _shader_bsdf_multi_eval(kg, sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight);
558                 }
559         }
560
561         return label;
562 #else
563         /* sample the single closure that we picked */
564         *pdf = 0.0f;
565         int label = bsdf_sample(kg, sd, &sd->closure, randu, randv, bsdf_eval, omega_in, domega_in, pdf);
566         *bsdf_eval *= sd->closure.weight;
567         return label;
568 #endif
569 }
570
571 __device int shader_bsdf_sample_closure(KernelGlobals *kg, const ShaderData *sd,
572         const ShaderClosure *sc, float randu, float randv, BsdfEval *bsdf_eval,
573         float3 *omega_in, differential3 *domega_in, float *pdf)
574 {
575         int label;
576         float3 eval;
577
578         *pdf = 0.0f;
579         label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
580
581         if(*pdf != 0.0f)
582                 bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass);
583
584         return label;
585 }
586
587 __device void shader_bsdf_blur(KernelGlobals *kg, ShaderData *sd, float roughness)
588 {
589 #ifdef __MULTI_CLOSURE__
590         for(int i = 0; i< sd->num_closure; i++) {
591                 ShaderClosure *sc = &sd->closure[i];
592
593                 if(CLOSURE_IS_BSDF(sc->type))
594                         bsdf_blur(kg, sc, roughness);
595         }
596 #else
597         bsdf_blur(kg, &sd->closure, roughness);
598 #endif
599 }
600
601 __device float3 shader_bsdf_transparency(KernelGlobals *kg, ShaderData *sd)
602 {
603 #ifdef __MULTI_CLOSURE__
604         float3 eval = make_float3(0.0f, 0.0f, 0.0f);
605
606         for(int i = 0; i< sd->num_closure; i++) {
607                 ShaderClosure *sc = &sd->closure[i];
608
609                 if(sc->type == CLOSURE_BSDF_TRANSPARENT_ID) // todo: make this work for osl
610                         eval += sc->weight;
611         }
612
613         return eval;
614 #else
615         if(sd->closure.type == CLOSURE_BSDF_TRANSPARENT_ID)
616                 return sd->closure.weight;
617         else
618                 return make_float3(0.0f, 0.0f, 0.0f);
619 #endif
620 }
621
622 __device float3 shader_bsdf_diffuse(KernelGlobals *kg, ShaderData *sd)
623 {
624 #ifdef __MULTI_CLOSURE__
625         float3 eval = make_float3(0.0f, 0.0f, 0.0f);
626
627         for(int i = 0; i< sd->num_closure; i++) {
628                 ShaderClosure *sc = &sd->closure[i];
629
630                 if(CLOSURE_IS_BSDF_DIFFUSE(sc->type))
631                         eval += sc->weight;
632         }
633
634         return eval;
635 #else
636         if(CLOSURE_IS_BSDF_DIFFUSE(sd->closure.type))
637                 return sd->closure.weight;
638         else
639                 return make_float3(0.0f, 0.0f, 0.0f);
640 #endif
641 }
642
643 __device float3 shader_bsdf_glossy(KernelGlobals *kg, ShaderData *sd)
644 {
645 #ifdef __MULTI_CLOSURE__
646         float3 eval = make_float3(0.0f, 0.0f, 0.0f);
647
648         for(int i = 0; i< sd->num_closure; i++) {
649                 ShaderClosure *sc = &sd->closure[i];
650
651                 if(CLOSURE_IS_BSDF_GLOSSY(sc->type))
652                         eval += sc->weight;
653         }
654
655         return eval;
656 #else
657         if(CLOSURE_IS_BSDF_GLOSSY(sd->closure.type))
658                 return sd->closure.weight;
659         else
660                 return make_float3(0.0f, 0.0f, 0.0f);
661 #endif
662 }
663
664 __device float3 shader_bsdf_transmission(KernelGlobals *kg, ShaderData *sd)
665 {
666 #ifdef __MULTI_CLOSURE__
667         float3 eval = make_float3(0.0f, 0.0f, 0.0f);
668
669         for(int i = 0; i< sd->num_closure; i++) {
670                 ShaderClosure *sc = &sd->closure[i];
671
672                 if(CLOSURE_IS_BSDF_TRANSMISSION(sc->type))
673                         eval += sc->weight;
674         }
675
676         return eval;
677 #else
678         if(CLOSURE_IS_BSDF_TRANSMISSION(sd->closure.type))
679                 return sd->closure.weight;
680         else
681                 return make_float3(0.0f, 0.0f, 0.0f);
682 #endif
683 }
684
685 __device float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd, float ao_factor, float3 *N)
686 {
687 #ifdef __MULTI_CLOSURE__
688         float3 eval = make_float3(0.0f, 0.0f, 0.0f);
689
690         *N = make_float3(0.0f, 0.0f, 0.0f);
691
692         for(int i = 0; i< sd->num_closure; i++) {
693                 ShaderClosure *sc = &sd->closure[i];
694
695                 if(CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
696                         eval += sc->weight*ao_factor;
697                         *N += sc->N*average(sc->weight);
698                 }
699                 if(CLOSURE_IS_AMBIENT_OCCLUSION(sc->type)) {
700                         eval += sc->weight;
701                         *N += sd->N*average(sc->weight);
702                 }
703         }
704
705         if(is_zero(*N))
706                 *N = sd->N;
707         else
708                 *N = normalize(*N);
709
710         return eval;
711 #else
712         *N = sd->N;
713
714         if(CLOSURE_IS_BSDF_DIFFUSE(sd->closure.type))
715                 return sd->closure.weight*ao_factor;
716         else if(CLOSURE_IS_AMBIENT_OCCLUSION(sd->closure.type))
717                 return sd->closure.weight;
718         else
719                 return make_float3(0.0f, 0.0f, 0.0f);
720 #endif
721 }
722
723 /* Emission */
724
725 __device float3 emissive_eval(KernelGlobals *kg, ShaderData *sd, ShaderClosure *sc)
726 {
727 #ifdef __OSL__
728         if(kg->osl && sc->prim)
729                 return OSLShader::emissive_eval(sd, sc);
730 #endif
731
732         return emissive_simple_eval(sd->Ng, sd->I);
733 }
734
735 __device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
736 {
737         float3 eval;
738 #ifdef __MULTI_CLOSURE__
739         eval = make_float3(0.0f, 0.0f, 0.0f);
740
741         for(int i = 0; i < sd->num_closure; i++) {
742                 ShaderClosure *sc = &sd->closure[i];
743
744                 if(CLOSURE_IS_EMISSION(sc->type))
745                         eval += emissive_eval(kg, sd, sc)*sc->weight;
746         }
747 #else
748         eval = emissive_eval(kg, sd, &sd->closure)*sd->closure.weight;
749 #endif
750
751         return eval;
752 }
753
754 /* Holdout */
755
756 __device float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd)
757 {
758 #ifdef __MULTI_CLOSURE__
759         float3 weight = make_float3(0.0f, 0.0f, 0.0f);
760
761         for(int i = 0; i < sd->num_closure; i++) {
762                 ShaderClosure *sc = &sd->closure[i];
763
764                 if(CLOSURE_IS_HOLDOUT(sc->type))
765                         weight += sc->weight;
766         }
767
768         return weight;
769 #else
770         if(sd->closure.type == CLOSURE_HOLDOUT_ID)
771                 return make_float3(1.0f, 1.0f, 1.0f);
772
773         return make_float3(0.0f, 0.0f, 0.0f);
774 #endif
775 }
776
777 /* Surface Evaluation */
778
779 __device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
780         float randb, int path_flag, ShaderContext ctx)
781 {
782 #ifdef __OSL__
783         if (kg->osl)
784                 OSLShader::eval_surface(kg, sd, randb, path_flag, ctx);
785         else
786 #endif
787         {
788 #ifdef __SVM__
789                 svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, randb, path_flag);
790 #else
791                 sd->closure.weight = make_float3(0.8f, 0.8f, 0.8f);
792                 sd->closure.N = sd->N;
793                 sd->flag |= bsdf_diffuse_setup(&sd->closure);
794 #endif
795         }
796 }
797
798 /* Background Evaluation */
799
800 __device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx)
801 {
802 #ifdef __OSL__
803         if (kg->osl)
804                 return OSLShader::eval_background(kg, sd, path_flag, ctx);
805         else
806 #endif
807
808         {
809 #ifdef __SVM__
810                 svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, 0.0f, path_flag);
811
812 #ifdef __MULTI_CLOSURE__
813                 float3 eval = make_float3(0.0f, 0.0f, 0.0f);
814
815                 for(int i = 0; i< sd->num_closure; i++) {
816                         const ShaderClosure *sc = &sd->closure[i];
817
818                         if(CLOSURE_IS_BACKGROUND(sc->type))
819                                 eval += sc->weight;
820                 }
821
822                 return eval;
823 #else
824                 if(sd->closure.type == CLOSURE_BACKGROUND_ID)
825                         return sd->closure.weight;
826                 else
827                         return make_float3(0.0f, 0.0f, 0.0f);
828 #endif
829
830 #else
831                 return make_float3(0.8f, 0.8f, 0.8f);
832 #endif
833         }
834 }
835
836 /* Volume */
837
838 __device float3 shader_volume_eval_phase(KernelGlobals *kg, ShaderData *sd,
839         float3 omega_in, float3 omega_out)
840 {
841 #ifdef __MULTI_CLOSURE__
842         float3 eval = make_float3(0.0f, 0.0f, 0.0f);
843
844         for(int i = 0; i< sd->num_closure; i++) {
845                 const ShaderClosure *sc = &sd->closure[i];
846
847                 if(CLOSURE_IS_VOLUME(sc->type))
848                         eval += volume_eval_phase(kg, sc, omega_in, omega_out);
849         }
850
851         return eval;
852 #else
853         return volume_eval_phase(kg, &sd->closure, omega_in, omega_out);
854 #endif
855 }
856
857 /* Volume Evaluation */
858
859 __device void shader_eval_volume(KernelGlobals *kg, ShaderData *sd,
860         float randb, int path_flag, ShaderContext ctx)
861 {
862 #ifdef __SVM__
863 #ifdef __OSL__
864         if (kg->osl)
865                 OSLShader::eval_volume(kg, sd, randb, path_flag, ctx);
866         else
867 #endif
868                 svm_eval_nodes(kg, sd, SHADER_TYPE_VOLUME, randb, path_flag);
869 #endif
870 }
871
872 /* Displacement Evaluation */
873
874 __device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd, ShaderContext ctx)
875 {
876         /* this will modify sd->P */
877 #ifdef __SVM__
878 #ifdef __OSL__
879         if (kg->osl)
880                 OSLShader::eval_displacement(kg, sd, ctx);
881         else
882 #endif
883                 svm_eval_nodes(kg, sd, SHADER_TYPE_DISPLACEMENT, 0.0f, 0);
884 #endif
885 }
886
887 /* Transparent Shadows */
888
889 #ifdef __TRANSPARENT_SHADOWS__
890 __device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect)
891 {
892         int prim = kernel_tex_fetch(__prim_index, isect->prim);
893         int shader = 0;
894
895 #ifdef __HAIR__
896         if(kernel_tex_fetch(__prim_segment, isect->prim) == ~0) {
897 #endif
898                 float4 Ns = kernel_tex_fetch(__tri_normal, prim);
899                 shader = __float_as_int(Ns.w);
900 #ifdef __HAIR__
901         }
902         else {
903                 float4 str = kernel_tex_fetch(__curves, prim);
904                 shader = __float_as_int(str.z);
905         }
906 #endif
907         int flag = kernel_tex_fetch(__shader_flag, (shader & SHADER_MASK)*2);
908
909         return (flag & SD_HAS_TRANSPARENT_SHADOW) != 0;
910 }
911 #endif
912
913 /* Merging */
914
915 #ifdef __NON_PROGRESSIVE__
916 __device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd)
917 {
918         /* merge identical closures, better when we sample a single closure at a time */
919         for(int i = 0; i < sd->num_closure; i++) {
920                 ShaderClosure *sci = &sd->closure[i];
921
922                 for(int j = i + 1; j < sd->num_closure; j++) {
923                         ShaderClosure *scj = &sd->closure[j];
924
925 #ifdef __OSL__
926                         if(!sci->prim && !scj->prim && sci->type == scj->type && sci->data0 == scj->data0 && sci->data1 == scj->data1) {
927 #else
928                         if(sci->type == scj->type && sci->data0 == scj->data0 && sci->data1 == scj->data1) {
929 #endif
930                                 sci->weight += scj->weight;
931                                 sci->sample_weight += scj->sample_weight;
932
933                                 int size = sd->num_closure - (j+1);
934                                 if(size > 0)
935                                         memmove(scj, scj+1, size*sizeof(ShaderClosure));
936
937                                 sd->num_closure--;
938                                 j--;
939                         }
940                 }
941         }
942 }
943 #endif
944
945 CCL_NAMESPACE_END
946