add BLI_strcpy_rlen, replace strcat, which was used in misleading way.
[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                 /*elements for minimum hair width using transparency bsdf*/
100                 /*sd->curve_transparency = 0.0f;*/
101                 /*sd->curve_radius = 0.0f;*/
102 #endif
103
104 #ifdef __UV__
105                 sd->u = isect->u;
106                 sd->v = isect->v;
107 #endif
108
109                 /* vectors */
110                 sd->P = bvh_triangle_refine(kg, sd, isect, ray);
111                 sd->Ng = Ng;
112                 sd->N = Ng;
113                 
114                 /* smooth normal */
115                 if(sd->shader & SHADER_SMOOTH_NORMAL)
116                         sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
117
118 #ifdef __DPDU__
119                 /* dPdu/dPdv */
120                 triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim);
121 #endif
122
123 #ifdef __HAIR__
124         }
125 #endif
126
127         sd->I = -ray->D;
128
129         sd->flag |= kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
130
131 #ifdef __INSTANCING__
132         if(isect->object != ~0) {
133                 /* instance transform */
134                 object_normal_transform(kg, sd, &sd->N);
135                 object_normal_transform(kg, sd, &sd->Ng);
136 #ifdef __DPDU__
137                 object_dir_transform(kg, sd, &sd->dPdu);
138                 object_dir_transform(kg, sd, &sd->dPdv);
139 #endif
140         }
141 #endif
142
143         /* backfacing test */
144         bool backfacing = (dot(sd->Ng, sd->I) < 0.0f);
145
146         if(backfacing) {
147                 sd->flag |= SD_BACKFACING;
148                 sd->Ng = -sd->Ng;
149                 sd->N = -sd->N;
150 #ifdef __DPDU__
151                 sd->dPdu = -sd->dPdu;
152                 sd->dPdv = -sd->dPdv;
153 #endif
154         }
155
156 #ifdef __RAY_DIFFERENTIALS__
157         /* differentials */
158         differential_transfer(&sd->dP, ray->dP, ray->D, ray->dD, sd->Ng, isect->t);
159         differential_incoming(&sd->dI, ray->dD);
160         differential_dudv(&sd->du, &sd->dv, sd->dPdu, sd->dPdv, sd->dP, sd->Ng);
161 #endif
162 }
163
164 /* ShaderData setup from BSSRDF scatter */
165
166 #ifdef __SUBSURFACE__
167 __device_inline void shader_setup_from_subsurface(KernelGlobals *kg, ShaderData *sd,
168         const Intersection *isect, const Ray *ray)
169 {
170         bool backfacing = sd->flag & SD_BACKFACING;
171
172         /* object, matrices, time, ray_length stay the same */
173         sd->flag = kernel_tex_fetch(__object_flag, sd->object);
174         sd->prim = kernel_tex_fetch(__prim_index, isect->prim);
175
176 #ifdef __HAIR__
177         if(kernel_tex_fetch(__prim_segment, isect->prim) != ~0) {
178                 /* Strand Shader setting*/
179                 float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
180
181                 sd->shader = __float_as_int(curvedata.z);
182                 sd->segment = isect->segment;
183
184                 float tcorr = isect->t;
185                 if(kernel_data.curve_kernel_data.curveflags & CURVE_KN_POSTINTERSECTCORRECTION)
186                         tcorr = (isect->u < 0)? tcorr + sqrtf(isect->v) : tcorr - sqrtf(isect->v);
187
188                 sd->P = bvh_curve_refine(kg, sd, isect, ray, tcorr);
189         }
190         else {
191 #endif
192                 /* fetch triangle data */
193                 float4 Ns = kernel_tex_fetch(__tri_normal, sd->prim);
194                 float3 Ng = make_float3(Ns.x, Ns.y, Ns.z);
195                 sd->shader = __float_as_int(Ns.w);
196
197 #ifdef __HAIR__
198                 sd->segment = ~0;
199 #endif
200
201 #ifdef __UV__
202                 sd->u = isect->u;
203                 sd->v = isect->v;
204 #endif
205
206                 /* vectors */
207                 sd->P = bvh_triangle_refine(kg, sd, isect, ray);
208                 sd->Ng = Ng;
209                 sd->N = Ng;
210                 
211                 /* smooth normal */
212                 if(sd->shader & SHADER_SMOOTH_NORMAL)
213                         sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
214
215 #ifdef __DPDU__
216                 /* dPdu/dPdv */
217                 triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim);
218 #endif
219
220 #ifdef __HAIR__
221         }
222 #endif
223
224         sd->flag |= kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
225
226 #ifdef __INSTANCING__
227         if(isect->object != ~0) {
228                 /* instance transform */
229                 object_normal_transform(kg, sd, &sd->N);
230                 object_normal_transform(kg, sd, &sd->Ng);
231 #ifdef __DPDU__
232                 object_dir_transform(kg, sd, &sd->dPdu);
233                 object_dir_transform(kg, sd, &sd->dPdv);
234 #endif
235         }
236 #endif
237
238         /* backfacing test */
239         if(backfacing) {
240                 sd->flag |= SD_BACKFACING;
241                 sd->Ng = -sd->Ng;
242                 sd->N = -sd->N;
243 #ifdef __DPDU__
244                 sd->dPdu = -sd->dPdu;
245                 sd->dPdv = -sd->dPdv;
246 #endif
247         }
248
249         /* should not get used in principle as the shading will only use a diffuse
250          * BSDF, but the shader might still access it */
251         sd->I = sd->N;
252
253 #ifdef __RAY_DIFFERENTIALS__
254         /* differentials */
255         differential_dudv(&sd->du, &sd->dv, sd->dPdu, sd->dPdv, sd->dP, sd->Ng);
256         /* don't modify dP and dI */
257 #endif
258 }
259 #endif
260
261 /* ShaderData setup from position sampled on mesh */
262
263 __device_noinline void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
264         const float3 P, const float3 Ng, const float3 I,
265         int shader, int object, int prim, float u, float v, float t, float time, int segment)
266 {
267         /* vectors */
268         sd->P = P;
269         sd->N = Ng;
270         sd->Ng = Ng;
271         sd->I = I;
272         sd->shader = shader;
273 #ifdef __HAIR__
274         sd->segment = segment;
275 #endif
276
277         /* primitive */
278 #ifdef __INSTANCING__
279         sd->object = object;
280 #endif
281         /* currently no access to bvh prim index for strand sd->prim - this will cause errors with needs fixing*/
282         sd->prim = prim;
283 #ifdef __UV__
284         sd->u = u;
285         sd->v = v;
286 #endif
287         sd->ray_length = t;
288
289         /* detect instancing, for non-instanced the object index is -object-1 */
290 #ifdef __INSTANCING__
291         bool instanced = false;
292
293         if(sd->prim != ~0) {
294                 if(sd->object >= 0)
295                         instanced = true;
296                 else
297 #endif
298                         sd->object = ~sd->object;
299 #ifdef __INSTANCING__
300         }
301 #endif
302
303         sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
304         if(sd->object != -1) {
305                 sd->flag |= kernel_tex_fetch(__object_flag, sd->object);
306
307 #ifdef __OBJECT_MOTION__
308                 shader_setup_object_transforms(kg, sd, time);
309         }
310
311         sd->time = time;
312 #else
313         }
314 #endif
315
316         /* smooth normal */
317 #ifdef __HAIR__
318         if(sd->shader & SHADER_SMOOTH_NORMAL && sd->segment == ~0) {
319                 sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
320 #else
321         if(sd->shader & SHADER_SMOOTH_NORMAL) {
322                 sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
323 #endif
324
325 #ifdef __INSTANCING__
326                 if(instanced)
327                         object_normal_transform(kg, sd, &sd->N);
328 #endif
329         }
330
331 #ifdef __DPDU__
332         /* dPdu/dPdv */
333 #ifdef __HAIR__
334         if(sd->prim == ~0 || sd->segment != ~0) {
335                 sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
336                 sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
337         }
338 #else
339         if(sd->prim == ~0) {
340                 sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
341                 sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
342         }
343 #endif
344         else {
345                 triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim);
346
347 #ifdef __INSTANCING__
348                 if(instanced) {
349                         object_dir_transform(kg, sd, &sd->dPdu);
350                         object_dir_transform(kg, sd, &sd->dPdv);
351                 }
352 #endif
353         }
354 #endif
355
356         /* backfacing test */
357         if(sd->prim != ~0) {
358                 bool backfacing = (dot(sd->Ng, sd->I) < 0.0f);
359
360                 if(backfacing) {
361                         sd->flag |= SD_BACKFACING;
362                         sd->Ng = -sd->Ng;
363                         sd->N = -sd->N;
364 #ifdef __DPDU__
365                         sd->dPdu = -sd->dPdu;
366                         sd->dPdv = -sd->dPdv;
367 #endif
368                 }
369         }
370
371 #ifdef __RAY_DIFFERENTIALS__
372         /* no ray differentials here yet */
373         sd->dP = differential3_zero();
374         sd->dI = differential3_zero();
375         sd->du = differential_zero();
376         sd->dv = differential_zero();
377 #endif
378 }
379
380 /* ShaderData setup for displacement */
381
382 __device void shader_setup_from_displace(KernelGlobals *kg, ShaderData *sd,
383         int object, int prim, float u, float v)
384 {
385         float3 P, Ng, I = make_float3(0.0f, 0.0f, 0.0f);
386         int shader;
387
388         P = triangle_point_MT(kg, prim, u, v);
389         Ng = triangle_normal_MT(kg, prim, &shader);
390
391         /* force smooth shading for displacement */
392         shader |= SHADER_SMOOTH_NORMAL;
393
394         /* watch out: no instance transform currently */
395
396         shader_setup_from_sample(kg, sd, P, Ng, I, shader, object, prim, u, v, 0.0f, TIME_INVALID, ~0);
397 }
398
399 /* ShaderData setup from ray into background */
400
401 __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData *sd, const Ray *ray)
402 {
403         /* vectors */
404         sd->P = ray->D;
405         sd->N = -ray->D;
406         sd->Ng = -ray->D;
407         sd->I = -ray->D;
408         sd->shader = kernel_data.background.shader;
409         sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
410 #ifdef __OBJECT_MOTION__
411         sd->time = ray->time;
412 #endif
413         sd->ray_length = 0.0f;
414
415 #ifdef __INSTANCING__
416         sd->object = ~0;
417 #endif
418         sd->prim = ~0;
419 #ifdef __HAIR__
420         sd->segment = ~0;
421 #endif
422 #ifdef __UV__
423         sd->u = 0.0f;
424         sd->v = 0.0f;
425 #endif
426
427 #ifdef __DPDU__
428         /* dPdu/dPdv */
429         sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
430         sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
431 #endif
432
433 #ifdef __RAY_DIFFERENTIALS__
434         /* differentials */
435         sd->dP = ray->dD;
436         differential_incoming(&sd->dI, sd->dP);
437         sd->du = differential_zero();
438         sd->dv = differential_zero();
439 #endif
440
441         /* for NDC coordinates */
442         sd->ray_P = ray->P;
443         sd->ray_dP = ray->dP;
444 }
445
446 /* BSDF */
447
448 #ifdef __MULTI_CLOSURE__
449
450 __device_inline void _shader_bsdf_multi_eval(KernelGlobals *kg, const ShaderData *sd, const float3 omega_in, float *pdf,
451         int skip_bsdf, BsdfEval *result_eval, float sum_pdf, float sum_sample_weight)
452 {
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         return _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_ao(KernelGlobals *kg, ShaderData *sd, float ao_factor, float3 *N)
671 {
672 #ifdef __MULTI_CLOSURE__
673         float3 eval = make_float3(0.0f, 0.0f, 0.0f);
674
675         *N = make_float3(0.0f, 0.0f, 0.0f);
676
677         for(int i = 0; i< sd->num_closure; i++) {
678                 ShaderClosure *sc = &sd->closure[i];
679
680                 if(CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
681                         eval += sc->weight*ao_factor;
682                         *N += sc->N*average(sc->weight);
683                 }
684                 if(CLOSURE_IS_AMBIENT_OCCLUSION(sc->type)) {
685                         eval += sc->weight;
686                         *N += sd->N*average(sc->weight);
687                 }
688         }
689
690         if(is_zero(*N))
691                 *N = sd->N;
692         else
693                 *N = normalize(*N);
694
695         return eval;
696 #else
697         *N = sd->N;
698
699         if(CLOSURE_IS_BSDF_DIFFUSE(sd->closure.type))
700                 return sd->closure.weight*ao_factor;
701         else if(CLOSURE_IS_AMBIENT_OCCLUSION(sd->closure.type))
702                 return sd->closure.weight;
703         else
704                 return make_float3(0.0f, 0.0f, 0.0f);
705 #endif
706 }
707
708 /* Emission */
709
710 __device float3 emissive_eval(KernelGlobals *kg, ShaderData *sd, ShaderClosure *sc)
711 {
712 #ifdef __OSL__
713         if(kg->osl && sc->prim)
714                 return OSLShader::emissive_eval(sd, sc);
715 #endif
716
717         return emissive_simple_eval(sd->Ng, sd->I);
718 }
719
720 __device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
721 {
722         float3 eval;
723 #ifdef __MULTI_CLOSURE__
724         eval = make_float3(0.0f, 0.0f, 0.0f);
725
726         for(int i = 0; i < sd->num_closure; i++) {
727                 ShaderClosure *sc = &sd->closure[i];
728
729                 if(CLOSURE_IS_EMISSION(sc->type))
730                         eval += emissive_eval(kg, sd, sc)*sc->weight;
731         }
732 #else
733         eval = emissive_eval(kg, sd, &sd->closure)*sd->closure.weight;
734 #endif
735
736         return eval;
737 }
738
739 /* Holdout */
740
741 __device float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd)
742 {
743 #ifdef __MULTI_CLOSURE__
744         float3 weight = make_float3(0.0f, 0.0f, 0.0f);
745
746         for(int i = 0; i < sd->num_closure; i++) {
747                 ShaderClosure *sc = &sd->closure[i];
748
749                 if(CLOSURE_IS_HOLDOUT(sc->type))
750                         weight += sc->weight;
751         }
752
753         return weight;
754 #else
755         if(sd->closure.type == CLOSURE_HOLDOUT_ID)
756                 return make_float3(1.0f, 1.0f, 1.0f);
757
758         return make_float3(0.0f, 0.0f, 0.0f);
759 #endif
760 }
761
762 /* Surface Evaluation */
763
764 __device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
765         float randb, int path_flag, ShaderContext ctx)
766 {
767 #ifdef __OSL__
768         if (kg->osl)
769                 OSLShader::eval_surface(kg, sd, randb, path_flag, ctx);
770         else
771 #endif
772         {
773 #ifdef __SVM__
774                 svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, randb, path_flag);
775 #else
776                 sd->closure.weight = make_float3(0.8f, 0.8f, 0.8f);
777                 sd->closure.N = sd->N;
778                 sd->flag |= bsdf_diffuse_setup(&sd->closure);
779 #endif
780         }
781 }
782
783 /* Background Evaluation */
784
785 __device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx)
786 {
787 #ifdef __OSL__
788         if (kg->osl)
789                 return OSLShader::eval_background(kg, sd, path_flag, ctx);
790         else
791 #endif
792
793         {
794 #ifdef __SVM__
795                 svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, 0.0f, path_flag);
796
797 #ifdef __MULTI_CLOSURE__
798                 float3 eval = make_float3(0.0f, 0.0f, 0.0f);
799
800                 for(int i = 0; i< sd->num_closure; i++) {
801                         const ShaderClosure *sc = &sd->closure[i];
802
803                         if(CLOSURE_IS_BACKGROUND(sc->type))
804                                 eval += sc->weight;
805                 }
806
807                 return eval;
808 #else
809                 if(sd->closure.type == CLOSURE_BACKGROUND_ID)
810                         return sd->closure.weight;
811                 else
812                         return make_float3(0.0f, 0.0f, 0.0f);
813 #endif
814
815 #else
816                 return make_float3(0.8f, 0.8f, 0.8f);
817 #endif
818         }
819 }
820
821 /* Volume */
822
823 __device float3 shader_volume_eval_phase(KernelGlobals *kg, ShaderData *sd,
824         float3 omega_in, float3 omega_out)
825 {
826 #ifdef __MULTI_CLOSURE__
827         float3 eval = make_float3(0.0f, 0.0f, 0.0f);
828
829         for(int i = 0; i< sd->num_closure; i++) {
830                 const ShaderClosure *sc = &sd->closure[i];
831
832                 if(CLOSURE_IS_VOLUME(sc->type))
833                         eval += volume_eval_phase(kg, sc, omega_in, omega_out);
834         }
835
836         return eval;
837 #else
838         return volume_eval_phase(kg, &sd->closure, omega_in, omega_out);
839 #endif
840 }
841
842 /* Volume Evaluation */
843
844 __device void shader_eval_volume(KernelGlobals *kg, ShaderData *sd,
845         float randb, int path_flag, ShaderContext ctx)
846 {
847 #ifdef __SVM__
848 #ifdef __OSL__
849         if (kg->osl)
850                 OSLShader::eval_volume(kg, sd, randb, path_flag, ctx);
851         else
852 #endif
853                 svm_eval_nodes(kg, sd, SHADER_TYPE_VOLUME, randb, path_flag);
854 #endif
855 }
856
857 /* Displacement Evaluation */
858
859 __device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd, ShaderContext ctx)
860 {
861         /* this will modify sd->P */
862 #ifdef __SVM__
863 #ifdef __OSL__
864         if (kg->osl)
865                 OSLShader::eval_displacement(kg, sd, ctx);
866         else
867 #endif
868                 svm_eval_nodes(kg, sd, SHADER_TYPE_DISPLACEMENT, 0.0f, 0);
869 #endif
870 }
871
872 /* Transparent Shadows */
873
874 #ifdef __TRANSPARENT_SHADOWS__
875 __device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect)
876 {
877         int prim = kernel_tex_fetch(__prim_index, isect->prim);
878         int shader = 0;
879
880 #ifdef __HAIR__
881         if(kernel_tex_fetch(__prim_segment, isect->prim) == ~0) {
882 #endif
883                 float4 Ns = kernel_tex_fetch(__tri_normal, prim);
884                 shader = __float_as_int(Ns.w);
885 #ifdef __HAIR__
886         }
887         else {
888                 float4 str = kernel_tex_fetch(__curves, prim);
889                 shader = __float_as_int(str.z);
890         }
891 #endif
892         int flag = kernel_tex_fetch(__shader_flag, (shader & SHADER_MASK)*2);
893
894         return (flag & SD_HAS_SURFACE_TRANSPARENT) != 0;
895 }
896 #endif
897
898 /* Merging */
899
900 #ifdef __NON_PROGRESSIVE__
901 __device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd)
902 {
903         /* merge identical closures, better when we sample a single closure at a time */
904         for(int i = 0; i < sd->num_closure; i++) {
905                 ShaderClosure *sci = &sd->closure[i];
906
907                 for(int j = i + 1; j < sd->num_closure; j++) {
908                         ShaderClosure *scj = &sd->closure[j];
909
910 #ifdef __OSL__
911                         if(!sci->prim && !scj->prim && sci->type == scj->type && sci->data0 == scj->data0 && sci->data1 == scj->data1) {
912 #else
913                         if(sci->type == scj->type && sci->data0 == scj->data0 && sci->data1 == scj->data1) {
914 #endif
915                                 sci->weight += scj->weight;
916                                 sci->sample_weight += scj->sample_weight;
917
918                                 int size = sd->num_closure - (j+1);
919                                 if(size > 0)
920                                         memmove(scj, scj+1, size*sizeof(ShaderClosure));
921
922                                 sd->num_closure--;
923                                 j--;
924                         }
925                 }
926         }
927 }
928 #endif
929
930 CCL_NAMESPACE_END
931