Cycles: OpenCL tweaks
[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
30 #ifdef __OSL__
31
32 #include "osl_shader.h"
33
34 #else
35
36 #include "svm/bsdf.h"
37 #include "svm/emissive.h"
38 #include "svm/volume.h"
39 #include "svm/svm_bsdf.h"
40 #include "svm/svm.h"
41
42 #endif
43
44 CCL_NAMESPACE_BEGIN
45
46 /* ShaderData setup from incoming ray */
47
48 __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
49         const Intersection *isect, const Ray *ray)
50 {
51         /* fetch triangle data */
52         int prim = kernel_tex_fetch(__prim_index, isect->prim);
53         float4 Ns = kernel_tex_fetch(__tri_normal, prim);
54         float3 Ng = make_float3(Ns.x, Ns.y, Ns.z);
55         int shader = __float_as_int(Ns.w);
56
57         /* vectors */
58         sd->P = bvh_triangle_refine(kg, isect, ray);
59         sd->Ng = Ng;
60         sd->N = Ng;
61         sd->I = -ray->D;
62         sd->shader = shader;
63
64         /* triangle */
65 #ifdef __INSTANCING__
66         sd->object = isect->object;
67 #endif
68         sd->prim = prim;
69 #ifdef __UV__
70         sd->u = isect->u;
71         sd->v = isect->v;
72 #endif
73
74         /* smooth normal */
75         if(sd->shader & SHADER_SMOOTH_NORMAL)
76                 sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
77
78         sd->flag = kernel_tex_fetch(__shader_flag, sd->shader & SHADER_MASK);
79
80 #ifdef __DPDU__
81         /* dPdu/dPdv */
82         triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim);
83 #endif
84
85 #ifdef __INSTANCING__
86         if(sd->object != ~0) {
87                 /* instance transform */
88                 object_normal_transform(kg, sd->object, &sd->N);
89                 object_normal_transform(kg, sd->object, &sd->Ng);
90 #ifdef __DPDU__
91                 object_dir_transform(kg, sd->object, &sd->dPdu);
92                 object_dir_transform(kg, sd->object, &sd->dPdv);
93 #endif
94         }
95         else {
96                 /* non-instanced object index */
97                 sd->object = kernel_tex_fetch(__prim_object, isect->prim);
98         }
99 #endif
100
101         /* backfacing test */
102         bool backfacing = (dot(sd->Ng, sd->I) < 0.0f);
103
104         if(backfacing) {
105                 sd->flag |= SD_BACKFACING;
106                 sd->Ng = -sd->Ng;
107                 sd->N = -sd->N;
108 #ifdef __DPDU__
109                 sd->dPdu = -sd->dPdu;
110                 sd->dPdv = -sd->dPdv;
111 #endif
112         }
113
114 #ifdef __RAY_DIFFERENTIALS__
115         /* differentials */
116         differential_transfer(&sd->dP, ray->dP, ray->D, ray->dD, sd->Ng, isect->t);
117         differential_incoming(&sd->dI, ray->dD);
118         differential_dudv(&sd->du, &sd->dv, sd->dPdu, sd->dPdv, sd->dP, sd->Ng);
119 #endif
120 }
121
122 /* ShaderData setup from position sampled on mesh */
123
124 __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
125         const float3 P, const float3 Ng, const float3 I,
126         int shader, int object, int prim,  float u, float v)
127 {
128         /* vectors */
129         sd->P = P;
130         sd->N = Ng;
131         sd->Ng = Ng;
132         sd->I = I;
133         sd->shader = shader;
134
135         /* primitive */
136 #ifdef __INSTANCING__
137         sd->object = object;
138 #endif
139         sd->prim = prim;
140 #ifdef __UV__
141         sd->u = u;
142         sd->v = v;
143 #endif
144
145         /* detect instancing, for non-instanced the object index is -object-1 */
146 #ifdef __INSTANCING__
147         bool instanced = false;
148
149         if(sd->prim != ~0) {
150                 if(sd->object >= 0)
151                         instanced = true;
152                 else
153 #endif
154                         sd->object = -sd->object-1;
155 #ifdef __INSTANCING__
156         }
157 #endif
158
159         /* smooth normal */
160         if(sd->shader & SHADER_SMOOTH_NORMAL) {
161                 sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
162
163 #ifdef __INSTANCING__
164                 if(instanced)
165                         object_normal_transform(kg, sd->object, &sd->N);
166 #endif
167         }
168
169         sd->flag = kernel_tex_fetch(__shader_flag, sd->shader & SHADER_MASK);
170
171 #ifdef __DPDU__
172         /* dPdu/dPdv */
173         if(sd->prim == ~0) {
174                 sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
175                 sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
176         }
177         else {
178                 triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim);
179
180 #ifdef __INSTANCING__
181                 if(instanced) {
182                         object_dir_transform(kg, sd->object, &sd->dPdu);
183                         object_dir_transform(kg, sd->object, &sd->dPdv);
184                 }
185 #endif
186         }
187 #endif
188
189         /* backfacing test */
190         if(sd->prim != ~0) {
191                 bool backfacing = (dot(sd->Ng, sd->I) < 0.0f);
192
193                 if(backfacing) {
194                         sd->flag |= SD_BACKFACING;
195                         sd->Ng = -sd->Ng;
196                         sd->N = -sd->N;
197 #ifdef __DPDU__
198                         sd->dPdu = -sd->dPdu;
199                         sd->dPdv = -sd->dPdv;
200 #endif
201                 }
202         }
203
204 #ifdef __RAY_DIFFERENTIALS__
205         /* no ray differentials here yet */
206         sd->dP.dx = make_float3(0.0f, 0.0f, 0.0f);
207         sd->dP.dy = make_float3(0.0f, 0.0f, 0.0f);
208         sd->dI.dx = make_float3(0.0f, 0.0f, 0.0f);
209         sd->dI.dy = make_float3(0.0f, 0.0f, 0.0f);
210         sd->du.dx = 0.0f;
211         sd->du.dy = 0.0f;
212         sd->dv.dx = 0.0f;
213         sd->dv.dy = 0.0f;
214 #endif
215 }
216
217 /* ShaderData setup for displacement */
218
219 __device void shader_setup_from_displace(KernelGlobals *kg, ShaderData *sd,
220         int object, int prim, float u, float v)
221 {
222         float3 P, Ng, I = make_float3(0.0f, 0.0f, 0.0f);
223         int shader;
224
225         P = triangle_point_MT(kg, prim, u, v);
226         Ng = triangle_normal_MT(kg, prim, &shader);
227
228         /* force smooth shading for displacement */
229         shader |= SHADER_SMOOTH_NORMAL;
230
231         /* watch out: no instance transform currently */
232
233         shader_setup_from_sample(kg, sd, P, Ng, I, shader, object, prim, u, v);
234 }
235
236 /* ShaderData setup from ray into background */
237
238 __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData *sd, const Ray *ray)
239 {
240         /* vectors */
241         sd->P = ray->D;
242         sd->N = -sd->P;
243         sd->Ng = -sd->P;
244         sd->I = -sd->P;
245         sd->shader = kernel_data.background.shader;
246         sd->flag = kernel_tex_fetch(__shader_flag, sd->shader & SHADER_MASK);
247
248 #ifdef __INSTANCING__
249         sd->object = ~0;
250 #endif
251         sd->prim = ~0;
252 #ifdef __UV__
253         sd->u = 0.0f;
254         sd->v = 0.0f;
255 #endif
256
257 #ifdef __DPDU__
258         /* dPdu/dPdv */
259         sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
260         sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
261 #endif
262
263 #ifdef __RAY_DIFFERENTIALS__
264         /* differentials */
265         sd->dP = ray->dD;
266         differential_incoming(&sd->dI, sd->dP);
267         sd->du.dx = 0.0f;
268         sd->du.dy = 0.0f;
269         sd->dv.dx = 0.0f;
270         sd->dv.dy = 0.0f;
271 #endif
272 }
273
274 /* BSDF */
275
276 #ifdef __MULTI_CLOSURE__
277
278 __device_inline float3 _shader_bsdf_multi_eval(const ShaderData *sd, const float3 omega_in, float *pdf,
279         int skip_bsdf, float3 sum_eval, float sum_pdf, float sum_sample_weight)
280 {
281         for(int i = 0; i< sd->num_closure; i++) {
282                 if(i == skip_bsdf)
283                         continue;
284
285                 const ShaderClosure *sc = &sd->closure[i];
286
287                 if(CLOSURE_IS_BSDF(sc->type)) {
288                         float bsdf_pdf = 0.0f;
289 #ifdef __OSL__
290                         float3 eval = OSLShader::bsdf_eval(sd, sc, omega_in, bsdf_pdf);
291 #else
292                         float3 eval = svm_bsdf_eval(sd, sc, omega_in, &bsdf_pdf);
293 #endif
294
295                         if(bsdf_pdf != 0.0f) {
296                                 sum_eval += eval*sc->weight;
297                                 sum_pdf += bsdf_pdf*sc->sample_weight;
298                         }
299
300                         sum_sample_weight += sc->sample_weight;
301                 }
302         }
303
304         *pdf = sum_pdf/sum_sample_weight;
305         return sum_eval;
306 }
307
308 #endif
309
310 __device float3 shader_bsdf_eval(KernelGlobals *kg, const ShaderData *sd,
311         const float3 omega_in, float *pdf)
312 {
313 #ifdef __MULTI_CLOSURE__
314         return _shader_bsdf_multi_eval(sd, omega_in, pdf, -1, make_float3(0.0f, 0.0f, 0.0f), 0.0f, 0.0f);
315 #else
316         const ShaderClosure *sc = &sd->closure;
317         *pdf = 0.0f;
318         return svm_bsdf_eval(sd, sc, omega_in, pdf)*sc->weight;
319 #endif
320 }
321
322 __device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd,
323         float randu, float randv, float3 *eval,
324         float3 *omega_in, differential3 *domega_in, float *pdf)
325 {
326 #ifdef __MULTI_CLOSURE__
327         int sampled = 0;
328
329         if(sd->num_closure > 1) {
330                 /* pick a BSDF closure based on sample weights */
331                 float sum = 0.0f;
332
333                 for(sampled = 0; sampled < sd->num_closure; sampled++) {
334                         const ShaderClosure *sc = &sd->closure[sampled];
335                         
336                         if(CLOSURE_IS_BSDF(sc->type))
337                                 sum += sc->sample_weight;
338                 }
339
340                 float r = sd->randb_closure*sum;
341                 sum = 0.0f;
342
343                 for(sampled = 0; sampled < sd->num_closure; sampled++) {
344                         const ShaderClosure *sc = &sd->closure[sampled];
345                         
346                         if(CLOSURE_IS_BSDF(sc->type)) {
347                                 sum += sd->closure[sampled].sample_weight;
348
349                                 if(r <= sum)
350                                         break;
351                         }
352                 }
353
354                 if(sampled == sd->num_closure) {
355                         *pdf = 0.0f;
356                         return LABEL_NONE;
357                 }
358         }
359
360         const ShaderClosure *sc = &sd->closure[sampled];
361         int label;
362
363         *pdf = 0.0f;
364 #ifdef __OSL__
365         label = OSLShader::bsdf_sample(sd, sc, randu, randv, *eval, *omega_in, *domega_in, *pdf);
366 #else
367         label = svm_bsdf_sample(sd, sc, randu, randv, eval, omega_in, domega_in, pdf);
368 #endif
369
370         *eval *= sc->weight;
371
372         if(sd->num_closure > 1 && *pdf != 0.0f) {
373                 float sweight = sc->sample_weight;
374                 *eval = _shader_bsdf_multi_eval(sd, *omega_in, pdf, sampled, *eval, *pdf*sweight, sweight);
375         }
376
377         return label;
378 #else
379         /* sample the single closure that we picked */
380         *pdf = 0.0f;
381         int label = svm_bsdf_sample(sd, &sd->closure, randu, randv, eval, omega_in, domega_in, pdf);
382         *eval *= sd->closure.weight;
383         return label;
384 #endif
385 }
386
387 __device void shader_bsdf_blur(KernelGlobals *kg, ShaderData *sd, float roughness)
388 {
389 #ifndef __OSL__
390 #ifdef __MULTI_CLOSURE__
391         for(int i = 0; i< sd->num_closure; i++) {
392                 ShaderClosure *sc = &sd->closure[i];
393
394                 if(CLOSURE_IS_BSDF(sc->type))
395                         svm_bsdf_blur(sc, roughness);
396         }
397 #else
398         svm_bsdf_blur(&sd->closure, roughness);
399 #endif
400 #endif
401 }
402
403 __device float3 shader_bsdf_transparency(KernelGlobals *kg, ShaderData *sd)
404 {
405 #ifdef __MULTI_CLOSURE__
406         float3 eval = make_float3(0.0f, 0.0f, 0.0f);
407
408         for(int i = 0; i< sd->num_closure; i++) {
409                 ShaderClosure *sc = &sd->closure[i];
410
411                 if(sc->type == CLOSURE_BSDF_TRANSPARENT_ID) // todo: make this work for osl
412                         eval += sc->weight;
413         }
414
415         return eval;
416 #else
417         if(sd->closure.type == CLOSURE_BSDF_TRANSPARENT_ID)
418                 return sd->closure.weight;
419         else
420                 return make_float3(0.0f, 0.0f, 0.0f);
421 #endif
422 }
423
424
425 /* Emission */
426
427 __device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
428 {
429         float3 eval;
430 #ifdef __MULTI_CLOSURE__
431         eval = make_float3(0.0f, 0.0f, 0.0f);
432
433         for(int i = 0; i < sd->num_closure; i++) {
434                 ShaderClosure *sc = &sd->closure[i];
435
436                 if(CLOSURE_IS_EMISSION(sc->type)) {
437 #ifdef __OSL__
438                         eval += OSLShader::emissive_eval(sd)*sc->weight;
439 #else
440                         eval += svm_emissive_eval(sd, sc)*sc->weight;
441 #endif
442                 }
443         }
444 #else
445         eval = svm_emissive_eval(sd, &sd->closure)*sd->closure.weight;
446 #endif
447
448         return eval;
449 }
450
451 /* Holdout */
452
453 __device float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd)
454 {
455 #ifdef __MULTI_CLOSURE__
456         float3 weight = make_float3(0.0f, 0.0f, 0.0f);
457
458         for(int i = 0; i < sd->num_closure; i++) {
459                 ShaderClosure *sc = &sd->closure[i];
460
461                 if(CLOSURE_IS_HOLDOUT(sc->type))
462                         weight += sc->weight;
463         }
464
465         return weight;
466 #else
467         if(sd->closure.type == CLOSURE_HOLDOUT_ID)
468                 return make_float3(1.0f, 1.0f, 1.0f);
469
470         return make_float3(0.0f, 0.0f, 0.0f);
471 #endif
472 }
473
474 /* Surface Evaluation */
475
476 __device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
477         float randb, int path_flag)
478 {
479 #ifdef __OSL__
480         OSLShader::eval_surface(kg, sd, randb, path_flag);
481 #else
482
483 #ifdef __SVM__
484         svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, randb, path_flag);
485 #else
486         bsdf_diffuse_setup(sd, &sd->closure);
487         sd->closure.weight = make_float3(0.8f, 0.8f, 0.8f);
488 #endif
489
490 #endif
491 }
492
493 /* Background Evaluation */
494
495 __device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag)
496 {
497 #ifdef __OSL__
498         return OSLShader::eval_background(kg, sd, path_flag);
499 #else
500
501 #ifdef __SVM__
502         svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, 0.0f, path_flag);
503
504 #ifdef __MULTI_CLOSURE__
505         float3 eval = make_float3(0.0f, 0.0f, 0.0f);
506
507         for(int i = 0; i< sd->num_closure; i++) {
508                 const ShaderClosure *sc = &sd->closure[i];
509
510                 if(CLOSURE_IS_BACKGROUND(sc->type))
511                         eval += sc->weight;
512         }
513
514         return eval;
515 #else
516         if(sd->closure.type == CLOSURE_BACKGROUND_ID)
517                 return sd->closure.weight;
518         else
519                 return make_float3(0.0f, 0.0f, 0.0f);
520 #endif
521
522 #else
523         return make_float3(0.8f, 0.8f, 0.8f);
524 #endif
525
526 #endif
527 }
528
529 /* Volume */
530
531 __device float3 shader_volume_eval_phase(KernelGlobals *kg, ShaderData *sd,
532         float3 omega_in, float3 omega_out)
533 {
534 #ifdef __MULTI_CLOSURE__
535         float3 eval = make_float3(0.0f, 0.0f, 0.0f);
536
537         for(int i = 0; i< sd->num_closure; i++) {
538                 const ShaderClosure *sc = &sd->closure[i];
539
540                 if(CLOSURE_IS_VOLUME(sc->type)) {
541 #ifdef __OSL__
542                         eval += OSLShader::volume_eval_phase(sd, omega_in, omega_out);
543 #else
544                         eval += volume_eval_phase(sd, sc, omega_in, omega_out);
545 #endif
546                 }
547         }
548
549         return eval;
550 #else
551         return volume_eval_phase(sd, &sd->closure, omega_in, omega_out);
552 #endif
553 }
554
555 /* Volume Evaluation */
556
557 __device void shader_eval_volume(KernelGlobals *kg, ShaderData *sd,
558         float randb, int path_flag)
559 {
560 #ifdef __SVM__
561 #ifdef __OSL__
562         OSLShader::eval_volume(kg, sd, randb, path_flag);
563 #else
564         svm_eval_nodes(kg, sd, SHADER_TYPE_VOLUME, randb, path_flag);
565 #endif
566 #endif
567 }
568
569 /* Displacement Evaluation */
570
571 __device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd)
572 {
573         /* this will modify sd->P */
574 #ifdef __SVM__
575 #ifdef __OSL__
576         OSLShader::eval_displacement(kg, sd);
577 #else
578         svm_eval_nodes(kg, sd, SHADER_TYPE_DISPLACEMENT, 0.0f, 0);
579 #endif
580 #endif
581 }
582
583 /* Transparent Shadows */
584
585 #ifdef __TRANSPARENT_SHADOWS__
586 __device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect)
587 {
588         int prim = kernel_tex_fetch(__prim_index, isect->prim);
589         float4 Ns = kernel_tex_fetch(__tri_normal, prim);
590         int shader = __float_as_int(Ns.w);
591         int flag = kernel_tex_fetch(__shader_flag, shader & SHADER_MASK);
592
593         return (flag & SD_HAS_SURFACE_TRANSPARENT) != 0;
594 }
595 #endif
596
597 /* Free ShaderData */
598
599 __device void shader_release(KernelGlobals *kg, ShaderData *sd)
600 {
601 #ifdef __OSL__
602         OSLShader::release(kg, sd);
603 #endif
604 }
605
606 CCL_NAMESPACE_END
607