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