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