21152efff4c2db2c5972a072c136cc938eacaaef
[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 = ~0)
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);
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 = -sd->P;
406         sd->Ng = -sd->P;
407         sd->I = -sd->P;
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
442 /* BSDF */
443
444 #ifdef __MULTI_CLOSURE__
445
446 __device_inline void _shader_bsdf_multi_eval(KernelGlobals *kg, const ShaderData *sd, const float3 omega_in, float *pdf,
447         int skip_bsdf, BsdfEval *result_eval, float sum_pdf, float sum_sample_weight)
448 {
449         for(int i = 0; i< sd->num_closure; i++) {
450                 if(i == skip_bsdf)
451                         continue;
452
453                 const ShaderClosure *sc = &sd->closure[i];
454
455                 if(CLOSURE_IS_BSDF(sc->type)) {
456                         float bsdf_pdf = 0.0f;
457                         float3 eval = bsdf_eval(kg, sd, sc, omega_in, &bsdf_pdf);
458
459                         if(bsdf_pdf != 0.0f) {
460                                 bsdf_eval_accum(result_eval, sc->type, eval*sc->weight);
461                                 sum_pdf += bsdf_pdf*sc->sample_weight;
462                         }
463
464                         sum_sample_weight += sc->sample_weight;
465                 }
466         }
467
468         *pdf = (sum_sample_weight > 0.0f)? sum_pdf/sum_sample_weight: 0.0f;
469 }
470
471 #endif
472
473 __device void shader_bsdf_eval(KernelGlobals *kg, const ShaderData *sd,
474         const float3 omega_in, BsdfEval *eval, float *pdf)
475 {
476 #ifdef __MULTI_CLOSURE__
477         bsdf_eval_init(eval, NBUILTIN_CLOSURES, make_float3(0.0f, 0.0f, 0.0f), kernel_data.film.use_light_pass);
478
479         return _shader_bsdf_multi_eval(kg, sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
480 #else
481         const ShaderClosure *sc = &sd->closure;
482
483         *pdf = 0.0f;
484         *eval = bsdf_eval(kg, sd, sc, omega_in, pdf)*sc->weight;
485 #endif
486 }
487
488 __device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd,
489         float randu, float randv, BsdfEval *bsdf_eval,
490         float3 *omega_in, differential3 *domega_in, float *pdf)
491 {
492 #ifdef __MULTI_CLOSURE__
493         int sampled = 0;
494
495         if(sd->num_closure > 1) {
496                 /* pick a BSDF closure based on sample weights */
497                 float sum = 0.0f;
498
499                 for(sampled = 0; sampled < sd->num_closure; sampled++) {
500                         const ShaderClosure *sc = &sd->closure[sampled];
501                         
502                         if(CLOSURE_IS_BSDF(sc->type))
503                                 sum += sc->sample_weight;
504                 }
505
506                 float r = sd->randb_closure*sum;
507                 sum = 0.0f;
508
509                 for(sampled = 0; sampled < sd->num_closure; sampled++) {
510                         const ShaderClosure *sc = &sd->closure[sampled];
511                         
512                         if(CLOSURE_IS_BSDF(sc->type)) {
513                                 sum += sc->sample_weight;
514
515                                 if(r <= sum)
516                                         break;
517                         }
518                 }
519
520                 if(sampled == sd->num_closure) {
521                         *pdf = 0.0f;
522                         return LABEL_NONE;
523                 }
524         }
525
526         const ShaderClosure *sc = &sd->closure[sampled];
527         int label;
528         float3 eval;
529
530         *pdf = 0.0f;
531         label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
532
533         if(*pdf != 0.0f) {
534                 bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass);
535
536                 if(sd->num_closure > 1) {
537                         float sweight = sc->sample_weight;
538                         _shader_bsdf_multi_eval(kg, sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight);
539                 }
540         }
541
542         return label;
543 #else
544         /* sample the single closure that we picked */
545         *pdf = 0.0f;
546         int label = bsdf_sample(kg, sd, &sd->closure, randu, randv, bsdf_eval, omega_in, domega_in, pdf);
547         *bsdf_eval *= sd->closure.weight;
548         return label;
549 #endif
550 }
551
552 __device int shader_bsdf_sample_closure(KernelGlobals *kg, const ShaderData *sd,
553         const ShaderClosure *sc, float randu, float randv, BsdfEval *bsdf_eval,
554         float3 *omega_in, differential3 *domega_in, float *pdf)
555 {
556         int label;
557         float3 eval;
558
559         *pdf = 0.0f;
560         label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
561
562         if(*pdf != 0.0f)
563                 bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass);
564
565         return label;
566 }
567
568 __device void shader_bsdf_blur(KernelGlobals *kg, ShaderData *sd, float roughness)
569 {
570 #ifdef __MULTI_CLOSURE__
571         for(int i = 0; i< sd->num_closure; i++) {
572                 ShaderClosure *sc = &sd->closure[i];
573
574                 if(CLOSURE_IS_BSDF(sc->type))
575                         bsdf_blur(kg, sc, roughness);
576         }
577 #else
578         bsdf_blur(kg, &sd->closure, roughness);
579 #endif
580 }
581
582 __device float3 shader_bsdf_transparency(KernelGlobals *kg, ShaderData *sd)
583 {
584 #ifdef __MULTI_CLOSURE__
585         float3 eval = make_float3(0.0f, 0.0f, 0.0f);
586
587         for(int i = 0; i< sd->num_closure; i++) {
588                 ShaderClosure *sc = &sd->closure[i];
589
590                 if(sc->type == CLOSURE_BSDF_TRANSPARENT_ID) // todo: make this work for osl
591                         eval += sc->weight;
592         }
593
594         return eval;
595 #else
596         if(sd->closure.type == CLOSURE_BSDF_TRANSPARENT_ID)
597                 return sd->closure.weight;
598         else
599                 return make_float3(0.0f, 0.0f, 0.0f);
600 #endif
601 }
602
603 __device float3 shader_bsdf_diffuse(KernelGlobals *kg, ShaderData *sd)
604 {
605 #ifdef __MULTI_CLOSURE__
606         float3 eval = make_float3(0.0f, 0.0f, 0.0f);
607
608         for(int i = 0; i< sd->num_closure; i++) {
609                 ShaderClosure *sc = &sd->closure[i];
610
611                 if(CLOSURE_IS_BSDF_DIFFUSE(sc->type))
612                         eval += sc->weight;
613         }
614
615         return eval;
616 #else
617         if(CLOSURE_IS_BSDF_DIFFUSE(sd->closure.type))
618                 return sd->closure.weight;
619         else
620                 return make_float3(0.0f, 0.0f, 0.0f);
621 #endif
622 }
623
624 __device float3 shader_bsdf_glossy(KernelGlobals *kg, ShaderData *sd)
625 {
626 #ifdef __MULTI_CLOSURE__
627         float3 eval = make_float3(0.0f, 0.0f, 0.0f);
628
629         for(int i = 0; i< sd->num_closure; i++) {
630                 ShaderClosure *sc = &sd->closure[i];
631
632                 if(CLOSURE_IS_BSDF_GLOSSY(sc->type))
633                         eval += sc->weight;
634         }
635
636         return eval;
637 #else
638         if(CLOSURE_IS_BSDF_GLOSSY(sd->closure.type))
639                 return sd->closure.weight;
640         else
641                 return make_float3(0.0f, 0.0f, 0.0f);
642 #endif
643 }
644
645 __device float3 shader_bsdf_transmission(KernelGlobals *kg, ShaderData *sd)
646 {
647 #ifdef __MULTI_CLOSURE__
648         float3 eval = make_float3(0.0f, 0.0f, 0.0f);
649
650         for(int i = 0; i< sd->num_closure; i++) {
651                 ShaderClosure *sc = &sd->closure[i];
652
653                 if(CLOSURE_IS_BSDF_TRANSMISSION(sc->type))
654                         eval += sc->weight;
655         }
656
657         return eval;
658 #else
659         if(CLOSURE_IS_BSDF_TRANSMISSION(sd->closure.type))
660                 return sd->closure.weight;
661         else
662                 return make_float3(0.0f, 0.0f, 0.0f);
663 #endif
664 }
665
666 __device float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd, float ao_factor, float3 *N)
667 {
668 #ifdef __MULTI_CLOSURE__
669         float3 eval = make_float3(0.0f, 0.0f, 0.0f);
670
671         *N = make_float3(0.0f, 0.0f, 0.0f);
672
673         for(int i = 0; i< sd->num_closure; i++) {
674                 ShaderClosure *sc = &sd->closure[i];
675
676                 if(CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
677                         eval += sc->weight*ao_factor;
678                         *N += sc->N*average(sc->weight);
679                 }
680                 if(CLOSURE_IS_AMBIENT_OCCLUSION(sc->type)) {
681                         eval += sc->weight;
682                         *N += sd->N*average(sc->weight);
683                 }
684         }
685
686         if(is_zero(*N))
687                 *N = sd->N;
688         else
689                 *N = normalize(*N);
690
691         return eval;
692 #else
693         *N = sd->N;
694
695         if(CLOSURE_IS_BSDF_DIFFUSE(sd->closure.type))
696                 return sd->closure.weight*ao_factor;
697         else if(CLOSURE_IS_AMBIENT_OCCLUSION(sd->closure.type))
698                 return sd->closure.weight;
699         else
700                 return make_float3(0.0f, 0.0f, 0.0f);
701 #endif
702 }
703
704 /* Emission */
705
706 __device float3 emissive_eval(KernelGlobals *kg, ShaderData *sd, ShaderClosure *sc)
707 {
708 #ifdef __OSL__
709         if(kg->osl && sc->prim)
710                 return OSLShader::emissive_eval(sd, sc);
711 #endif
712
713         return emissive_simple_eval(sd->Ng, sd->I);
714 }
715
716 __device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
717 {
718         float3 eval;
719 #ifdef __MULTI_CLOSURE__
720         eval = make_float3(0.0f, 0.0f, 0.0f);
721
722         for(int i = 0; i < sd->num_closure; i++) {
723                 ShaderClosure *sc = &sd->closure[i];
724
725                 if(CLOSURE_IS_EMISSION(sc->type))
726                         eval += emissive_eval(kg, sd, sc)*sc->weight;
727         }
728 #else
729         eval = emissive_eval(kg, sd, &sd->closure)*sd->closure.weight;
730 #endif
731
732         return eval;
733 }
734
735 /* Holdout */
736
737 __device float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd)
738 {
739 #ifdef __MULTI_CLOSURE__
740         float3 weight = make_float3(0.0f, 0.0f, 0.0f);
741
742         for(int i = 0; i < sd->num_closure; i++) {
743                 ShaderClosure *sc = &sd->closure[i];
744
745                 if(CLOSURE_IS_HOLDOUT(sc->type))
746                         weight += sc->weight;
747         }
748
749         return weight;
750 #else
751         if(sd->closure.type == CLOSURE_HOLDOUT_ID)
752                 return make_float3(1.0f, 1.0f, 1.0f);
753
754         return make_float3(0.0f, 0.0f, 0.0f);
755 #endif
756 }
757
758 /* Surface Evaluation */
759
760 __device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
761         float randb, int path_flag, ShaderContext ctx)
762 {
763 #ifdef __OSL__
764         if (kg->osl)
765                 OSLShader::eval_surface(kg, sd, randb, path_flag, ctx);
766         else
767 #endif
768         {
769 #ifdef __SVM__
770                 svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, randb, path_flag);
771 #else
772                 bsdf_diffuse_setup(&sd->closure);
773                 sd->closure.weight = make_float3(0.8f, 0.8f, 0.8f);
774 #endif
775         }
776 }
777
778 /* Background Evaluation */
779
780 __device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx)
781 {
782 #ifdef __OSL__
783         if (kg->osl)
784                 return OSLShader::eval_background(kg, sd, path_flag, ctx);
785         else
786 #endif
787
788         {
789 #ifdef __SVM__
790                 svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, 0.0f, path_flag);
791
792 #ifdef __MULTI_CLOSURE__
793                 float3 eval = make_float3(0.0f, 0.0f, 0.0f);
794
795                 for(int i = 0; i< sd->num_closure; i++) {
796                         const ShaderClosure *sc = &sd->closure[i];
797
798                         if(CLOSURE_IS_BACKGROUND(sc->type))
799                                 eval += sc->weight;
800                 }
801
802                 return eval;
803 #else
804                 if(sd->closure.type == CLOSURE_BACKGROUND_ID)
805                         return sd->closure.weight;
806                 else
807                         return make_float3(0.0f, 0.0f, 0.0f);
808 #endif
809
810 #else
811                 return make_float3(0.8f, 0.8f, 0.8f);
812 #endif
813         }
814 }
815
816 /* Volume */
817
818 __device float3 shader_volume_eval_phase(KernelGlobals *kg, ShaderData *sd,
819         float3 omega_in, float3 omega_out)
820 {
821 #ifdef __MULTI_CLOSURE__
822         float3 eval = make_float3(0.0f, 0.0f, 0.0f);
823
824         for(int i = 0; i< sd->num_closure; i++) {
825                 const ShaderClosure *sc = &sd->closure[i];
826
827                 if(CLOSURE_IS_VOLUME(sc->type))
828                         eval += volume_eval_phase(kg, sc, omega_in, omega_out);
829         }
830
831         return eval;
832 #else
833         return volume_eval_phase(kg, &sd->closure, omega_in, omega_out);
834 #endif
835 }
836
837 /* Volume Evaluation */
838
839 __device void shader_eval_volume(KernelGlobals *kg, ShaderData *sd,
840         float randb, int path_flag, ShaderContext ctx)
841 {
842 #ifdef __SVM__
843 #ifdef __OSL__
844         if (kg->osl)
845                 OSLShader::eval_volume(kg, sd, randb, path_flag, ctx);
846         else
847 #endif
848                 svm_eval_nodes(kg, sd, SHADER_TYPE_VOLUME, randb, path_flag);
849 #endif
850 }
851
852 /* Displacement Evaluation */
853
854 __device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd, ShaderContext ctx)
855 {
856         /* this will modify sd->P */
857 #ifdef __SVM__
858 #ifdef __OSL__
859         if (kg->osl)
860                 OSLShader::eval_displacement(kg, sd, ctx);
861         else
862 #endif
863                 svm_eval_nodes(kg, sd, SHADER_TYPE_DISPLACEMENT, 0.0f, 0);
864 #endif
865 }
866
867 /* Transparent Shadows */
868
869 #ifdef __TRANSPARENT_SHADOWS__
870 __device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect)
871 {
872         int prim = kernel_tex_fetch(__prim_index, isect->prim);
873         int shader = 0;
874
875 #ifdef __HAIR__
876         if(kernel_tex_fetch(__prim_segment, isect->prim) == ~0) {
877 #endif
878                 float4 Ns = kernel_tex_fetch(__tri_normal, prim);
879                 shader = __float_as_int(Ns.w);
880 #ifdef __HAIR__
881         }
882         else {
883                 float4 str = kernel_tex_fetch(__curves, prim);
884                 shader = __float_as_int(str.z);
885         }
886 #endif
887         int flag = kernel_tex_fetch(__shader_flag, (shader & SHADER_MASK)*2);
888
889         return (flag & SD_HAS_SURFACE_TRANSPARENT) != 0;
890 }
891 #endif
892
893 /* Merging */
894
895 #ifdef __NON_PROGRESSIVE__
896 __device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd)
897 {
898         /* merge identical closures, better when we sample a single closure at a time */
899         for(int i = 0; i < sd->num_closure; i++) {
900                 ShaderClosure *sci = &sd->closure[i];
901
902                 for(int j = i + 1; j < sd->num_closure; j++) {
903                         ShaderClosure *scj = &sd->closure[j];
904
905 #ifdef __OSL__
906                         if(!sci->prim && !scj->prim && sci->type == scj->type && sci->data0 == scj->data0 && sci->data1 == scj->data1) {
907 #else
908                         if(sci->type == scj->type && sci->data0 == scj->data0 && sci->data1 == scj->data1) {
909 #endif
910                                 sci->weight += scj->weight;
911                                 sci->sample_weight += scj->sample_weight;
912
913                                 int size = sd->num_closure - (j+1);
914                                 if(size > 0)
915                                         memmove(scj, scj+1, size*sizeof(ShaderClosure));
916
917                                 sd->num_closure--;
918                                 j--;
919                         }
920                 }
921         }
922 }
923 #endif
924
925 CCL_NAMESPACE_END
926