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_emission = make_float3(0.0f, 0.0f, 0.0f);
185
186                 L->color_diffuse = make_float3(0.0f, 0.0f, 0.0f);
187                 L->color_glossy = make_float3(0.0f, 0.0f, 0.0f);
188                 L->color_transmission = make_float3(0.0f, 0.0f, 0.0f);
189                 L->color_subsurface = make_float3(0.0f, 0.0f, 0.0f);
190
191                 L->direct_diffuse = make_float3(0.0f, 0.0f, 0.0f);
192                 L->direct_glossy = make_float3(0.0f, 0.0f, 0.0f);
193                 L->direct_transmission = make_float3(0.0f, 0.0f, 0.0f);
194                 L->direct_subsurface = make_float3(0.0f, 0.0f, 0.0f);
195                 L->direct_scatter = make_float3(0.0f, 0.0f, 0.0f);
196
197                 L->indirect_diffuse = make_float3(0.0f, 0.0f, 0.0f);
198                 L->indirect_glossy = make_float3(0.0f, 0.0f, 0.0f);
199                 L->indirect_transmission = make_float3(0.0f, 0.0f, 0.0f);
200                 L->indirect_subsurface = make_float3(0.0f, 0.0f, 0.0f);
201                 L->indirect_scatter = make_float3(0.0f, 0.0f, 0.0f);
202
203                 L->transparent = 0.0f;
204                 L->emission = make_float3(0.0f, 0.0f, 0.0f);
205                 L->background = make_float3(0.0f, 0.0f, 0.0f);
206                 L->ao = make_float3(0.0f, 0.0f, 0.0f);
207                 L->shadow = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
208                 L->mist = 0.0f;
209
210                 L->state.diffuse = make_float3(0.0f, 0.0f, 0.0f);
211                 L->state.glossy = make_float3(0.0f, 0.0f, 0.0f);
212                 L->state.transmission = make_float3(0.0f, 0.0f, 0.0f);
213                 L->state.subsurface = make_float3(0.0f, 0.0f, 0.0f);
214                 L->state.scatter = make_float3(0.0f, 0.0f, 0.0f);
215                 L->state.direct = make_float3(0.0f, 0.0f, 0.0f);
216         }
217         else
218 #endif
219         {
220                 L->transparent = 0.0f;
221                 L->emission = make_float3(0.0f, 0.0f, 0.0f);
222         }
223
224 #ifdef __SHADOW_TRICKS__
225         L->path_total = make_float3(0.0f, 0.0f, 0.0f);
226         L->path_total_shaded = make_float3(0.0f, 0.0f, 0.0f);
227         L->shadow_background_color = make_float3(0.0f, 0.0f, 0.0f);
228         L->shadow_throughput = 0.0f;
229         L->shadow_transparency = 1.0f;
230         L->has_shadow_catcher = 0;
231 #endif
232
233 #ifdef __DENOISING_FEATURES__
234         L->denoising_normal = make_float3(0.0f, 0.0f, 0.0f);
235         L->denoising_albedo = make_float3(0.0f, 0.0f, 0.0f);
236         L->denoising_depth = 0.0f;
237 #endif
238
239 #ifdef __KERNEL_DEBUG__
240         L->debug_data.num_bvh_traversed_nodes = 0;
241         L->debug_data.num_bvh_traversed_instances = 0;
242         L->debug_data.num_bvh_intersections = 0;
243         L->debug_data.num_ray_bounces = 0;
244 #endif
245 }
246
247 ccl_device_inline void path_radiance_bsdf_bounce(
248         KernelGlobals *kg,
249         PathRadianceState *L_state,
250         ccl_addr_space float3 *throughput,
251         BsdfEval *bsdf_eval,
252         float bsdf_pdf, int bounce, int bsdf_label)
253 {
254         float inverse_pdf = 1.0f/bsdf_pdf;
255
256 #ifdef __PASSES__
257         if(kernel_data.film.use_light_pass) {
258                 if(bounce == 0 && !(bsdf_label & LABEL_TRANSPARENT)) {
259                         /* first on directly visible surface */
260                         float3 value = *throughput*inverse_pdf;
261
262                         L_state->diffuse = bsdf_eval->diffuse*value;
263                         L_state->glossy = bsdf_eval->glossy*value;
264                         L_state->transmission = bsdf_eval->transmission*value;
265                         L_state->subsurface = bsdf_eval->subsurface*value;
266                         L_state->scatter = bsdf_eval->scatter*value;
267
268                         *throughput = L_state->diffuse +
269                                       L_state->glossy +
270                                       L_state->transmission +
271                                       L_state->subsurface +
272                                       L_state->scatter;
273
274                         L_state->direct = *throughput;
275                 }
276                 else {
277                         /* transparent bounce before first hit, or indirectly visible through BSDF */
278                         float3 sum = (bsdf_eval_sum(bsdf_eval) + bsdf_eval->transparent) * inverse_pdf;
279                         *throughput *= sum;
280                 }
281         }
282         else
283 #endif
284         {
285                 *throughput *= bsdf_eval->diffuse*inverse_pdf;
286         }
287 }
288
289 ccl_device_inline void path_radiance_accum_emission(PathRadiance *L,
290                                                     ccl_addr_space PathState *state,
291                                                     float3 throughput,
292                                                     float3 value)
293 {
294 #ifdef __SHADOW_TRICKS__
295         if(state->flag & PATH_RAY_SHADOW_CATCHER) {
296                 return;
297         }
298 #endif
299
300 #ifdef __PASSES__
301         if(L->use_light_pass) {
302                 if(state->bounce == 0)
303                         L->emission += throughput*value;
304                 else if(state->bounce == 1)
305                         L->direct_emission += throughput*value;
306                 else
307                         L->indirect += throughput*value;
308         }
309         else
310 #endif
311         {
312                 L->emission += throughput*value;
313         }
314 }
315
316 ccl_device_inline void path_radiance_accum_ao(PathRadiance *L,
317                                               ccl_addr_space PathState *state,
318                                               float3 throughput,
319                                               float3 alpha,
320                                               float3 bsdf,
321                                               float3 ao)
322 {
323         /* Store AO pass. */
324         if(L->use_light_pass && state->bounce == 0) {
325                 L->ao += alpha*throughput*ao;
326         }
327
328 #ifdef __SHADOW_TRICKS__
329         /* For shadow catcher, accumulate ratio. */
330         if(state->flag & PATH_RAY_STORE_SHADOW_INFO) {
331                 float3 light = throughput * bsdf;
332                 L->path_total += light;
333                 L->path_total_shaded += ao * light;
334
335                 if(state->flag & PATH_RAY_SHADOW_CATCHER) {
336                         return;
337                 }
338         }
339 #endif
340
341 #ifdef __PASSES__
342         if(L->use_light_pass) {
343                 if(state->bounce == 0) {
344                         /* Directly visible lighting. */
345                         L->direct_diffuse += throughput*bsdf*ao;
346                 }
347                 else {
348                         /* Indirectly visible lighting after BSDF bounce. */
349                         L->indirect += throughput*bsdf*ao;
350                 }
351         }
352         else
353 #endif
354         {
355                 L->emission += throughput*bsdf*ao;
356         }
357 }
358
359 ccl_device_inline void path_radiance_accum_total_ao(
360         PathRadiance *L,
361         ccl_addr_space PathState *state,
362         float3 throughput,
363         float3 bsdf)
364 {
365 #ifdef __SHADOW_TRICKS__
366         if(state->flag & PATH_RAY_STORE_SHADOW_INFO) {
367                 L->path_total += throughput * bsdf;
368         }
369 #else
370         (void) L;
371         (void) state;
372         (void) throughput;
373         (void) bsdf;
374 #endif
375 }
376
377 ccl_device_inline void path_radiance_accum_light(PathRadiance *L,
378                                                  ccl_addr_space PathState *state,
379                                                  float3 throughput,
380                                                  BsdfEval *bsdf_eval,
381                                                  float3 shadow,
382                                                  float shadow_fac,
383                                                  bool is_lamp)
384 {
385 #ifdef __SHADOW_TRICKS__
386         if(state->flag & PATH_RAY_STORE_SHADOW_INFO) {
387                 float3 light = throughput * bsdf_eval->sum_no_mis;
388                 L->path_total += light;
389                 L->path_total_shaded += shadow * light;
390
391                 if(state->flag & PATH_RAY_SHADOW_CATCHER) {
392                         return;
393                 }
394         }
395 #endif
396
397 #ifdef __PASSES__
398         if(L->use_light_pass) {
399                 if(state->bounce == 0) {
400                         /* directly visible lighting */
401                         L->direct_diffuse += throughput*bsdf_eval->diffuse*shadow;
402                         L->direct_glossy += throughput*bsdf_eval->glossy*shadow;
403                         L->direct_transmission += throughput*bsdf_eval->transmission*shadow;
404                         L->direct_subsurface += throughput*bsdf_eval->subsurface*shadow;
405                         L->direct_scatter += throughput*bsdf_eval->scatter*shadow;
406
407                         if(is_lamp) {
408                                 L->shadow.x += shadow.x*shadow_fac;
409                                 L->shadow.y += shadow.y*shadow_fac;
410                                 L->shadow.z += shadow.z*shadow_fac;
411                         }
412                 }
413                 else {
414                         /* indirectly visible lighting after BSDF bounce */
415                         L->indirect += throughput*bsdf_eval_sum(bsdf_eval)*shadow;
416                 }
417         }
418         else
419 #endif
420         {
421                 L->emission += throughput*bsdf_eval->diffuse*shadow;
422         }
423 }
424
425 ccl_device_inline void path_radiance_accum_total_light(
426         PathRadiance *L,
427         ccl_addr_space PathState *state,
428         float3 throughput,
429         const BsdfEval *bsdf_eval)
430 {
431 #ifdef __SHADOW_TRICKS__
432         if(state->flag & PATH_RAY_STORE_SHADOW_INFO) {
433                 L->path_total += throughput * bsdf_eval->sum_no_mis;
434         }
435 #else
436         (void) L;
437         (void) state;
438         (void) throughput;
439         (void) bsdf_eval;
440 #endif
441 }
442
443 ccl_device_inline void path_radiance_accum_background(
444         PathRadiance *L,
445         ccl_addr_space PathState *state,
446         float3 throughput,
447         float3 value)
448 {
449
450 #ifdef __SHADOW_TRICKS__
451         if(state->flag & PATH_RAY_STORE_SHADOW_INFO) {
452                 L->path_total += throughput * value;
453                 L->path_total_shaded += throughput * value * L->shadow_transparency;
454
455                 if(state->flag & PATH_RAY_SHADOW_CATCHER) {
456                         return;
457                 }
458         }
459 #endif
460
461 #ifdef __PASSES__
462         if(L->use_light_pass) {
463                 if(state->flag & PATH_RAY_TRANSPARENT_BACKGROUND)
464                         L->background += throughput*value;
465                 else if(state->bounce == 1)
466                         L->direct_emission += throughput*value;
467                 else
468                         L->indirect += throughput*value;
469         }
470         else
471 #endif
472         {
473                 L->emission += throughput*value;
474         }
475
476 #ifdef __DENOISING_FEATURES__
477         L->denoising_albedo += state->denoising_feature_weight * value;
478 #endif  /* __DENOISING_FEATURES__ */
479 }
480
481 ccl_device_inline void path_radiance_accum_transparent(
482         PathRadiance *L,
483         ccl_addr_space PathState *state,
484         float3 throughput)
485 {
486         L->transparent += average(throughput);
487 }
488
489 #ifdef __SHADOW_TRICKS__
490 ccl_device_inline void path_radiance_accum_shadowcatcher(
491         PathRadiance *L,
492         float3 throughput,
493         float3 background)
494 {
495         L->shadow_throughput += average(throughput);
496         L->shadow_background_color += throughput * background;
497         L->has_shadow_catcher = 1;
498 }
499 #endif
500
501 ccl_device_inline void path_radiance_sum_indirect(PathRadiance *L)
502 {
503 #ifdef __PASSES__
504         /* this division is a bit ugly, but means we only have to keep track of
505          * only a single throughput further along the path, here we recover just
506          * the indirect path that is not influenced by any particular BSDF type */
507         if(L->use_light_pass) {
508                 L->direct_emission = safe_divide_color(L->direct_emission, L->state.direct);
509                 L->direct_diffuse += L->state.diffuse*L->direct_emission;
510                 L->direct_glossy += L->state.glossy*L->direct_emission;
511                 L->direct_transmission += L->state.transmission*L->direct_emission;
512                 L->direct_subsurface += L->state.subsurface*L->direct_emission;
513                 L->direct_scatter += L->state.scatter*L->direct_emission;
514
515                 L->indirect = safe_divide_color(L->indirect, L->state.direct);
516                 L->indirect_diffuse += L->state.diffuse*L->indirect;
517                 L->indirect_glossy += L->state.glossy*L->indirect;
518                 L->indirect_transmission += L->state.transmission*L->indirect;
519                 L->indirect_subsurface += L->state.subsurface*L->indirect;
520                 L->indirect_scatter += L->state.scatter*L->indirect;
521         }
522 #endif
523 }
524
525 ccl_device_inline void path_radiance_reset_indirect(PathRadiance *L)
526 {
527 #ifdef __PASSES__
528         if(L->use_light_pass) {
529                 L->state.diffuse = make_float3(0.0f, 0.0f, 0.0f);
530                 L->state.glossy = make_float3(0.0f, 0.0f, 0.0f);
531                 L->state.transmission = make_float3(0.0f, 0.0f, 0.0f);
532                 L->state.subsurface = make_float3(0.0f, 0.0f, 0.0f);
533                 L->state.scatter = make_float3(0.0f, 0.0f, 0.0f);
534
535                 L->direct_emission = make_float3(0.0f, 0.0f, 0.0f);
536                 L->indirect = make_float3(0.0f, 0.0f, 0.0f);
537         }
538 #endif
539 }
540
541 ccl_device_inline void path_radiance_copy_indirect(PathRadiance *L,
542                                                    const PathRadiance *L_src)
543 {
544 #ifdef __PASSES__
545         if(L->use_light_pass) {
546                 L->state = L_src->state;
547
548                 L->direct_emission = L_src->direct_emission;
549                 L->indirect = L_src->indirect;
550         }
551 #endif
552 }
553
554 #ifdef __SHADOW_TRICKS__
555 ccl_device_inline void path_radiance_sum_shadowcatcher(KernelGlobals *kg,
556                                                        PathRadiance *L,
557                                                        float3 *L_sum,
558                                                        float *alpha)
559 {
560         /* Calculate current shadow of the path. */
561         float path_total = average(L->path_total);
562         float shadow;
563
564         if(UNLIKELY(!isfinite_safe(path_total))) {
565                 kernel_assert(!"Non-finite total radiance along the path");
566                 shadow = 0.0f;
567         }
568         else if(path_total == 0.0f) {
569                 shadow = L->shadow_transparency;
570         }
571         else {
572                 float path_total_shaded = average(L->path_total_shaded);
573                 shadow = path_total_shaded / path_total;
574         }
575
576         /* Calculate final light sum and transparency for shadow catcher object. */
577         if(kernel_data.background.transparent) {
578                 *alpha -= L->shadow_throughput * shadow;
579         }
580         else {
581                 L->shadow_background_color *= shadow;
582                 *L_sum += L->shadow_background_color;
583         }
584 }
585 #endif
586
587 ccl_device_inline float3 path_radiance_clamp_and_sum(KernelGlobals *kg, PathRadiance *L, float *alpha)
588 {
589         float3 L_sum;
590         /* Light Passes are used */
591 #ifdef __PASSES__
592         float3 L_direct, L_indirect;
593         float clamp_direct = kernel_data.integrator.sample_clamp_direct;
594         float clamp_indirect = kernel_data.integrator.sample_clamp_indirect;
595         if(L->use_light_pass) {
596                 path_radiance_sum_indirect(L);
597
598                 L_direct = L->direct_diffuse + L->direct_glossy + L->direct_transmission + L->direct_subsurface + L->direct_scatter + L->emission;
599                 L_indirect = L->indirect_diffuse + L->indirect_glossy + L->indirect_transmission + L->indirect_subsurface + L->indirect_scatter;
600
601                 if(!kernel_data.background.transparent)
602                         L_direct += L->background;
603
604                 L_sum = L_direct + L_indirect;
605                 float sum = fabsf((L_sum).x) + fabsf((L_sum).y) + fabsf((L_sum).z);
606
607                 /* Reject invalid value */
608                 if(!isfinite_safe(sum)) {
609                         kernel_assert(!"Non-finite sum in path_radiance_clamp_and_sum!");
610                         L_sum = make_float3(0.0f, 0.0f, 0.0f);
611
612                         L->direct_diffuse = make_float3(0.0f, 0.0f, 0.0f);
613                         L->direct_glossy = make_float3(0.0f, 0.0f, 0.0f);
614                         L->direct_transmission = make_float3(0.0f, 0.0f, 0.0f);
615                         L->direct_subsurface = make_float3(0.0f, 0.0f, 0.0f);
616                         L->direct_scatter = make_float3(0.0f, 0.0f, 0.0f);
617
618                         L->indirect_diffuse = make_float3(0.0f, 0.0f, 0.0f);
619                         L->indirect_glossy = make_float3(0.0f, 0.0f, 0.0f);
620                         L->indirect_transmission = make_float3(0.0f, 0.0f, 0.0f);
621                         L->indirect_subsurface = make_float3(0.0f, 0.0f, 0.0f);
622                         L->indirect_scatter = make_float3(0.0f, 0.0f, 0.0f);
623
624                         L->emission = make_float3(0.0f, 0.0f, 0.0f);
625                 }
626
627                 /* Clamp direct and indirect samples */
628 #ifdef __CLAMP_SAMPLE__
629                 else if(sum > clamp_direct || sum > clamp_indirect) {
630                         float scale;
631
632                         /* Direct */
633                         float sum_direct = fabsf(L_direct.x) + fabsf(L_direct.y) + fabsf(L_direct.z);
634                         if(sum_direct > clamp_direct) {
635                                 scale = clamp_direct/sum_direct;
636                                 L_direct *= scale;
637
638                                 L->direct_diffuse *= scale;
639                                 L->direct_glossy *= scale;
640                                 L->direct_transmission *= scale;
641                                 L->direct_subsurface *= scale;
642                                 L->direct_scatter *= scale;
643                                 L->emission *= scale;
644                                 L->background *= scale;
645                         }
646
647                         /* Indirect */
648                         float sum_indirect = fabsf(L_indirect.x) + fabsf(L_indirect.y) + fabsf(L_indirect.z);
649                         if(sum_indirect > clamp_indirect) {
650                                 scale = clamp_indirect/sum_indirect;
651                                 L_indirect *= scale;
652
653                                 L->indirect_diffuse *= scale;
654                                 L->indirect_glossy *= scale;
655                                 L->indirect_transmission *= scale;
656                                 L->indirect_subsurface *= scale;
657                                 L->indirect_scatter *= scale;
658                         }
659
660                         /* Sum again, after clamping */
661                         L_sum = L_direct + L_indirect;
662                 }
663 #endif
664         }
665
666         /* No Light Passes */
667         else
668 #endif
669         {
670                 L_sum = L->emission;
671
672                 /* Reject invalid value */
673                 float sum = fabsf((L_sum).x) + fabsf((L_sum).y) + fabsf((L_sum).z);
674                 if(!isfinite_safe(sum)) {
675                         kernel_assert(!"Non-finite final sum in path_radiance_clamp_and_sum!");
676                         L_sum = make_float3(0.0f, 0.0f, 0.0f);
677                 }
678         }
679
680         /* Compute alpha. */
681         *alpha = 1.0f - L->transparent;
682
683         /* Add shadow catcher contributions. */
684 #ifdef __SHADOW_TRICKS__
685         if(L->has_shadow_catcher) {
686                 path_radiance_sum_shadowcatcher(kg, L, &L_sum, alpha);
687         }
688 #endif  /* __SHADOW_TRICKS__ */
689
690         return L_sum;
691 }
692
693 ccl_device_inline void path_radiance_split_denoising(KernelGlobals *kg, PathRadiance *L, float3 *noisy, float3 *clean)
694 {
695 #ifdef __PASSES__
696         kernel_assert(L->use_light_pass);
697
698         *clean = L->emission + L->background;
699         *noisy = L->direct_scatter + L->indirect_scatter;
700
701 #  define ADD_COMPONENT(flag, component)     \
702         if(kernel_data.film.denoising_flags & flag) \
703                 *clean += component;                 \
704         else                                     \
705                 *noisy += component;
706
707         ADD_COMPONENT(DENOISING_CLEAN_DIFFUSE_DIR,      L->direct_diffuse);
708         ADD_COMPONENT(DENOISING_CLEAN_DIFFUSE_IND,      L->indirect_diffuse);
709         ADD_COMPONENT(DENOISING_CLEAN_GLOSSY_DIR,       L->direct_glossy);
710         ADD_COMPONENT(DENOISING_CLEAN_GLOSSY_IND,       L->indirect_glossy);
711         ADD_COMPONENT(DENOISING_CLEAN_TRANSMISSION_DIR, L->direct_transmission);
712         ADD_COMPONENT(DENOISING_CLEAN_TRANSMISSION_IND, L->indirect_transmission);
713         ADD_COMPONENT(DENOISING_CLEAN_SUBSURFACE_DIR,   L->direct_subsurface);
714         ADD_COMPONENT(DENOISING_CLEAN_SUBSURFACE_IND,   L->indirect_subsurface);
715 #  undef ADD_COMPONENT
716 #else
717         *noisy = L->emission;
718         *clean = make_float3(0.0f, 0.0f, 0.0f);
719 #endif
720
721 #ifdef __SHADOW_TRICKS__
722         if(L->has_shadow_catcher) {
723                 *noisy += L->shadow_background_color;
724         }
725 #endif
726
727         *noisy = ensure_finite3(*noisy);
728         *clean = ensure_finite3(*clean);
729 }
730
731 ccl_device_inline void path_radiance_accum_sample(PathRadiance *L, PathRadiance *L_sample)
732 {
733 #ifdef __SPLIT_KERNEL__
734 #  define safe_float3_add(f, v) \
735         do { \
736                 ccl_global float *p = (ccl_global float*)(&(f)); \
737                 atomic_add_and_fetch_float(p+0, (v).x); \
738                 atomic_add_and_fetch_float(p+1, (v).y); \
739                 atomic_add_and_fetch_float(p+2, (v).z); \
740         } while(0)
741 #  define safe_float_add(f, v) \
742                 atomic_add_and_fetch_float(&(f), (v))
743 #else
744 #  define safe_float3_add(f, v) (f) += (v)
745 #  define safe_float_add(f, v) (f) += (v)
746 #endif  /* __SPLIT_KERNEL__ */
747
748 #ifdef __PASSES__
749         safe_float3_add(L->direct_diffuse, L_sample->direct_diffuse);
750         safe_float3_add(L->direct_glossy, L_sample->direct_glossy);
751         safe_float3_add(L->direct_transmission, L_sample->direct_transmission);
752         safe_float3_add(L->direct_subsurface, L_sample->direct_subsurface);
753         safe_float3_add(L->direct_scatter, L_sample->direct_scatter);
754
755         safe_float3_add(L->indirect_diffuse, L_sample->indirect_diffuse);
756         safe_float3_add(L->indirect_glossy, L_sample->indirect_glossy);
757         safe_float3_add(L->indirect_transmission, L_sample->indirect_transmission);
758         safe_float3_add(L->indirect_subsurface, L_sample->indirect_subsurface);
759         safe_float3_add(L->indirect_scatter, L_sample->indirect_scatter);
760
761         safe_float3_add(L->background, L_sample->background);
762         safe_float3_add(L->ao, L_sample->ao);
763         safe_float3_add(L->shadow, L_sample->shadow);
764         safe_float_add(L->mist, L_sample->mist);
765 #endif  /* __PASSES__ */
766         safe_float3_add(L->emission, L_sample->emission);
767
768 #undef safe_float_add
769 #undef safe_float3_add
770 }
771
772 CCL_NAMESPACE_END