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 float3 shader_bsdf_transparency(KernelGlobals *kg,
25                                            const ShaderData *sd);
26
27 ccl_device_inline void bsdf_eval_init(BsdfEval *eval, ClosureType type, float3 value, int use_light_pass)
28 {
29 #ifdef __PASSES__
30         eval->use_light_pass = use_light_pass;
31
32         if(eval->use_light_pass) {
33                 eval->diffuse = make_float3(0.0f, 0.0f, 0.0f);
34                 eval->glossy = make_float3(0.0f, 0.0f, 0.0f);
35                 eval->transmission = make_float3(0.0f, 0.0f, 0.0f);
36                 eval->transparent = make_float3(0.0f, 0.0f, 0.0f);
37                 eval->subsurface = make_float3(0.0f, 0.0f, 0.0f);
38                 eval->scatter = make_float3(0.0f, 0.0f, 0.0f);
39
40                 if(type == CLOSURE_BSDF_TRANSPARENT_ID)
41                         eval->transparent = value;
42                 else if(CLOSURE_IS_BSDF_DIFFUSE(type))
43                         eval->diffuse = value;
44                 else if(CLOSURE_IS_BSDF_GLOSSY(type))
45                         eval->glossy = value;
46                 else if(CLOSURE_IS_BSDF_TRANSMISSION(type))
47                         eval->transmission = value;
48                 else if(CLOSURE_IS_BSDF_BSSRDF(type))
49                         eval->subsurface = value;
50                 else if(CLOSURE_IS_PHASE(type))
51                         eval->scatter = value;
52         }
53         else
54 #endif
55         {
56                 eval->diffuse = value;
57         }
58 #ifdef __SHADOW_TRICKS__
59         eval->sum_no_mis = make_float3(0.0f, 0.0f, 0.0f);
60 #endif
61 }
62
63 ccl_device_inline void bsdf_eval_accum(BsdfEval *eval, ClosureType type, float3 value, float mis_weight)
64 {
65 #ifdef __SHADOW_TRICKS__
66         eval->sum_no_mis += value;
67 #endif
68         value *= mis_weight;
69 #ifdef __PASSES__
70         if(eval->use_light_pass) {
71                 if(CLOSURE_IS_BSDF_DIFFUSE(type))
72                         eval->diffuse += value;
73                 else if(CLOSURE_IS_BSDF_GLOSSY(type))
74                         eval->glossy += value;
75                 else if(CLOSURE_IS_BSDF_TRANSMISSION(type))
76                         eval->transmission += value;
77                 else if(CLOSURE_IS_BSDF_BSSRDF(type))
78                         eval->subsurface += value;
79                 else if(CLOSURE_IS_PHASE(type))
80                         eval->scatter += value;
81
82                 /* skipping transparent, this function is used by for eval(), will be zero then */
83         }
84         else
85 #endif
86         {
87                 eval->diffuse += value;
88         }
89 }
90
91 ccl_device_inline bool bsdf_eval_is_zero(BsdfEval *eval)
92 {
93 #ifdef __PASSES__
94         if(eval->use_light_pass) {
95                 return is_zero(eval->diffuse)
96                         && is_zero(eval->glossy)
97                         && is_zero(eval->transmission)
98                         && is_zero(eval->transparent)
99                         && is_zero(eval->subsurface)
100                         && is_zero(eval->scatter);
101         }
102         else
103 #endif
104         {
105                 return is_zero(eval->diffuse);
106         }
107 }
108
109 ccl_device_inline void bsdf_eval_mis(BsdfEval *eval, float value)
110 {
111 #ifdef __PASSES__
112         if(eval->use_light_pass) {
113                 eval->diffuse *= value;
114                 eval->glossy *= value;
115                 eval->transmission *= value;
116                 eval->subsurface *= value;
117                 eval->scatter *= value;
118
119                 /* skipping transparent, this function is used by for eval(), will be zero then */
120         }
121         else
122 #endif
123         {
124                 eval->diffuse *= value;
125         }
126 }
127
128 ccl_device_inline void bsdf_eval_mul(BsdfEval *eval, float value)
129 {
130 #ifdef __SHADOW_TRICKS__
131         eval->sum_no_mis *= value;
132 #endif
133         bsdf_eval_mis(eval, value);
134 }
135
136 ccl_device_inline void bsdf_eval_mul3(BsdfEval *eval, float3 value)
137 {
138 #ifdef __SHADOW_TRICKS__
139         eval->sum_no_mis *= value;
140 #endif
141 #ifdef __PASSES__
142         if(eval->use_light_pass) {
143                 eval->diffuse *= value;
144                 eval->glossy *= value;
145                 eval->transmission *= value;
146                 eval->subsurface *= value;
147                 eval->scatter *= value;
148
149                 /* skipping transparent, this function is used by for eval(), will be zero then */
150         }
151         else
152                 eval->diffuse *= value;
153 #else
154         eval->diffuse *= value;
155 #endif
156 }
157
158 ccl_device_inline float3 bsdf_eval_sum(const BsdfEval *eval)
159 {
160 #ifdef __PASSES__
161         if(eval->use_light_pass) {
162                 return eval->diffuse + eval->glossy + eval->transmission + eval->subsurface + eval->scatter;
163         }
164         else
165 #endif
166         return eval->diffuse;
167 }
168
169 /* Path Radiance
170  *
171  * We accumulate different render passes separately. After summing at the end
172  * to get the combined result, it should be identical. We definite directly
173  * visible as the first non-transparent hit, while indirectly visible are the
174  * bounces after that. */
175
176 ccl_device_inline void path_radiance_init(PathRadiance *L, int use_light_pass)
177 {
178         /* clear all */
179 #ifdef __PASSES__
180         L->use_light_pass = use_light_pass;
181
182         if(use_light_pass) {
183                 L->indirect = make_float3(0.0f, 0.0f, 0.0f);
184                 L->direct_throughput = make_float3(0.0f, 0.0f, 0.0f);
185                 L->direct_emission = make_float3(0.0f, 0.0f, 0.0f);
186
187                 L->color_diffuse = make_float3(0.0f, 0.0f, 0.0f);
188                 L->color_glossy = make_float3(0.0f, 0.0f, 0.0f);
189                 L->color_transmission = make_float3(0.0f, 0.0f, 0.0f);
190                 L->color_subsurface = make_float3(0.0f, 0.0f, 0.0f);
191                 L->color_scatter = make_float3(0.0f, 0.0f, 0.0f);
192
193                 L->direct_diffuse = make_float3(0.0f, 0.0f, 0.0f);
194                 L->direct_glossy = make_float3(0.0f, 0.0f, 0.0f);
195                 L->direct_transmission = make_float3(0.0f, 0.0f, 0.0f);
196                 L->direct_subsurface = make_float3(0.0f, 0.0f, 0.0f);
197                 L->direct_scatter = make_float3(0.0f, 0.0f, 0.0f);
198
199                 L->indirect_diffuse = make_float3(0.0f, 0.0f, 0.0f);
200                 L->indirect_glossy = make_float3(0.0f, 0.0f, 0.0f);
201                 L->indirect_transmission = make_float3(0.0f, 0.0f, 0.0f);
202                 L->indirect_subsurface = make_float3(0.0f, 0.0f, 0.0f);
203                 L->indirect_scatter = make_float3(0.0f, 0.0f, 0.0f);
204
205                 L->path_diffuse = make_float3(0.0f, 0.0f, 0.0f);
206                 L->path_glossy = make_float3(0.0f, 0.0f, 0.0f);
207                 L->path_transmission = make_float3(0.0f, 0.0f, 0.0f);
208                 L->path_subsurface = make_float3(0.0f, 0.0f, 0.0f);
209                 L->path_scatter = make_float3(0.0f, 0.0f, 0.0f);
210
211                 L->emission = make_float3(0.0f, 0.0f, 0.0f);
212                 L->background = make_float3(0.0f, 0.0f, 0.0f);
213                 L->ao = make_float3(0.0f, 0.0f, 0.0f);
214                 L->shadow = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
215                 L->mist = 0.0f;
216         }
217         else
218 #endif
219         {
220                 L->emission = make_float3(0.0f, 0.0f, 0.0f);
221         }
222
223 #ifdef __SHADOW_TRICKS__
224         L->path_total = make_float3(0.0f, 0.0f, 0.0f);
225         L->path_total_shaded = make_float3(0.0f, 0.0f, 0.0f);
226         L->shadow_background_color = make_float3(0.0f, 0.0f, 0.0f);
227         L->shadow_radiance_sum = make_float3(0.0f, 0.0f, 0.0f);
228         L->shadow_throughput = 0.0f;
229         L->shadow_transparency = 1.0f;
230 #endif
231
232 #ifdef __DENOISING_FEATURES__
233         L->denoising_normal = make_float3(0.0f, 0.0f, 0.0f);
234         L->denoising_albedo = make_float3(0.0f, 0.0f, 0.0f);
235         L->denoising_depth = 0.0f;
236 #endif  /* __DENOISING_FEATURES__ */
237 }
238
239 ccl_device_inline void path_radiance_bsdf_bounce(PathRadiance *L, ccl_addr_space float3 *throughput,
240         BsdfEval *bsdf_eval, float bsdf_pdf, int bounce, int bsdf_label)
241 {
242         float inverse_pdf = 1.0f/bsdf_pdf;
243
244 #ifdef __PASSES__
245         if(L->use_light_pass) {
246                 if(bounce == 0 && !(bsdf_label & LABEL_TRANSPARENT)) {
247                         /* first on directly visible surface */
248                         float3 value = *throughput*inverse_pdf;
249
250                         L->path_diffuse = bsdf_eval->diffuse*value;
251                         L->path_glossy = bsdf_eval->glossy*value;
252                         L->path_transmission = bsdf_eval->transmission*value;
253                         L->path_subsurface = bsdf_eval->subsurface*value;
254                         L->path_scatter = bsdf_eval->scatter*value;
255
256                         *throughput = L->path_diffuse + L->path_glossy + L->path_transmission + L->path_subsurface + L->path_scatter;
257                         
258                         L->direct_throughput = *throughput;
259                 }
260                 else {
261                         /* transparent bounce before first hit, or indirectly visible through BSDF */
262                         float3 sum = (bsdf_eval_sum(bsdf_eval) + bsdf_eval->transparent) * inverse_pdf;
263                         *throughput *= sum;
264                 }
265         }
266         else
267 #endif
268         {
269                 *throughput *= bsdf_eval->diffuse*inverse_pdf;
270         }
271 }
272
273 ccl_device_inline void path_radiance_accum_emission(PathRadiance *L, float3 throughput, float3 value, int bounce)
274 {
275 #ifdef __PASSES__
276         if(L->use_light_pass) {
277                 if(bounce == 0)
278                         L->emission += throughput*value;
279                 else if(bounce == 1)
280                         L->direct_emission += throughput*value;
281                 else
282                         L->indirect += throughput*value;
283         }
284         else
285 #endif
286         {
287                 L->emission += throughput*value;
288         }
289 }
290
291 ccl_device_inline void path_radiance_accum_ao(PathRadiance *L,
292                                               ccl_addr_space PathState *state,
293                                               float3 throughput,
294                                               float3 alpha,
295                                               float3 bsdf,
296                                               float3 ao)
297 {
298 #ifdef __PASSES__
299         if(L->use_light_pass) {
300                 if(state->bounce == 0) {
301                         /* directly visible lighting */
302                         L->direct_diffuse += throughput*bsdf*ao;
303                         L->ao += alpha*throughput*ao;
304                 }
305                 else {
306                         /* indirectly visible lighting after BSDF bounce */
307                         L->indirect += throughput*bsdf*ao;
308                 }
309         }
310         else
311 #endif
312         {
313                 L->emission += throughput*bsdf*ao;
314         }
315
316 #ifdef __SHADOW_TRICKS__
317         if(state->flag & PATH_RAY_STORE_SHADOW_INFO) {
318                 float3 light = throughput * bsdf;
319                 L->path_total += light;
320                 L->path_total_shaded += ao * light;
321         }
322 #endif
323 }
324
325 ccl_device_inline void path_radiance_accum_total_ao(
326         PathRadiance *L,
327         ccl_addr_space PathState *state,
328         float3 throughput,
329         float3 bsdf)
330 {
331 #ifdef __SHADOW_TRICKS__
332         if(state->flag & PATH_RAY_STORE_SHADOW_INFO) {
333                 L->path_total += throughput * bsdf;
334         }
335 #else
336         (void) L;
337         (void) state;
338         (void) throughput;
339         (void) bsdf;
340 #endif
341 }
342
343 ccl_device_inline void path_radiance_accum_light(PathRadiance *L,
344                                                  ccl_addr_space PathState *state,
345                                                  float3 throughput,
346                                                  BsdfEval *bsdf_eval,
347                                                  float3 shadow,
348                                                  float shadow_fac,
349                                                  bool is_lamp)
350 {
351 #ifdef __PASSES__
352         if(L->use_light_pass) {
353                 if(state->bounce == 0) {
354                         /* directly visible lighting */
355                         L->direct_diffuse += throughput*bsdf_eval->diffuse*shadow;
356                         L->direct_glossy += throughput*bsdf_eval->glossy*shadow;
357                         L->direct_transmission += throughput*bsdf_eval->transmission*shadow;
358                         L->direct_subsurface += throughput*bsdf_eval->subsurface*shadow;
359                         L->direct_scatter += throughput*bsdf_eval->scatter*shadow;
360
361                         if(is_lamp) {
362                                 L->shadow.x += shadow.x*shadow_fac;
363                                 L->shadow.y += shadow.y*shadow_fac;
364                                 L->shadow.z += shadow.z*shadow_fac;
365                         }
366                 }
367                 else {
368                         /* indirectly visible lighting after BSDF bounce */
369                         L->indirect += throughput*bsdf_eval_sum(bsdf_eval)*shadow;
370                 }
371         }
372         else
373 #endif
374         {
375                 L->emission += throughput*bsdf_eval->diffuse*shadow;
376         }
377
378 #ifdef __SHADOW_TRICKS__
379         if(state->flag & PATH_RAY_STORE_SHADOW_INFO) {
380                 float3 light = throughput * bsdf_eval->sum_no_mis;
381                 L->path_total += light;
382                 L->path_total_shaded += shadow * light;
383         }
384 #endif
385 }
386
387 ccl_device_inline void path_radiance_accum_total_light(
388         PathRadiance *L,
389         ccl_addr_space PathState *state,
390         float3 throughput,
391         const BsdfEval *bsdf_eval)
392 {
393 #ifdef __SHADOW_TRICKS__
394         if(state->flag & PATH_RAY_STORE_SHADOW_INFO) {
395                 L->path_total += throughput * bsdf_eval->sum_no_mis;
396         }
397 #else
398         (void) L;
399         (void) state;
400         (void) throughput;
401         (void) bsdf_eval;
402 #endif
403 }
404
405 ccl_device_inline void path_radiance_accum_background(
406         PathRadiance *L,
407         ccl_addr_space PathState *state,
408         float3 throughput,
409         float3 value)
410 {
411 #ifdef __PASSES__
412         if(L->use_light_pass) {
413                 if(state->bounce == 0)
414                         L->background += throughput*value;
415                 else if(state->bounce == 1)
416                         L->direct_emission += throughput*value;
417                 else
418                         L->indirect += throughput*value;
419         }
420         else
421 #endif
422         {
423                 L->emission += throughput*value;
424         }
425
426 #ifdef __SHADOW_TRICKS__
427         if(state->flag & PATH_RAY_STORE_SHADOW_INFO) {
428                 L->path_total += throughput * value;
429                 L->path_total_shaded += throughput * value * L->shadow_transparency;
430         }
431 #endif
432
433 #ifdef __DENOISING_FEATURES__
434         L->denoising_albedo += state->denoising_feature_weight * value;
435 #endif  /* __DENOISING_FEATURES__ */
436 }
437
438 ccl_device_inline void path_radiance_sum_indirect(PathRadiance *L)
439 {
440 #ifdef __PASSES__
441         /* this division is a bit ugly, but means we only have to keep track of
442          * only a single throughput further along the path, here we recover just
443          * the indirect path that is not influenced by any particular BSDF type */
444         if(L->use_light_pass) {
445                 L->direct_emission = safe_divide_color(L->direct_emission, L->direct_throughput);
446                 L->direct_diffuse += L->path_diffuse*L->direct_emission;
447                 L->direct_glossy += L->path_glossy*L->direct_emission;
448                 L->direct_transmission += L->path_transmission*L->direct_emission;
449                 L->direct_subsurface += L->path_subsurface*L->direct_emission;
450                 L->direct_scatter += L->path_scatter*L->direct_emission;
451
452                 L->indirect = safe_divide_color(L->indirect, L->direct_throughput);
453                 L->indirect_diffuse += L->path_diffuse*L->indirect;
454                 L->indirect_glossy += L->path_glossy*L->indirect;
455                 L->indirect_transmission += L->path_transmission*L->indirect;
456                 L->indirect_subsurface += L->path_subsurface*L->indirect;
457                 L->indirect_scatter += L->path_scatter*L->indirect;
458         }
459 #endif
460 }
461
462 ccl_device_inline void path_radiance_reset_indirect(PathRadiance *L)
463 {
464 #ifdef __PASSES__
465         if(L->use_light_pass) {
466                 L->path_diffuse = make_float3(0.0f, 0.0f, 0.0f);
467                 L->path_glossy = make_float3(0.0f, 0.0f, 0.0f);
468                 L->path_transmission = make_float3(0.0f, 0.0f, 0.0f);
469                 L->path_subsurface = make_float3(0.0f, 0.0f, 0.0f);
470                 L->path_scatter = make_float3(0.0f, 0.0f, 0.0f);
471
472                 L->direct_emission = make_float3(0.0f, 0.0f, 0.0f);
473                 L->indirect = make_float3(0.0f, 0.0f, 0.0f);
474         }
475 #endif
476 }
477
478 ccl_device_inline void path_radiance_copy_indirect(PathRadiance *L,
479                                                    const PathRadiance *L_src)
480 {
481 #ifdef __PASSES__
482         if(L->use_light_pass) {
483                 L->path_diffuse = L_src->path_diffuse;
484                 L->path_glossy = L_src->path_glossy;
485                 L->path_transmission = L_src->path_transmission;
486                 L->path_subsurface = L_src->path_subsurface;
487                 L->path_scatter = L_src->path_scatter;
488
489                 L->direct_emission = L_src->direct_emission;
490                 L->indirect = L_src->indirect;
491         }
492 #endif
493 }
494
495 ccl_device_inline float3 path_radiance_clamp_and_sum(KernelGlobals *kg, PathRadiance *L)
496 {
497         float3 L_sum;
498         /* Light Passes are used */
499 #ifdef __PASSES__
500         float3 L_direct, L_indirect;
501         float clamp_direct = kernel_data.integrator.sample_clamp_direct;
502         float clamp_indirect = kernel_data.integrator.sample_clamp_indirect;
503         if(L->use_light_pass) {
504                 path_radiance_sum_indirect(L);
505
506                 L_direct = L->direct_diffuse + L->direct_glossy + L->direct_transmission + L->direct_subsurface + L->direct_scatter + L->emission;
507                 L_indirect = L->indirect_diffuse + L->indirect_glossy + L->indirect_transmission + L->indirect_subsurface + L->indirect_scatter;
508
509                 if(!kernel_data.background.transparent)
510                         L_direct += L->background;
511
512                 L_sum = L_direct + L_indirect;
513                 float sum = fabsf((L_sum).x) + fabsf((L_sum).y) + fabsf((L_sum).z);
514
515                 /* Reject invalid value */
516                 if(!isfinite_safe(sum)) {
517                         kernel_assert(!"Non-finite sum in path_radiance_clamp_and_sum!");
518                         L_sum = make_float3(0.0f, 0.0f, 0.0f);
519
520                         L->direct_diffuse = make_float3(0.0f, 0.0f, 0.0f);
521                         L->direct_glossy = make_float3(0.0f, 0.0f, 0.0f);
522                         L->direct_transmission = make_float3(0.0f, 0.0f, 0.0f);
523                         L->direct_subsurface = make_float3(0.0f, 0.0f, 0.0f);
524                         L->direct_scatter = make_float3(0.0f, 0.0f, 0.0f);
525
526                         L->indirect_diffuse = make_float3(0.0f, 0.0f, 0.0f);
527                         L->indirect_glossy = make_float3(0.0f, 0.0f, 0.0f);
528                         L->indirect_transmission = make_float3(0.0f, 0.0f, 0.0f);
529                         L->indirect_subsurface = make_float3(0.0f, 0.0f, 0.0f);
530                         L->indirect_scatter = make_float3(0.0f, 0.0f, 0.0f);
531
532                         L->emission = make_float3(0.0f, 0.0f, 0.0f);
533                 }
534
535                 /* Clamp direct and indirect samples */
536 #ifdef __CLAMP_SAMPLE__
537                 else if(sum > clamp_direct || sum > clamp_indirect) {
538                         float scale;
539
540                         /* Direct */
541                         float sum_direct = fabsf(L_direct.x) + fabsf(L_direct.y) + fabsf(L_direct.z);
542                         if(sum_direct > clamp_direct) {
543                                 scale = clamp_direct/sum_direct;
544                                 L_direct *= scale;
545
546                                 L->direct_diffuse *= scale;
547                                 L->direct_glossy *= scale;
548                                 L->direct_transmission *= scale;
549                                 L->direct_subsurface *= scale;
550                                 L->direct_scatter *= scale;
551                                 L->emission *= scale;
552                                 L->background *= scale;
553                         }
554
555                         /* Indirect */
556                         float sum_indirect = fabsf(L_indirect.x) + fabsf(L_indirect.y) + fabsf(L_indirect.z);
557                         if(sum_indirect > clamp_indirect) {
558                                 scale = clamp_indirect/sum_indirect;
559                                 L_indirect *= scale;
560
561                                 L->indirect_diffuse *= scale;
562                                 L->indirect_glossy *= scale;
563                                 L->indirect_transmission *= scale;
564                                 L->indirect_subsurface *= scale;
565                                 L->indirect_scatter *= scale;
566                         }
567
568                         /* Sum again, after clamping */
569                         L_sum = L_direct + L_indirect;
570                 }
571 #endif
572
573                 return L_sum;
574         }
575
576         /* No Light Passes */
577         else
578 #endif
579         {
580                 L_sum = L->emission;
581         }
582
583         /* Reject invalid value */
584         float sum = fabsf((L_sum).x) + fabsf((L_sum).y) + fabsf((L_sum).z);
585         if(!isfinite_safe(sum)) {
586                 kernel_assert(!"Non-finite final sum in path_radiance_clamp_and_sum!");
587                 L_sum = make_float3(0.0f, 0.0f, 0.0f);
588         }
589
590         return L_sum;
591 }
592
593 ccl_device_inline void path_radiance_split_denoising(KernelGlobals *kg, PathRadiance *L, float3 *noisy, float3 *clean)
594 {
595 #ifdef __PASSES__
596         kernel_assert(L->use_light_pass);
597
598         *clean = L->emission + L->background;
599         *noisy = L->direct_scatter + L->indirect_scatter;
600
601 #  define ADD_COMPONENT(flag, component)     \
602         if(kernel_data.film.denoising_flags & flag) \
603                 *clean += component;                 \
604         else                                     \
605                 *noisy += component;
606
607         ADD_COMPONENT(DENOISING_CLEAN_DIFFUSE_DIR,      L->direct_diffuse);
608         ADD_COMPONENT(DENOISING_CLEAN_DIFFUSE_IND,      L->indirect_diffuse);
609         ADD_COMPONENT(DENOISING_CLEAN_GLOSSY_DIR,       L->direct_glossy);
610         ADD_COMPONENT(DENOISING_CLEAN_GLOSSY_IND,       L->indirect_glossy);
611         ADD_COMPONENT(DENOISING_CLEAN_TRANSMISSION_DIR, L->direct_transmission);
612         ADD_COMPONENT(DENOISING_CLEAN_TRANSMISSION_IND, L->indirect_transmission);
613         ADD_COMPONENT(DENOISING_CLEAN_SUBSURFACE_DIR,   L->direct_subsurface);
614         ADD_COMPONENT(DENOISING_CLEAN_SUBSURFACE_IND,   L->indirect_subsurface);
615 #  undef ADD_COMPONENT
616 #else
617         *noisy = L->emission;
618         *clean = make_float3(0.0f, 0.0f, 0.0f);
619 #endif
620
621         *noisy = ensure_finite3(*noisy);
622         *clean = ensure_finite3(*clean);
623 }
624
625 ccl_device_inline void path_radiance_accum_sample(PathRadiance *L, PathRadiance *L_sample, int num_samples)
626 {
627         float fac = 1.0f/num_samples;
628
629 #ifdef __SPLIT_KERNEL__
630 #  define safe_float3_add(f, v) \
631         do { \
632                 ccl_global float *p = (ccl_global float*)(&(f)); \
633                 atomic_add_and_fetch_float(p+0, (v).x); \
634                 atomic_add_and_fetch_float(p+1, (v).y); \
635                 atomic_add_and_fetch_float(p+2, (v).z); \
636         } while(0)
637 #else
638 #  define safe_float3_add(f, v) (f) += (v)
639 #endif  /* __SPLIT_KERNEL__ */
640
641 #ifdef __PASSES__
642         safe_float3_add(L->direct_diffuse, L_sample->direct_diffuse*fac);
643         safe_float3_add(L->direct_glossy, L_sample->direct_glossy*fac);
644         safe_float3_add(L->direct_transmission, L_sample->direct_transmission*fac);
645         safe_float3_add(L->direct_subsurface, L_sample->direct_subsurface*fac);
646         safe_float3_add(L->direct_scatter, L_sample->direct_scatter*fac);
647
648         safe_float3_add(L->indirect_diffuse, L_sample->indirect_diffuse*fac);
649         safe_float3_add(L->indirect_glossy, L_sample->indirect_glossy*fac);
650         safe_float3_add(L->indirect_transmission, L_sample->indirect_transmission*fac);
651         safe_float3_add(L->indirect_subsurface, L_sample->indirect_subsurface*fac);
652         safe_float3_add(L->indirect_scatter, L_sample->indirect_scatter*fac);
653
654         safe_float3_add(L->background, L_sample->background*fac);
655         safe_float3_add(L->ao, L_sample->ao*fac);
656         safe_float3_add(L->shadow, L_sample->shadow*fac);
657 #  ifdef __SPLIT_KERNEL__
658         atomic_add_and_fetch_float(&L->mist, L_sample->mist*fac);
659 #  else
660         L->mist += L_sample->mist*fac;
661 #  endif  /* __SPLIT_KERNEL__ */
662 #endif  /* __PASSES__ */
663         safe_float3_add(L->emission, L_sample->emission*fac);
664
665 #undef safe_float3_add
666 }
667
668 #ifdef __SHADOW_TRICKS__
669 /* Calculate current shadow of the path. */
670 ccl_device_inline float path_radiance_sum_shadow(const PathRadiance *L)
671 {
672         float path_total = average(L->path_total);
673         float path_total_shaded = average(L->path_total_shaded);
674         if(path_total != 0.0f) {
675                 return path_total_shaded / path_total;
676         }
677         return L->shadow_transparency;
678 }
679
680 /* Calculate final light sum and transparency for shadow catcher object. */
681 ccl_device_inline float3 path_radiance_sum_shadowcatcher(KernelGlobals *kg,
682                                                          const PathRadiance *L,
683                                                          float* alpha)
684 {
685         const float shadow = path_radiance_sum_shadow(L);
686         float3 L_sum;
687         if(kernel_data.background.transparent) {
688                 *alpha = 1.0f - L->shadow_throughput * shadow;
689                 L_sum = L->shadow_radiance_sum;
690         }
691         else {
692                 L_sum = L->shadow_background_color * L->shadow_throughput * shadow +
693                         L->shadow_radiance_sum;
694         }
695         return L_sum;
696 }
697 #endif
698
699 CCL_NAMESPACE_END