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