Cycles: First implementation of shadow catcher
[blender.git] / intern / cycles / kernel / kernel_accumulate.h
1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 CCL_NAMESPACE_BEGIN
18
19 /* BSDF Eval
20  *
21  * BSDF evaluation result, split per BSDF type. This is used to accumulate
22  * render passes separately. */
23
24 ccl_device_inline void bsdf_eval_init(BsdfEval *eval, ClosureType type, float3 value, int use_light_pass)
25 {
26 #ifdef __PASSES__
27         eval->use_light_pass = use_light_pass;
28
29         if(eval->use_light_pass) {
30                 eval->diffuse = make_float3(0.0f, 0.0f, 0.0f);
31                 eval->glossy = make_float3(0.0f, 0.0f, 0.0f);
32                 eval->transmission = make_float3(0.0f, 0.0f, 0.0f);
33                 eval->transparent = make_float3(0.0f, 0.0f, 0.0f);
34                 eval->subsurface = make_float3(0.0f, 0.0f, 0.0f);
35                 eval->scatter = make_float3(0.0f, 0.0f, 0.0f);
36
37                 if(type == CLOSURE_BSDF_TRANSPARENT_ID)
38                         eval->transparent = value;
39                 else if(CLOSURE_IS_BSDF_DIFFUSE(type))
40                         eval->diffuse = value;
41                 else if(CLOSURE_IS_BSDF_GLOSSY(type))
42                         eval->glossy = value;
43                 else if(CLOSURE_IS_BSDF_TRANSMISSION(type))
44                         eval->transmission = value;
45                 else if(CLOSURE_IS_BSDF_BSSRDF(type))
46                         eval->subsurface = value;
47                 else if(CLOSURE_IS_PHASE(type))
48                         eval->scatter = value;
49         }
50         else
51 #endif
52         {
53                 eval->diffuse = value;
54         }
55 #ifdef __SHADOW_TRICKS__
56         eval->sum_no_mis = make_float3(0.0f, 0.0f, 0.0f);
57 #endif
58 }
59
60 ccl_device_inline void bsdf_eval_accum(BsdfEval *eval, ClosureType type, float3 value, float mis_weight)
61 {
62 #ifdef __SHADOW_TRICKS__
63         eval->sum_no_mis += value;
64 #endif
65         value *= mis_weight;
66 #ifdef __PASSES__
67         if(eval->use_light_pass) {
68                 if(CLOSURE_IS_BSDF_DIFFUSE(type))
69                         eval->diffuse += value;
70                 else if(CLOSURE_IS_BSDF_GLOSSY(type))
71                         eval->glossy += value;
72                 else if(CLOSURE_IS_BSDF_TRANSMISSION(type))
73                         eval->transmission += value;
74                 else if(CLOSURE_IS_BSDF_BSSRDF(type))
75                         eval->subsurface += value;
76                 else if(CLOSURE_IS_PHASE(type))
77                         eval->scatter += value;
78
79                 /* skipping transparent, this function is used by for eval(), will be zero then */
80         }
81         else
82 #endif
83         {
84                 eval->diffuse += value;
85         }
86 }
87
88 ccl_device_inline bool bsdf_eval_is_zero(BsdfEval *eval)
89 {
90 #ifdef __PASSES__
91         if(eval->use_light_pass) {
92                 return is_zero(eval->diffuse)
93                         && is_zero(eval->glossy)
94                         && is_zero(eval->transmission)
95                         && is_zero(eval->transparent)
96                         && is_zero(eval->subsurface)
97                         && is_zero(eval->scatter);
98         }
99         else
100 #endif
101         {
102                 return is_zero(eval->diffuse);
103         }
104 }
105
106 ccl_device_inline void bsdf_eval_mis(BsdfEval *eval, float value)
107 {
108 #ifdef __PASSES__
109         if(eval->use_light_pass) {
110                 eval->diffuse *= value;
111                 eval->glossy *= value;
112                 eval->transmission *= value;
113                 eval->subsurface *= value;
114                 eval->scatter *= value;
115
116                 /* skipping transparent, this function is used by for eval(), will be zero then */
117         }
118         else
119 #endif
120         {
121                 eval->diffuse *= value;
122         }
123 }
124
125 ccl_device_inline void bsdf_eval_mul(BsdfEval *eval, float value)
126 {
127 #ifdef __SHADOW_TRICKS__
128         eval->sum_no_mis *= value;
129 #endif
130         bsdf_eval_mis(eval, value);
131 }
132
133 ccl_device_inline void bsdf_eval_mul3(BsdfEval *eval, float3 value)
134 {
135 #ifdef __SHADOW_TRICKS__
136         eval->sum_no_mis *= value;
137 #endif
138 #ifdef __PASSES__
139         if(eval->use_light_pass) {
140                 eval->diffuse *= value;
141                 eval->glossy *= value;
142                 eval->transmission *= value;
143                 eval->subsurface *= value;
144                 eval->scatter *= value;
145
146                 /* skipping transparent, this function is used by for eval(), will be zero then */
147         }
148         else
149                 eval->diffuse *= value;
150 #else
151         eval->diffuse *= value;
152 #endif
153 }
154
155 ccl_device_inline float3 bsdf_eval_sum(const BsdfEval *eval)
156 {
157 #ifdef __PASSES__
158         if(eval->use_light_pass) {
159                 return eval->diffuse + eval->glossy + eval->transmission + eval->subsurface + eval->scatter;
160         }
161         else
162 #endif
163         return eval->diffuse;
164 }
165
166 /* Path Radiance
167  *
168  * We accumulate different render passes separately. After summing at the end
169  * to get the combined result, it should be identical. We definite directly
170  * visible as the first non-transparent hit, while indirectly visible are the
171  * bounces after that. */
172
173 ccl_device_inline void path_radiance_init(PathRadiance *L, int use_light_pass)
174 {
175         /* clear all */
176 #ifdef __PASSES__
177         L->use_light_pass = use_light_pass;
178
179         if(use_light_pass) {
180                 L->indirect = make_float3(0.0f, 0.0f, 0.0f);
181                 L->direct_throughput = make_float3(0.0f, 0.0f, 0.0f);
182                 L->direct_emission = make_float3(0.0f, 0.0f, 0.0f);
183
184                 L->color_diffuse = make_float3(0.0f, 0.0f, 0.0f);
185                 L->color_glossy = make_float3(0.0f, 0.0f, 0.0f);
186                 L->color_transmission = make_float3(0.0f, 0.0f, 0.0f);
187                 L->color_subsurface = make_float3(0.0f, 0.0f, 0.0f);
188                 L->color_scatter = make_float3(0.0f, 0.0f, 0.0f);
189
190                 L->direct_diffuse = make_float3(0.0f, 0.0f, 0.0f);
191                 L->direct_glossy = make_float3(0.0f, 0.0f, 0.0f);
192                 L->direct_transmission = make_float3(0.0f, 0.0f, 0.0f);
193                 L->direct_subsurface = make_float3(0.0f, 0.0f, 0.0f);
194                 L->direct_scatter = make_float3(0.0f, 0.0f, 0.0f);
195
196                 L->indirect_diffuse = make_float3(0.0f, 0.0f, 0.0f);
197                 L->indirect_glossy = make_float3(0.0f, 0.0f, 0.0f);
198                 L->indirect_transmission = make_float3(0.0f, 0.0f, 0.0f);
199                 L->indirect_subsurface = make_float3(0.0f, 0.0f, 0.0f);
200                 L->indirect_scatter = make_float3(0.0f, 0.0f, 0.0f);
201
202                 L->path_diffuse = make_float3(0.0f, 0.0f, 0.0f);
203                 L->path_glossy = make_float3(0.0f, 0.0f, 0.0f);
204                 L->path_transmission = make_float3(0.0f, 0.0f, 0.0f);
205                 L->path_subsurface = make_float3(0.0f, 0.0f, 0.0f);
206                 L->path_scatter = make_float3(0.0f, 0.0f, 0.0f);
207
208                 L->emission = make_float3(0.0f, 0.0f, 0.0f);
209                 L->background = make_float3(0.0f, 0.0f, 0.0f);
210                 L->ao = make_float3(0.0f, 0.0f, 0.0f);
211                 L->shadow = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
212                 L->mist = 0.0f;
213         }
214         else
215 #endif
216         {
217                 L->emission = make_float3(0.0f, 0.0f, 0.0f);
218         }
219
220 #ifdef __SHADOW_TRICKS__
221         L->path_total = make_float3(0.0f, 0.0f, 0.0f);
222         L->path_total_shaded = make_float3(0.0f, 0.0f, 0.0f);
223         L->shadow_color = make_float3(0.0f, 0.0f, 0.0f);
224 #endif
225 }
226
227 ccl_device_inline void path_radiance_bsdf_bounce(PathRadiance *L, ccl_addr_space float3 *throughput,
228         BsdfEval *bsdf_eval, float bsdf_pdf, int bounce, int bsdf_label)
229 {
230         float inverse_pdf = 1.0f/bsdf_pdf;
231
232 #ifdef __PASSES__
233         if(L->use_light_pass) {
234                 if(bounce == 0 && !(bsdf_label & LABEL_TRANSPARENT)) {
235                         /* first on directly visible surface */
236                         float3 value = *throughput*inverse_pdf;
237
238                         L->path_diffuse = bsdf_eval->diffuse*value;
239                         L->path_glossy = bsdf_eval->glossy*value;
240                         L->path_transmission = bsdf_eval->transmission*value;
241                         L->path_subsurface = bsdf_eval->subsurface*value;
242                         L->path_scatter = bsdf_eval->scatter*value;
243
244                         *throughput = L->path_diffuse + L->path_glossy + L->path_transmission + L->path_subsurface + L->path_scatter;
245                         
246                         L->direct_throughput = *throughput;
247                 }
248                 else {
249                         /* transparent bounce before first hit, or indirectly visible through BSDF */
250                         float3 sum = (bsdf_eval_sum(bsdf_eval) + bsdf_eval->transparent) * inverse_pdf;
251                         *throughput *= sum;
252                 }
253         }
254         else
255 #endif
256         {
257                 *throughput *= bsdf_eval->diffuse*inverse_pdf;
258         }
259 }
260
261 ccl_device_inline void path_radiance_accum_emission(PathRadiance *L, float3 throughput, float3 value, int bounce)
262 {
263 #ifdef __PASSES__
264         if(L->use_light_pass) {
265                 if(bounce == 0)
266                         L->emission += throughput*value;
267                 else if(bounce == 1)
268                         L->direct_emission += throughput*value;
269                 else
270                         L->indirect += throughput*value;
271         }
272         else
273 #endif
274         {
275                 L->emission += throughput*value;
276         }
277 }
278
279 ccl_device_inline void path_radiance_accum_ao(PathRadiance *L,
280                                               float3 throughput,
281                                               float3 alpha,
282                                               float3 bsdf,
283                                               float3 ao,
284                                               int bounce)
285 {
286 #ifdef __PASSES__
287         if(L->use_light_pass) {
288                 if(bounce == 0) {
289                         /* directly visible lighting */
290                         L->direct_diffuse += throughput*bsdf*ao;
291                         L->ao += alpha*throughput*ao;
292                 }
293                 else {
294                         /* indirectly visible lighting after BSDF bounce */
295                         L->indirect += throughput*bsdf*ao;
296                 }
297         }
298         else
299 #endif
300         {
301                 L->emission += throughput*bsdf*ao;
302         }
303
304 #ifdef __SHADOW_TRICKS__
305         float3 light = throughput * bsdf;
306         L->path_total += light;
307         L->path_total_shaded += ao * light;
308 #endif
309 }
310
311 ccl_device_inline void path_radiance_accum_total_ao(
312         PathRadiance *L,
313         float3 throughput,
314         float3 bsdf)
315 {
316 #ifdef __SHADOW_TRICKS__
317         L->path_total += throughput * bsdf;
318 #else
319         (void) L;
320         (void) throughput;
321         (void) bsdf;
322 #endif
323 }
324
325 ccl_device_inline void path_radiance_accum_light(PathRadiance *L, float3 throughput, BsdfEval *bsdf_eval, float3 shadow, float shadow_fac, int bounce, bool is_lamp)
326 {
327 #ifdef __PASSES__
328         if(L->use_light_pass) {
329                 if(bounce == 0) {
330                         /* directly visible lighting */
331                         L->direct_diffuse += throughput*bsdf_eval->diffuse*shadow;
332                         L->direct_glossy += throughput*bsdf_eval->glossy*shadow;
333                         L->direct_transmission += throughput*bsdf_eval->transmission*shadow;
334                         L->direct_subsurface += throughput*bsdf_eval->subsurface*shadow;
335                         L->direct_scatter += throughput*bsdf_eval->scatter*shadow;
336
337                         if(is_lamp) {
338                                 L->shadow.x += shadow.x*shadow_fac;
339                                 L->shadow.y += shadow.y*shadow_fac;
340                                 L->shadow.z += shadow.z*shadow_fac;
341                         }
342                 }
343                 else {
344                         /* indirectly visible lighting after BSDF bounce */
345                         L->indirect += throughput*bsdf_eval_sum(bsdf_eval)*shadow;
346                 }
347         }
348         else
349 #endif
350         {
351                 L->emission += throughput*bsdf_eval->diffuse*shadow;
352         }
353
354 #ifdef __SHADOW_TRICKS__
355         float3 light = throughput * bsdf_eval->sum_no_mis;
356         L->path_total += light;
357         L->path_total_shaded += shadow * light;
358 #endif
359 }
360
361 ccl_device_inline void path_radiance_accum_total_light(
362         PathRadiance *L,
363         float3 throughput,
364         const BsdfEval *bsdf_eval)
365 {
366 #ifdef __SHADOW_TRICKS__
367         L->path_total += throughput * bsdf_eval->sum_no_mis;
368 #else
369         (void) L;
370         (void) throughput;
371         (void) bsdf_eval;
372 #endif
373 }
374
375 ccl_device_inline void path_radiance_accum_background(PathRadiance *L,
376                                                       ccl_addr_space PathState *state,
377                                                       float3 throughput,
378                                                       float3 value)
379 {
380 #ifdef __PASSES__
381         if(L->use_light_pass) {
382                 if(state->bounce == 0)
383                         L->background += throughput*value;
384                 else if(state->bounce == 1)
385                         L->direct_emission += throughput*value;
386                 else
387                         L->indirect += throughput*value;
388         }
389         else
390 #endif
391         {
392                 L->emission += throughput*value;
393         }
394
395 #ifdef __SHADOW_TRICKS__
396         L->path_total += throughput * value;
397         if(state->flag & PATH_RAY_SHADOW_CATCHER_ONLY) {
398                 L->path_total_shaded += throughput * value;
399         }
400 #endif
401 }
402
403 ccl_device_inline void path_radiance_sum_indirect(PathRadiance *L)
404 {
405 #ifdef __PASSES__
406         /* this division is a bit ugly, but means we only have to keep track of
407          * only a single throughput further along the path, here we recover just
408          * the indirect path that is not influenced by any particular BSDF type */
409         if(L->use_light_pass) {
410                 L->direct_emission = safe_divide_color(L->direct_emission, L->direct_throughput);
411                 L->direct_diffuse += L->path_diffuse*L->direct_emission;
412                 L->direct_glossy += L->path_glossy*L->direct_emission;
413                 L->direct_transmission += L->path_transmission*L->direct_emission;
414                 L->direct_subsurface += L->path_subsurface*L->direct_emission;
415                 L->direct_scatter += L->path_scatter*L->direct_emission;
416
417                 L->indirect = safe_divide_color(L->indirect, L->direct_throughput);
418                 L->indirect_diffuse += L->path_diffuse*L->indirect;
419                 L->indirect_glossy += L->path_glossy*L->indirect;
420                 L->indirect_transmission += L->path_transmission*L->indirect;
421                 L->indirect_subsurface += L->path_subsurface*L->indirect;
422                 L->indirect_scatter += L->path_scatter*L->indirect;
423         }
424 #endif
425 }
426
427 ccl_device_inline void path_radiance_reset_indirect(PathRadiance *L)
428 {
429 #ifdef __PASSES__
430         if(L->use_light_pass) {
431                 L->path_diffuse = make_float3(0.0f, 0.0f, 0.0f);
432                 L->path_glossy = make_float3(0.0f, 0.0f, 0.0f);
433                 L->path_transmission = make_float3(0.0f, 0.0f, 0.0f);
434                 L->path_subsurface = make_float3(0.0f, 0.0f, 0.0f);
435                 L->path_scatter = make_float3(0.0f, 0.0f, 0.0f);
436
437                 L->direct_emission = make_float3(0.0f, 0.0f, 0.0f);
438                 L->indirect = make_float3(0.0f, 0.0f, 0.0f);
439         }
440 #endif
441 }
442
443 ccl_device_inline void path_radiance_copy_indirect(PathRadiance *L,
444                                                    const PathRadiance *L_src)
445 {
446 #ifdef __PASSES__
447         if(L->use_light_pass) {
448                 L->path_diffuse = L_src->path_diffuse;
449                 L->path_glossy = L_src->path_glossy;
450                 L->path_transmission = L_src->path_transmission;
451                 L->path_subsurface = L_src->path_subsurface;
452                 L->path_scatter = L_src->path_scatter;
453
454                 L->direct_emission = L_src->direct_emission;
455                 L->indirect = L_src->indirect;
456         }
457 #endif
458 }
459
460 ccl_device_inline float3 path_radiance_clamp_and_sum(KernelGlobals *kg, PathRadiance *L)
461 {
462         float3 L_sum;
463         /* Light Passes are used */
464 #ifdef __PASSES__
465         float3 L_direct, L_indirect;
466         float clamp_direct = kernel_data.integrator.sample_clamp_direct;
467         float clamp_indirect = kernel_data.integrator.sample_clamp_indirect;
468         if(L->use_light_pass) {
469                 path_radiance_sum_indirect(L);
470
471                 L_direct = L->direct_diffuse + L->direct_glossy + L->direct_transmission + L->direct_subsurface + L->direct_scatter + L->emission;
472                 L_indirect = L->indirect_diffuse + L->indirect_glossy + L->indirect_transmission + L->indirect_subsurface + L->indirect_scatter;
473
474                 if(!kernel_data.background.transparent)
475                         L_direct += L->background;
476
477                 L_sum = L_direct + L_indirect;
478                 float sum = fabsf((L_sum).x) + fabsf((L_sum).y) + fabsf((L_sum).z);
479
480                 /* Reject invalid value */
481                 if(!isfinite_safe(sum)) {
482                         kernel_assert(!"Non-finite sum in path_radiance_clamp_and_sum!");
483                         L_sum = make_float3(0.0f, 0.0f, 0.0f);
484
485                         L->direct_diffuse = make_float3(0.0f, 0.0f, 0.0f);
486                         L->direct_glossy = make_float3(0.0f, 0.0f, 0.0f);
487                         L->direct_transmission = make_float3(0.0f, 0.0f, 0.0f);
488                         L->direct_subsurface = make_float3(0.0f, 0.0f, 0.0f);
489                         L->direct_scatter = make_float3(0.0f, 0.0f, 0.0f);
490
491                         L->indirect_diffuse = make_float3(0.0f, 0.0f, 0.0f);
492                         L->indirect_glossy = make_float3(0.0f, 0.0f, 0.0f);
493                         L->indirect_transmission = make_float3(0.0f, 0.0f, 0.0f);
494                         L->indirect_subsurface = make_float3(0.0f, 0.0f, 0.0f);
495                         L->indirect_scatter = make_float3(0.0f, 0.0f, 0.0f);
496
497                         L->emission = make_float3(0.0f, 0.0f, 0.0f);
498                 }
499
500                 /* Clamp direct and indirect samples */
501 #ifdef __CLAMP_SAMPLE__
502                 else if(sum > clamp_direct || sum > clamp_indirect) {
503                         float scale;
504
505                         /* Direct */
506                         float sum_direct = fabsf(L_direct.x) + fabsf(L_direct.y) + fabsf(L_direct.z);
507                         if(sum_direct > clamp_direct) {
508                                 scale = clamp_direct/sum_direct;
509                                 L_direct *= scale;
510
511                                 L->direct_diffuse *= scale;
512                                 L->direct_glossy *= scale;
513                                 L->direct_transmission *= scale;
514                                 L->direct_subsurface *= scale;
515                                 L->direct_scatter *= scale;
516                                 L->emission *= scale;
517                                 L->background *= scale;
518                         }
519
520                         /* Indirect */
521                         float sum_indirect = fabsf(L_indirect.x) + fabsf(L_indirect.y) + fabsf(L_indirect.z);
522                         if(sum_indirect > clamp_indirect) {
523                                 scale = clamp_indirect/sum_indirect;
524                                 L_indirect *= scale;
525
526                                 L->indirect_diffuse *= scale;
527                                 L->indirect_glossy *= scale;
528                                 L->indirect_transmission *= scale;
529                                 L->indirect_subsurface *= scale;
530                                 L->indirect_scatter *= scale;
531                         }
532
533                         /* Sum again, after clamping */
534                         L_sum = L_direct + L_indirect;
535                 }
536 #endif
537
538                 return L_sum;
539         }
540
541         /* No Light Passes */
542         else
543 #endif
544         {
545                 L_sum = L->emission;
546         }
547
548         /* Reject invalid value */
549         float sum = fabsf((L_sum).x) + fabsf((L_sum).y) + fabsf((L_sum).z);
550         if(!isfinite_safe(sum)) {
551                 kernel_assert(!"Non-finite final sum in path_radiance_clamp_and_sum!");
552                 L_sum = make_float3(0.0f, 0.0f, 0.0f);
553         }
554
555         return L_sum;
556 }
557
558 ccl_device_inline void path_radiance_accum_sample(PathRadiance *L, PathRadiance *L_sample, int num_samples)
559 {
560         float fac = 1.0f/num_samples;
561
562 #ifdef __PASSES__
563         L->direct_diffuse += L_sample->direct_diffuse*fac;
564         L->direct_glossy += L_sample->direct_glossy*fac;
565         L->direct_transmission += L_sample->direct_transmission*fac;
566         L->direct_subsurface += L_sample->direct_subsurface*fac;
567         L->direct_scatter += L_sample->direct_scatter*fac;
568
569         L->indirect_diffuse += L_sample->indirect_diffuse*fac;
570         L->indirect_glossy += L_sample->indirect_glossy*fac;
571         L->indirect_transmission += L_sample->indirect_transmission*fac;
572         L->indirect_subsurface += L_sample->indirect_subsurface*fac;
573         L->indirect_scatter += L_sample->indirect_scatter*fac;
574
575         L->background += L_sample->background*fac;
576         L->ao += L_sample->ao*fac;
577         L->shadow += L_sample->shadow*fac;
578         L->mist += L_sample->mist*fac;
579 #endif
580         L->emission += L_sample->emission * fac;
581 }
582
583 #ifdef __SHADOW_TRICKS__
584 /* Calculate current shadow of the path. */
585 ccl_device_inline float path_radiance_sum_shadow(const PathRadiance *L)
586 {
587         float path_total = average(L->path_total);
588         float path_total_shaded = average(L->path_total_shaded);
589         if(path_total != 0.0f) {
590                 return path_total_shaded / path_total;
591         }
592         return 1.0f;
593 }
594
595 /* Calculate final light sum and transparency for shadow catcher object. */
596 ccl_device_inline float3 path_radiance_sum_shadowcatcher(KernelGlobals *kg,
597                                                          const PathRadiance *L,
598                                                          ccl_addr_space float* L_transparent)
599 {
600         const float shadow = path_radiance_sum_shadow(L);
601         float3 L_sum;
602         if(kernel_data.background.transparent) {
603                 *L_transparent = shadow;
604                 L_sum = make_float3(0.0f, 0.0f, 0.0f);
605         }
606         else {
607                 L_sum = L->shadow_color * shadow;
608         }
609         return L_sum;
610 }
611 #endif
612
613 CCL_NAMESPACE_END