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