Cycles: don't count volume boundaries as transparent bounces.
[blender-staging.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 #ifdef __SHADOW_TRICKS__
324         if(state->flag & PATH_RAY_STORE_SHADOW_INFO) {
325                 float3 light = throughput * bsdf;
326                 L->path_total += light;
327                 L->path_total_shaded += ao * light;
328
329                 if(state->flag & PATH_RAY_SHADOW_CATCHER) {
330                         return;
331                 }
332         }
333 #endif
334
335 #ifdef __PASSES__
336         if(L->use_light_pass) {
337                 if(state->bounce == 0) {
338                         /* directly visible lighting */
339                         L->direct_diffuse += throughput*bsdf*ao;
340                         L->ao += alpha*throughput*ao;
341                 }
342                 else {
343                         /* indirectly visible lighting after BSDF bounce */
344                         L->indirect += throughput*bsdf*ao;
345                 }
346         }
347         else
348 #endif
349         {
350                 L->emission += throughput*bsdf*ao;
351         }
352 }
353
354 ccl_device_inline void path_radiance_accum_total_ao(
355         PathRadiance *L,
356         ccl_addr_space PathState *state,
357         float3 throughput,
358         float3 bsdf)
359 {
360 #ifdef __SHADOW_TRICKS__
361         if(state->flag & PATH_RAY_STORE_SHADOW_INFO) {
362                 L->path_total += throughput * bsdf;
363         }
364 #else
365         (void) L;
366         (void) state;
367         (void) throughput;
368         (void) bsdf;
369 #endif
370 }
371
372 ccl_device_inline void path_radiance_accum_light(PathRadiance *L,
373                                                  ccl_addr_space PathState *state,
374                                                  float3 throughput,
375                                                  BsdfEval *bsdf_eval,
376                                                  float3 shadow,
377                                                  float shadow_fac,
378                                                  bool is_lamp)
379 {
380 #ifdef __SHADOW_TRICKS__
381         if(state->flag & PATH_RAY_STORE_SHADOW_INFO) {
382                 float3 light = throughput * bsdf_eval->sum_no_mis;
383                 L->path_total += light;
384                 L->path_total_shaded += shadow * light;
385
386                 if(state->flag & PATH_RAY_SHADOW_CATCHER) {
387                         return;
388                 }
389         }
390 #endif
391
392 #ifdef __PASSES__
393         if(L->use_light_pass) {
394                 if(state->bounce == 0) {
395                         /* directly visible lighting */
396                         L->direct_diffuse += throughput*bsdf_eval->diffuse*shadow;
397                         L->direct_glossy += throughput*bsdf_eval->glossy*shadow;
398                         L->direct_transmission += throughput*bsdf_eval->transmission*shadow;
399                         L->direct_subsurface += throughput*bsdf_eval->subsurface*shadow;
400                         L->direct_scatter += throughput*bsdf_eval->scatter*shadow;
401
402                         if(is_lamp) {
403                                 L->shadow.x += shadow.x*shadow_fac;
404                                 L->shadow.y += shadow.y*shadow_fac;
405                                 L->shadow.z += shadow.z*shadow_fac;
406                         }
407                 }
408                 else {
409                         /* indirectly visible lighting after BSDF bounce */
410                         L->indirect += throughput*bsdf_eval_sum(bsdf_eval)*shadow;
411                 }
412         }
413         else
414 #endif
415         {
416                 L->emission += throughput*bsdf_eval->diffuse*shadow;
417         }
418 }
419
420 ccl_device_inline void path_radiance_accum_total_light(
421         PathRadiance *L,
422         ccl_addr_space PathState *state,
423         float3 throughput,
424         const BsdfEval *bsdf_eval)
425 {
426 #ifdef __SHADOW_TRICKS__
427         if(state->flag & PATH_RAY_STORE_SHADOW_INFO) {
428                 L->path_total += throughput * bsdf_eval->sum_no_mis;
429         }
430 #else
431         (void) L;
432         (void) state;
433         (void) throughput;
434         (void) bsdf_eval;
435 #endif
436 }
437
438 ccl_device_inline void path_radiance_accum_background(
439         PathRadiance *L,
440         ccl_addr_space PathState *state,
441         float3 throughput,
442         float3 value)
443 {
444
445 #ifdef __SHADOW_TRICKS__
446         if(state->flag & PATH_RAY_STORE_SHADOW_INFO) {
447                 L->path_total += throughput * value;
448                 L->path_total_shaded += throughput * value * L->shadow_transparency;
449
450                 if(state->flag & PATH_RAY_SHADOW_CATCHER) {
451                         return;
452                 }
453         }
454 #endif
455
456 #ifdef __PASSES__
457         if(L->use_light_pass) {
458                 if(state->flag & PATH_RAY_TRANSPARENT_BACKGROUND)
459                         L->background += throughput*value;
460                 else if(state->bounce == 1)
461                         L->direct_emission += throughput*value;
462                 else
463                         L->indirect += throughput*value;
464         }
465         else
466 #endif
467         {
468                 L->emission += throughput*value;
469         }
470
471 #ifdef __DENOISING_FEATURES__
472         L->denoising_albedo += state->denoising_feature_weight * value;
473 #endif  /* __DENOISING_FEATURES__ */
474 }
475
476 ccl_device_inline void path_radiance_accum_transparent(
477         PathRadiance *L,
478         ccl_addr_space PathState *state,
479         float3 throughput)
480 {
481         L->transparent += average(throughput);
482 }
483
484 #ifdef __SHADOW_TRICKS__
485 ccl_device_inline void path_radiance_accum_shadowcatcher(
486         PathRadiance *L,
487         float3 throughput,
488         float3 background)
489 {
490         L->shadow_throughput += average(throughput);
491         L->shadow_background_color += throughput * background;
492         L->has_shadow_catcher = 1;
493 }
494 #endif
495
496 ccl_device_inline void path_radiance_sum_indirect(PathRadiance *L)
497 {
498 #ifdef __PASSES__
499         /* this division is a bit ugly, but means we only have to keep track of
500          * only a single throughput further along the path, here we recover just
501          * the indirect path that is not influenced by any particular BSDF type */
502         if(L->use_light_pass) {
503                 L->direct_emission = safe_divide_color(L->direct_emission, L->state.direct);
504                 L->direct_diffuse += L->state.diffuse*L->direct_emission;
505                 L->direct_glossy += L->state.glossy*L->direct_emission;
506                 L->direct_transmission += L->state.transmission*L->direct_emission;
507                 L->direct_subsurface += L->state.subsurface*L->direct_emission;
508                 L->direct_scatter += L->state.scatter*L->direct_emission;
509
510                 L->indirect = safe_divide_color(L->indirect, L->state.direct);
511                 L->indirect_diffuse += L->state.diffuse*L->indirect;
512                 L->indirect_glossy += L->state.glossy*L->indirect;
513                 L->indirect_transmission += L->state.transmission*L->indirect;
514                 L->indirect_subsurface += L->state.subsurface*L->indirect;
515                 L->indirect_scatter += L->state.scatter*L->indirect;
516         }
517 #endif
518 }
519
520 ccl_device_inline void path_radiance_reset_indirect(PathRadiance *L)
521 {
522 #ifdef __PASSES__
523         if(L->use_light_pass) {
524                 L->state.diffuse = make_float3(0.0f, 0.0f, 0.0f);
525                 L->state.glossy = make_float3(0.0f, 0.0f, 0.0f);
526                 L->state.transmission = make_float3(0.0f, 0.0f, 0.0f);
527                 L->state.subsurface = make_float3(0.0f, 0.0f, 0.0f);
528                 L->state.scatter = make_float3(0.0f, 0.0f, 0.0f);
529
530                 L->direct_emission = make_float3(0.0f, 0.0f, 0.0f);
531                 L->indirect = make_float3(0.0f, 0.0f, 0.0f);
532         }
533 #endif
534 }
535
536 ccl_device_inline void path_radiance_copy_indirect(PathRadiance *L,
537                                                    const PathRadiance *L_src)
538 {
539 #ifdef __PASSES__
540         if(L->use_light_pass) {
541                 L->state = L_src->state;
542
543                 L->direct_emission = L_src->direct_emission;
544                 L->indirect = L_src->indirect;
545         }
546 #endif
547 }
548
549 #ifdef __SHADOW_TRICKS__
550 ccl_device_inline void path_radiance_sum_shadowcatcher(KernelGlobals *kg,
551                                                        PathRadiance *L,
552                                                        float3 *L_sum,
553                                                        float *alpha)
554 {
555         /* Calculate current shadow of the path. */
556         float path_total = average(L->path_total);
557         float shadow;
558
559         if(UNLIKELY(!isfinite_safe(path_total))) {
560                 kernel_assert(!"Non-finite total radiance along the path");
561                 shadow = 0.0f;
562         }
563         else if(path_total == 0.0f) {
564                 shadow = L->shadow_transparency;
565         }
566         else {
567                 float path_total_shaded = average(L->path_total_shaded);
568                 shadow = path_total_shaded / path_total;
569         }
570
571         /* Calculate final light sum and transparency for shadow catcher object. */
572         if(kernel_data.background.transparent) {
573                 *alpha -= L->shadow_throughput * shadow;
574         }
575         else {
576                 L->shadow_background_color *= shadow;
577                 *L_sum += L->shadow_background_color;
578         }
579 }
580 #endif
581
582 ccl_device_inline float3 path_radiance_clamp_and_sum(KernelGlobals *kg, PathRadiance *L, float *alpha)
583 {
584         float3 L_sum;
585         /* Light Passes are used */
586 #ifdef __PASSES__
587         float3 L_direct, L_indirect;
588         float clamp_direct = kernel_data.integrator.sample_clamp_direct;
589         float clamp_indirect = kernel_data.integrator.sample_clamp_indirect;
590         if(L->use_light_pass) {
591                 path_radiance_sum_indirect(L);
592
593                 L_direct = L->direct_diffuse + L->direct_glossy + L->direct_transmission + L->direct_subsurface + L->direct_scatter + L->emission;
594                 L_indirect = L->indirect_diffuse + L->indirect_glossy + L->indirect_transmission + L->indirect_subsurface + L->indirect_scatter;
595
596                 if(!kernel_data.background.transparent)
597                         L_direct += L->background;
598
599                 L_sum = L_direct + L_indirect;
600                 float sum = fabsf((L_sum).x) + fabsf((L_sum).y) + fabsf((L_sum).z);
601
602                 /* Reject invalid value */
603                 if(!isfinite_safe(sum)) {
604                         kernel_assert(!"Non-finite sum in path_radiance_clamp_and_sum!");
605                         L_sum = make_float3(0.0f, 0.0f, 0.0f);
606
607                         L->direct_diffuse = make_float3(0.0f, 0.0f, 0.0f);
608                         L->direct_glossy = make_float3(0.0f, 0.0f, 0.0f);
609                         L->direct_transmission = make_float3(0.0f, 0.0f, 0.0f);
610                         L->direct_subsurface = make_float3(0.0f, 0.0f, 0.0f);
611                         L->direct_scatter = make_float3(0.0f, 0.0f, 0.0f);
612
613                         L->indirect_diffuse = make_float3(0.0f, 0.0f, 0.0f);
614                         L->indirect_glossy = make_float3(0.0f, 0.0f, 0.0f);
615                         L->indirect_transmission = make_float3(0.0f, 0.0f, 0.0f);
616                         L->indirect_subsurface = make_float3(0.0f, 0.0f, 0.0f);
617                         L->indirect_scatter = make_float3(0.0f, 0.0f, 0.0f);
618
619                         L->emission = make_float3(0.0f, 0.0f, 0.0f);
620                 }
621
622                 /* Clamp direct and indirect samples */
623 #ifdef __CLAMP_SAMPLE__
624                 else if(sum > clamp_direct || sum > clamp_indirect) {
625                         float scale;
626
627                         /* Direct */
628                         float sum_direct = fabsf(L_direct.x) + fabsf(L_direct.y) + fabsf(L_direct.z);
629                         if(sum_direct > clamp_direct) {
630                                 scale = clamp_direct/sum_direct;
631                                 L_direct *= scale;
632
633                                 L->direct_diffuse *= scale;
634                                 L->direct_glossy *= scale;
635                                 L->direct_transmission *= scale;
636                                 L->direct_subsurface *= scale;
637                                 L->direct_scatter *= scale;
638                                 L->emission *= scale;
639                                 L->background *= scale;
640                         }
641
642                         /* Indirect */
643                         float sum_indirect = fabsf(L_indirect.x) + fabsf(L_indirect.y) + fabsf(L_indirect.z);
644                         if(sum_indirect > clamp_indirect) {
645                                 scale = clamp_indirect/sum_indirect;
646                                 L_indirect *= scale;
647
648                                 L->indirect_diffuse *= scale;
649                                 L->indirect_glossy *= scale;
650                                 L->indirect_transmission *= scale;
651                                 L->indirect_subsurface *= scale;
652                                 L->indirect_scatter *= scale;
653                         }
654
655                         /* Sum again, after clamping */
656                         L_sum = L_direct + L_indirect;
657                 }
658 #endif
659         }
660
661         /* No Light Passes */
662         else
663 #endif
664         {
665                 L_sum = L->emission;
666
667                 /* Reject invalid value */
668                 float sum = fabsf((L_sum).x) + fabsf((L_sum).y) + fabsf((L_sum).z);
669                 if(!isfinite_safe(sum)) {
670                         kernel_assert(!"Non-finite final sum in path_radiance_clamp_and_sum!");
671                         L_sum = make_float3(0.0f, 0.0f, 0.0f);
672                 }
673         }
674
675         /* Compute alpha. */
676         *alpha = 1.0f - L->transparent;
677
678         /* Add shadow catcher contributions. */
679 #ifdef __SHADOW_TRICKS__
680         if(L->has_shadow_catcher) {
681                 path_radiance_sum_shadowcatcher(kg, L, &L_sum, alpha);
682         }
683 #endif  /* __SHADOW_TRICKS__ */
684
685         return L_sum;
686 }
687
688 ccl_device_inline void path_radiance_split_denoising(KernelGlobals *kg, PathRadiance *L, float3 *noisy, float3 *clean)
689 {
690 #ifdef __PASSES__
691         kernel_assert(L->use_light_pass);
692
693         *clean = L->emission + L->background;
694         *noisy = L->direct_scatter + L->indirect_scatter;
695
696 #  define ADD_COMPONENT(flag, component)     \
697         if(kernel_data.film.denoising_flags & flag) \
698                 *clean += component;                 \
699         else                                     \
700                 *noisy += component;
701
702         ADD_COMPONENT(DENOISING_CLEAN_DIFFUSE_DIR,      L->direct_diffuse);
703         ADD_COMPONENT(DENOISING_CLEAN_DIFFUSE_IND,      L->indirect_diffuse);
704         ADD_COMPONENT(DENOISING_CLEAN_GLOSSY_DIR,       L->direct_glossy);
705         ADD_COMPONENT(DENOISING_CLEAN_GLOSSY_IND,       L->indirect_glossy);
706         ADD_COMPONENT(DENOISING_CLEAN_TRANSMISSION_DIR, L->direct_transmission);
707         ADD_COMPONENT(DENOISING_CLEAN_TRANSMISSION_IND, L->indirect_transmission);
708         ADD_COMPONENT(DENOISING_CLEAN_SUBSURFACE_DIR,   L->direct_subsurface);
709         ADD_COMPONENT(DENOISING_CLEAN_SUBSURFACE_IND,   L->indirect_subsurface);
710 #  undef ADD_COMPONENT
711 #else
712         *noisy = L->emission;
713         *clean = make_float3(0.0f, 0.0f, 0.0f);
714 #endif
715
716 #ifdef __SHADOW_TRICKS__
717         if(L->has_shadow_catcher) {
718                 *noisy += L->shadow_background_color;
719         }
720 #endif
721
722         *noisy = ensure_finite3(*noisy);
723         *clean = ensure_finite3(*clean);
724 }
725
726 ccl_device_inline void path_radiance_accum_sample(PathRadiance *L, PathRadiance *L_sample)
727 {
728 #ifdef __SPLIT_KERNEL__
729 #  define safe_float3_add(f, v) \
730         do { \
731                 ccl_global float *p = (ccl_global float*)(&(f)); \
732                 atomic_add_and_fetch_float(p+0, (v).x); \
733                 atomic_add_and_fetch_float(p+1, (v).y); \
734                 atomic_add_and_fetch_float(p+2, (v).z); \
735         } while(0)
736 #  define safe_float_add(f, v) \
737                 atomic_add_and_fetch_float(&(f), (v))
738 #else
739 #  define safe_float3_add(f, v) (f) += (v)
740 #  define safe_float_add(f, v) (f) += (v)
741 #endif  /* __SPLIT_KERNEL__ */
742
743 #ifdef __PASSES__
744         safe_float3_add(L->direct_diffuse, L_sample->direct_diffuse);
745         safe_float3_add(L->direct_glossy, L_sample->direct_glossy);
746         safe_float3_add(L->direct_transmission, L_sample->direct_transmission);
747         safe_float3_add(L->direct_subsurface, L_sample->direct_subsurface);
748         safe_float3_add(L->direct_scatter, L_sample->direct_scatter);
749
750         safe_float3_add(L->indirect_diffuse, L_sample->indirect_diffuse);
751         safe_float3_add(L->indirect_glossy, L_sample->indirect_glossy);
752         safe_float3_add(L->indirect_transmission, L_sample->indirect_transmission);
753         safe_float3_add(L->indirect_subsurface, L_sample->indirect_subsurface);
754         safe_float3_add(L->indirect_scatter, L_sample->indirect_scatter);
755
756         safe_float3_add(L->background, L_sample->background);
757         safe_float3_add(L->ao, L_sample->ao);
758         safe_float3_add(L->shadow, L_sample->shadow);
759         safe_float_add(L->mist, L_sample->mist);
760 #endif  /* __PASSES__ */
761         safe_float3_add(L->emission, L_sample->emission);
762
763 #undef safe_float_add
764 #undef safe_float3_add
765 }
766
767 CCL_NAMESPACE_END