Merge branch 'master' into blender2.8
[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 #ifdef __DENOISING_FEATURES__
227         L->denoising_normal = make_float3(0.0f, 0.0f, 0.0f);
228         L->denoising_albedo = make_float3(0.0f, 0.0f, 0.0f);
229         L->denoising_depth = 0.0f;
230 #endif  /* __DENOISING_FEATURES__ */
231 }
232
233 ccl_device_inline void path_radiance_bsdf_bounce(PathRadiance *L, ccl_addr_space float3 *throughput,
234         BsdfEval *bsdf_eval, float bsdf_pdf, int bounce, int bsdf_label)
235 {
236         float inverse_pdf = 1.0f/bsdf_pdf;
237
238 #ifdef __PASSES__
239         if(L->use_light_pass) {
240                 if(bounce == 0 && !(bsdf_label & LABEL_TRANSPARENT)) {
241                         /* first on directly visible surface */
242                         float3 value = *throughput*inverse_pdf;
243
244                         L->path_diffuse = bsdf_eval->diffuse*value;
245                         L->path_glossy = bsdf_eval->glossy*value;
246                         L->path_transmission = bsdf_eval->transmission*value;
247                         L->path_subsurface = bsdf_eval->subsurface*value;
248                         L->path_scatter = bsdf_eval->scatter*value;
249
250                         *throughput = L->path_diffuse + L->path_glossy + L->path_transmission + L->path_subsurface + L->path_scatter;
251                         
252                         L->direct_throughput = *throughput;
253                 }
254                 else {
255                         /* transparent bounce before first hit, or indirectly visible through BSDF */
256                         float3 sum = (bsdf_eval_sum(bsdf_eval) + bsdf_eval->transparent) * inverse_pdf;
257                         *throughput *= sum;
258                 }
259         }
260         else
261 #endif
262         {
263                 *throughput *= bsdf_eval->diffuse*inverse_pdf;
264         }
265 }
266
267 ccl_device_inline void path_radiance_accum_emission(PathRadiance *L, float3 throughput, float3 value, int bounce)
268 {
269 #ifdef __PASSES__
270         if(L->use_light_pass) {
271                 if(bounce == 0)
272                         L->emission += throughput*value;
273                 else if(bounce == 1)
274                         L->direct_emission += throughput*value;
275                 else
276                         L->indirect += throughput*value;
277         }
278         else
279 #endif
280         {
281                 L->emission += throughput*value;
282         }
283 }
284
285 ccl_device_inline void path_radiance_accum_ao(PathRadiance *L,
286                                               ccl_addr_space PathState *state,
287                                               float3 throughput,
288                                               float3 alpha,
289                                               float3 bsdf,
290                                               float3 ao)
291 {
292 #ifdef __PASSES__
293         if(L->use_light_pass) {
294                 if(state->bounce == 0) {
295                         /* directly visible lighting */
296                         L->direct_diffuse += throughput*bsdf*ao;
297                         L->ao += alpha*throughput*ao;
298                 }
299                 else {
300                         /* indirectly visible lighting after BSDF bounce */
301                         L->indirect += throughput*bsdf*ao;
302                 }
303         }
304         else
305 #endif
306         {
307                 L->emission += throughput*bsdf*ao;
308         }
309
310 #ifdef __SHADOW_TRICKS__
311         if(state->flag & PATH_RAY_STORE_SHADOW_INFO) {
312                 float3 light = throughput * bsdf;
313                 L->path_total += light;
314                 L->path_total_shaded += ao * light;
315         }
316 #endif
317 }
318
319 ccl_device_inline void path_radiance_accum_total_ao(
320         PathRadiance *L,
321         ccl_addr_space PathState *state,
322         float3 throughput,
323         float3 bsdf)
324 {
325 #ifdef __SHADOW_TRICKS__
326         if(state->flag & PATH_RAY_STORE_SHADOW_INFO) {
327                 L->path_total += throughput * bsdf;
328         }
329 #else
330         (void) L;
331         (void) state;
332         (void) throughput;
333         (void) bsdf;
334 #endif
335 }
336
337 ccl_device_inline void path_radiance_accum_light(PathRadiance *L,
338                                                  ccl_addr_space PathState *state,
339                                                  float3 throughput,
340                                                  BsdfEval *bsdf_eval,
341                                                  float3 shadow,
342                                                  float shadow_fac,
343                                                  bool is_lamp)
344 {
345 #ifdef __PASSES__
346         if(L->use_light_pass) {
347                 if(state->bounce == 0) {
348                         /* directly visible lighting */
349                         L->direct_diffuse += throughput*bsdf_eval->diffuse*shadow;
350                         L->direct_glossy += throughput*bsdf_eval->glossy*shadow;
351                         L->direct_transmission += throughput*bsdf_eval->transmission*shadow;
352                         L->direct_subsurface += throughput*bsdf_eval->subsurface*shadow;
353                         L->direct_scatter += throughput*bsdf_eval->scatter*shadow;
354
355                         if(is_lamp) {
356                                 L->shadow.x += shadow.x*shadow_fac;
357                                 L->shadow.y += shadow.y*shadow_fac;
358                                 L->shadow.z += shadow.z*shadow_fac;
359                         }
360                 }
361                 else {
362                         /* indirectly visible lighting after BSDF bounce */
363                         L->indirect += throughput*bsdf_eval_sum(bsdf_eval)*shadow;
364                 }
365         }
366         else
367 #endif
368         {
369                 L->emission += throughput*bsdf_eval->diffuse*shadow;
370         }
371
372 #ifdef __SHADOW_TRICKS__
373         if(state->flag & PATH_RAY_STORE_SHADOW_INFO) {
374                 float3 light = throughput * bsdf_eval->sum_no_mis;
375                 L->path_total += light;
376                 L->path_total_shaded += shadow * light;
377         }
378 #endif
379 }
380
381 ccl_device_inline void path_radiance_accum_total_light(
382         PathRadiance *L,
383         ccl_addr_space PathState *state,
384         float3 throughput,
385         const BsdfEval *bsdf_eval)
386 {
387 #ifdef __SHADOW_TRICKS__
388         if(state->flag & PATH_RAY_STORE_SHADOW_INFO) {
389                 L->path_total += throughput * bsdf_eval->sum_no_mis;
390         }
391 #else
392         (void) L;
393         (void) state;
394         (void) throughput;
395         (void) bsdf_eval;
396 #endif
397 }
398
399 ccl_device_inline void path_radiance_accum_background(PathRadiance *L,
400                                                       ccl_addr_space PathState *state,
401                                                       float3 throughput,
402                                                       float3 value)
403 {
404 #ifdef __PASSES__
405         if(L->use_light_pass) {
406                 if(state->bounce == 0)
407                         L->background += throughput*value;
408                 else if(state->bounce == 1)
409                         L->direct_emission += throughput*value;
410                 else
411                         L->indirect += throughput*value;
412         }
413         else
414 #endif
415         {
416                 L->emission += throughput*value;
417         }
418
419 #ifdef __SHADOW_TRICKS__
420         if(state->flag & PATH_RAY_STORE_SHADOW_INFO) {
421                 L->path_total += throughput * value;
422                 if(state->flag & PATH_RAY_SHADOW_CATCHER_ONLY) {
423                         L->path_total_shaded += throughput * value;
424                 }
425         }
426 #endif
427
428 #ifdef __DENOISING_FEATURES__
429         L->denoising_albedo += state->denoising_feature_weight * value;
430 #endif  /* __DENOISING_FEATURES__ */
431 }
432
433 ccl_device_inline void path_radiance_sum_indirect(PathRadiance *L)
434 {
435 #ifdef __PASSES__
436         /* this division is a bit ugly, but means we only have to keep track of
437          * only a single throughput further along the path, here we recover just
438          * the indirect path that is not influenced by any particular BSDF type */
439         if(L->use_light_pass) {
440                 L->direct_emission = safe_divide_color(L->direct_emission, L->direct_throughput);
441                 L->direct_diffuse += L->path_diffuse*L->direct_emission;
442                 L->direct_glossy += L->path_glossy*L->direct_emission;
443                 L->direct_transmission += L->path_transmission*L->direct_emission;
444                 L->direct_subsurface += L->path_subsurface*L->direct_emission;
445                 L->direct_scatter += L->path_scatter*L->direct_emission;
446
447                 L->indirect = safe_divide_color(L->indirect, L->direct_throughput);
448                 L->indirect_diffuse += L->path_diffuse*L->indirect;
449                 L->indirect_glossy += L->path_glossy*L->indirect;
450                 L->indirect_transmission += L->path_transmission*L->indirect;
451                 L->indirect_subsurface += L->path_subsurface*L->indirect;
452                 L->indirect_scatter += L->path_scatter*L->indirect;
453         }
454 #endif
455 }
456
457 ccl_device_inline void path_radiance_reset_indirect(PathRadiance *L)
458 {
459 #ifdef __PASSES__
460         if(L->use_light_pass) {
461                 L->path_diffuse = make_float3(0.0f, 0.0f, 0.0f);
462                 L->path_glossy = make_float3(0.0f, 0.0f, 0.0f);
463                 L->path_transmission = make_float3(0.0f, 0.0f, 0.0f);
464                 L->path_subsurface = make_float3(0.0f, 0.0f, 0.0f);
465                 L->path_scatter = make_float3(0.0f, 0.0f, 0.0f);
466
467                 L->direct_emission = make_float3(0.0f, 0.0f, 0.0f);
468                 L->indirect = make_float3(0.0f, 0.0f, 0.0f);
469         }
470 #endif
471 }
472
473 ccl_device_inline void path_radiance_copy_indirect(PathRadiance *L,
474                                                    const PathRadiance *L_src)
475 {
476 #ifdef __PASSES__
477         if(L->use_light_pass) {
478                 L->path_diffuse = L_src->path_diffuse;
479                 L->path_glossy = L_src->path_glossy;
480                 L->path_transmission = L_src->path_transmission;
481                 L->path_subsurface = L_src->path_subsurface;
482                 L->path_scatter = L_src->path_scatter;
483
484                 L->direct_emission = L_src->direct_emission;
485                 L->indirect = L_src->indirect;
486         }
487 #endif
488 }
489
490 ccl_device_inline float3 path_radiance_clamp_and_sum(KernelGlobals *kg, PathRadiance *L)
491 {
492         float3 L_sum;
493         /* Light Passes are used */
494 #ifdef __PASSES__
495         float3 L_direct, L_indirect;
496         float clamp_direct = kernel_data.integrator.sample_clamp_direct;
497         float clamp_indirect = kernel_data.integrator.sample_clamp_indirect;
498         if(L->use_light_pass) {
499                 path_radiance_sum_indirect(L);
500
501                 L_direct = L->direct_diffuse + L->direct_glossy + L->direct_transmission + L->direct_subsurface + L->direct_scatter + L->emission;
502                 L_indirect = L->indirect_diffuse + L->indirect_glossy + L->indirect_transmission + L->indirect_subsurface + L->indirect_scatter;
503
504                 if(!kernel_data.background.transparent)
505                         L_direct += L->background;
506
507                 L_sum = L_direct + L_indirect;
508                 float sum = fabsf((L_sum).x) + fabsf((L_sum).y) + fabsf((L_sum).z);
509
510                 /* Reject invalid value */
511                 if(!isfinite_safe(sum)) {
512                         kernel_assert(!"Non-finite sum in path_radiance_clamp_and_sum!");
513                         L_sum = make_float3(0.0f, 0.0f, 0.0f);
514
515                         L->direct_diffuse = make_float3(0.0f, 0.0f, 0.0f);
516                         L->direct_glossy = make_float3(0.0f, 0.0f, 0.0f);
517                         L->direct_transmission = make_float3(0.0f, 0.0f, 0.0f);
518                         L->direct_subsurface = make_float3(0.0f, 0.0f, 0.0f);
519                         L->direct_scatter = make_float3(0.0f, 0.0f, 0.0f);
520
521                         L->indirect_diffuse = make_float3(0.0f, 0.0f, 0.0f);
522                         L->indirect_glossy = make_float3(0.0f, 0.0f, 0.0f);
523                         L->indirect_transmission = make_float3(0.0f, 0.0f, 0.0f);
524                         L->indirect_subsurface = make_float3(0.0f, 0.0f, 0.0f);
525                         L->indirect_scatter = make_float3(0.0f, 0.0f, 0.0f);
526
527                         L->emission = make_float3(0.0f, 0.0f, 0.0f);
528                 }
529
530                 /* Clamp direct and indirect samples */
531 #ifdef __CLAMP_SAMPLE__
532                 else if(sum > clamp_direct || sum > clamp_indirect) {
533                         float scale;
534
535                         /* Direct */
536                         float sum_direct = fabsf(L_direct.x) + fabsf(L_direct.y) + fabsf(L_direct.z);
537                         if(sum_direct > clamp_direct) {
538                                 scale = clamp_direct/sum_direct;
539                                 L_direct *= scale;
540
541                                 L->direct_diffuse *= scale;
542                                 L->direct_glossy *= scale;
543                                 L->direct_transmission *= scale;
544                                 L->direct_subsurface *= scale;
545                                 L->direct_scatter *= scale;
546                                 L->emission *= scale;
547                                 L->background *= scale;
548                         }
549
550                         /* Indirect */
551                         float sum_indirect = fabsf(L_indirect.x) + fabsf(L_indirect.y) + fabsf(L_indirect.z);
552                         if(sum_indirect > clamp_indirect) {
553                                 scale = clamp_indirect/sum_indirect;
554                                 L_indirect *= scale;
555
556                                 L->indirect_diffuse *= scale;
557                                 L->indirect_glossy *= scale;
558                                 L->indirect_transmission *= scale;
559                                 L->indirect_subsurface *= scale;
560                                 L->indirect_scatter *= scale;
561                         }
562
563                         /* Sum again, after clamping */
564                         L_sum = L_direct + L_indirect;
565                 }
566 #endif
567
568                 return L_sum;
569         }
570
571         /* No Light Passes */
572         else
573 #endif
574         {
575                 L_sum = L->emission;
576         }
577
578         /* Reject invalid value */
579         float sum = fabsf((L_sum).x) + fabsf((L_sum).y) + fabsf((L_sum).z);
580         if(!isfinite_safe(sum)) {
581                 kernel_assert(!"Non-finite final sum in path_radiance_clamp_and_sum!");
582                 L_sum = make_float3(0.0f, 0.0f, 0.0f);
583         }
584
585         return L_sum;
586 }
587
588 ccl_device_inline void path_radiance_split_denoising(KernelGlobals *kg, PathRadiance *L, float3 *noisy, float3 *clean)
589 {
590 #ifdef __PASSES__
591         kernel_assert(L->use_light_pass);
592
593         *clean = L->emission + L->background;
594         *noisy = L->direct_scatter + L->indirect_scatter;
595
596 #  define ADD_COMPONENT(flag, component)     \
597         if(kernel_data.film.denoising_flags & flag) \
598                 *clean += component;                 \
599         else                                     \
600                 *noisy += component;
601
602         ADD_COMPONENT(DENOISING_CLEAN_DIFFUSE_DIR,      L->direct_diffuse);
603         ADD_COMPONENT(DENOISING_CLEAN_DIFFUSE_IND,      L->indirect_diffuse);
604         ADD_COMPONENT(DENOISING_CLEAN_GLOSSY_DIR,       L->direct_glossy);
605         ADD_COMPONENT(DENOISING_CLEAN_GLOSSY_IND,       L->indirect_glossy);
606         ADD_COMPONENT(DENOISING_CLEAN_TRANSMISSION_DIR, L->direct_transmission);
607         ADD_COMPONENT(DENOISING_CLEAN_TRANSMISSION_IND, L->indirect_transmission);
608         ADD_COMPONENT(DENOISING_CLEAN_SUBSURFACE_DIR,   L->direct_subsurface);
609         ADD_COMPONENT(DENOISING_CLEAN_SUBSURFACE_IND,   L->indirect_subsurface);
610 #  undef ADD_COMPONENT
611 #else
612         *noisy = L->emission;
613         *clean = make_float3(0.0f, 0.0f, 0.0f);
614 #endif
615
616         *noisy = ensure_finite3(*noisy);
617         *clean = ensure_finite3(*clean);
618 }
619
620 ccl_device_inline void path_radiance_accum_sample(PathRadiance *L, PathRadiance *L_sample, int num_samples)
621 {
622         float fac = 1.0f/num_samples;
623
624 #ifdef __SPLIT_KERNEL__
625 #  define safe_float3_add(f, v) \
626         do { \
627                 ccl_global float *p = (ccl_global float*)(&(f)); \
628                 atomic_add_and_fetch_float(p+0, (v).x); \
629                 atomic_add_and_fetch_float(p+1, (v).y); \
630                 atomic_add_and_fetch_float(p+2, (v).z); \
631         } while(0)
632 #else
633 #  define safe_float3_add(f, v) (f) += (v)
634 #endif  /* __SPLIT_KERNEL__ */
635
636 #ifdef __PASSES__
637         safe_float3_add(L->direct_diffuse, L_sample->direct_diffuse*fac);
638         safe_float3_add(L->direct_glossy, L_sample->direct_glossy*fac);
639         safe_float3_add(L->direct_transmission, L_sample->direct_transmission*fac);
640         safe_float3_add(L->direct_subsurface, L_sample->direct_subsurface*fac);
641         safe_float3_add(L->direct_scatter, L_sample->direct_scatter*fac);
642
643         safe_float3_add(L->indirect_diffuse, L_sample->indirect_diffuse*fac);
644         safe_float3_add(L->indirect_glossy, L_sample->indirect_glossy*fac);
645         safe_float3_add(L->indirect_transmission, L_sample->indirect_transmission*fac);
646         safe_float3_add(L->indirect_subsurface, L_sample->indirect_subsurface*fac);
647         safe_float3_add(L->indirect_scatter, L_sample->indirect_scatter*fac);
648
649         safe_float3_add(L->background, L_sample->background*fac);
650         safe_float3_add(L->ao, L_sample->ao*fac);
651         safe_float3_add(L->shadow, L_sample->shadow*fac);
652 #  ifdef __SPLIT_KERNEL__
653         atomic_add_and_fetch_float(&L->mist, L_sample->mist*fac);
654 #  else
655         L->mist += L_sample->mist*fac;
656 #  endif  /* __SPLIT_KERNEL__ */
657 #endif  /* __PASSES__ */
658         safe_float3_add(L->emission, L_sample->emission*fac);
659
660 #undef safe_float3_add
661 }
662
663 #ifdef __SHADOW_TRICKS__
664 /* Calculate current shadow of the path. */
665 ccl_device_inline float path_radiance_sum_shadow(const PathRadiance *L)
666 {
667         float path_total = average(L->path_total);
668         float path_total_shaded = average(L->path_total_shaded);
669         if(path_total != 0.0f) {
670                 return path_total_shaded / path_total;
671         }
672         return 1.0f;
673 }
674
675 /* Calculate final light sum and transparency for shadow catcher object. */
676 ccl_device_inline float3 path_radiance_sum_shadowcatcher(KernelGlobals *kg,
677                                                          const PathRadiance *L,
678                                                          float* alpha)
679 {
680         const float shadow = path_radiance_sum_shadow(L);
681         float3 L_sum;
682         if(kernel_data.background.transparent) {
683                 *alpha = 1.0f-shadow;
684                 L_sum = make_float3(0.0f, 0.0f, 0.0f);
685         }
686         else {
687                 L_sum = L->shadow_color * shadow;
688         }
689         return L_sum;
690 }
691 #endif
692
693 CCL_NAMESPACE_END