Fix T47461: Different results on CPU and GPU when using Branched Path Tracing
[blender.git] / intern / cycles / kernel / kernel_accumulate.h
1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 CCL_NAMESPACE_BEGIN
18
19 /* BSDF Eval
20  *
21  * BSDF evaluation result, split per BSDF type. This is used to accumulate
22  * render passes separately. */
23
24 ccl_device_inline void bsdf_eval_init(BsdfEval *eval, ClosureType type, float3 value, int use_light_pass)
25 {
26 #ifdef __PASSES__
27         eval->use_light_pass = use_light_pass;
28
29         if(eval->use_light_pass) {
30                 eval->diffuse = make_float3(0.0f, 0.0f, 0.0f);
31                 eval->glossy = make_float3(0.0f, 0.0f, 0.0f);
32                 eval->transmission = make_float3(0.0f, 0.0f, 0.0f);
33                 eval->transparent = make_float3(0.0f, 0.0f, 0.0f);
34                 eval->subsurface = make_float3(0.0f, 0.0f, 0.0f);
35                 eval->scatter = make_float3(0.0f, 0.0f, 0.0f);
36
37                 if(type == CLOSURE_BSDF_TRANSPARENT_ID)
38                         eval->transparent = value;
39                 else if(CLOSURE_IS_BSDF_DIFFUSE(type))
40                         eval->diffuse = value;
41                 else if(CLOSURE_IS_BSDF_GLOSSY(type))
42                         eval->glossy = value;
43                 else if(CLOSURE_IS_BSDF_TRANSMISSION(type))
44                         eval->transmission = value;
45                 else if(CLOSURE_IS_BSDF_BSSRDF(type))
46                         eval->subsurface = value;
47                 else if(CLOSURE_IS_PHASE(type))
48                         eval->scatter = value;
49         }
50         else
51                 eval->diffuse = value;
52 #else
53         *eval = value;
54 #endif
55 }
56
57 /* TODO(sergey): This is just a workaround for annoying 6.5 compiler bug. */
58 #if !defined(__KERNEL_CUDA__) || __CUDA_ARCH__ < 500
59 ccl_device_inline
60 #else
61 ccl_device_noinline
62 #endif
63 void bsdf_eval_accum(BsdfEval *eval, ClosureType type, float3 value)
64 {
65 #ifdef __PASSES__
66         if(eval->use_light_pass) {
67                 if(CLOSURE_IS_BSDF_DIFFUSE(type))
68                         eval->diffuse += value;
69                 else if(CLOSURE_IS_BSDF_GLOSSY(type))
70                         eval->glossy += value;
71                 else if(CLOSURE_IS_BSDF_TRANSMISSION(type))
72                         eval->transmission += value;
73                 else if(CLOSURE_IS_BSDF_BSSRDF(type))
74                         eval->subsurface += value;
75                 else if(CLOSURE_IS_PHASE(type))
76                         eval->scatter += value;
77
78                 /* skipping transparent, this function is used by for eval(), will be zero then */
79         }
80         else
81                 eval->diffuse += value;
82 #else
83         *eval += value;
84 #endif
85 }
86
87 ccl_device_inline bool bsdf_eval_is_zero(BsdfEval *eval)
88 {
89 #ifdef __PASSES__
90         if(eval->use_light_pass) {
91                 return is_zero(eval->diffuse)
92                         && is_zero(eval->glossy)
93                         && is_zero(eval->transmission)
94                         && is_zero(eval->transparent)
95                         && is_zero(eval->subsurface)
96                         && is_zero(eval->scatter);
97         }
98         else
99                 return is_zero(eval->diffuse);
100 #else
101         return is_zero(*eval);
102 #endif
103 }
104
105 ccl_device_inline void bsdf_eval_mul(BsdfEval *eval, float3 value)
106 {
107 #ifdef __PASSES__
108         if(eval->use_light_pass) {
109                 eval->diffuse *= value;
110                 eval->glossy *= value;
111                 eval->transmission *= value;
112                 eval->subsurface *= value;
113                 eval->scatter *= value;
114
115                 /* skipping transparent, this function is used by for eval(), will be zero then */
116         }
117         else
118                 eval->diffuse *= value;
119 #else
120         *eval *= value;
121 #endif
122 }
123
124 /* Path Radiance
125  *
126  * We accumulate different render passes separately. After summing at the end
127  * to get the combined result, it should be identical. We definite directly
128  * visible as the first non-transparent hit, while indirectly visible are the
129  * bounces after that. */
130
131 ccl_device_inline void path_radiance_init(PathRadiance *L, int use_light_pass)
132 {
133         /* clear all */
134 #ifdef __PASSES__
135         L->use_light_pass = use_light_pass;
136
137         if(use_light_pass) {
138                 L->indirect = make_float3(0.0f, 0.0f, 0.0f);
139                 L->direct_throughput = make_float3(0.0f, 0.0f, 0.0f);
140                 L->direct_emission = make_float3(0.0f, 0.0f, 0.0f);
141
142                 L->color_diffuse = make_float3(0.0f, 0.0f, 0.0f);
143                 L->color_glossy = make_float3(0.0f, 0.0f, 0.0f);
144                 L->color_transmission = make_float3(0.0f, 0.0f, 0.0f);
145                 L->color_subsurface = make_float3(0.0f, 0.0f, 0.0f);
146                 L->color_scatter = make_float3(0.0f, 0.0f, 0.0f);
147
148                 L->direct_diffuse = make_float3(0.0f, 0.0f, 0.0f);
149                 L->direct_glossy = make_float3(0.0f, 0.0f, 0.0f);
150                 L->direct_transmission = make_float3(0.0f, 0.0f, 0.0f);
151                 L->direct_subsurface = make_float3(0.0f, 0.0f, 0.0f);
152                 L->direct_scatter = make_float3(0.0f, 0.0f, 0.0f);
153
154                 L->indirect_diffuse = make_float3(0.0f, 0.0f, 0.0f);
155                 L->indirect_glossy = make_float3(0.0f, 0.0f, 0.0f);
156                 L->indirect_transmission = make_float3(0.0f, 0.0f, 0.0f);
157                 L->indirect_subsurface = make_float3(0.0f, 0.0f, 0.0f);
158                 L->indirect_scatter = make_float3(0.0f, 0.0f, 0.0f);
159
160                 L->path_diffuse = make_float3(0.0f, 0.0f, 0.0f);
161                 L->path_glossy = make_float3(0.0f, 0.0f, 0.0f);
162                 L->path_transmission = make_float3(0.0f, 0.0f, 0.0f);
163                 L->path_subsurface = make_float3(0.0f, 0.0f, 0.0f);
164                 L->path_scatter = make_float3(0.0f, 0.0f, 0.0f);
165
166                 L->emission = make_float3(0.0f, 0.0f, 0.0f);
167                 L->background = make_float3(0.0f, 0.0f, 0.0f);
168                 L->ao = make_float3(0.0f, 0.0f, 0.0f);
169                 L->shadow = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
170                 L->mist = 0.0f;
171         }
172         else
173                 L->emission = make_float3(0.0f, 0.0f, 0.0f);
174 #else
175         *L = make_float3(0.0f, 0.0f, 0.0f);
176 #endif
177 }
178
179 ccl_device_inline void path_radiance_bsdf_bounce(PathRadiance *L, ccl_addr_space float3 *throughput,
180         BsdfEval *bsdf_eval, float bsdf_pdf, int bounce, int bsdf_label)
181 {
182         float inverse_pdf = 1.0f/bsdf_pdf;
183
184 #ifdef __PASSES__
185         if(L->use_light_pass) {
186                 if(bounce == 0 && !(bsdf_label & LABEL_TRANSPARENT)) {
187                         /* first on directly visible surface */
188                         float3 value = *throughput*inverse_pdf;
189
190                         L->path_diffuse = bsdf_eval->diffuse*value;
191                         L->path_glossy = bsdf_eval->glossy*value;
192                         L->path_transmission = bsdf_eval->transmission*value;
193                         L->path_subsurface = bsdf_eval->subsurface*value;
194                         L->path_scatter = bsdf_eval->scatter*value;
195
196                         *throughput = L->path_diffuse + L->path_glossy + L->path_transmission + L->path_subsurface + L->path_scatter;
197                         
198                         L->direct_throughput = *throughput;
199                 }
200                 else {
201                         /* transparent bounce before first hit, or indirectly visible through BSDF */
202                         float3 sum = (bsdf_eval->diffuse + bsdf_eval->glossy + bsdf_eval->transmission + bsdf_eval->transparent +
203                                                   bsdf_eval->subsurface + bsdf_eval->scatter) * inverse_pdf;
204                         *throughput *= sum;
205                 }
206         }
207         else
208                 *throughput *= bsdf_eval->diffuse*inverse_pdf;
209 #else
210         *throughput *= *bsdf_eval*inverse_pdf;
211 #endif
212 }
213
214 ccl_device_inline void path_radiance_accum_emission(PathRadiance *L, float3 throughput, float3 value, int bounce)
215 {
216 #ifdef __PASSES__
217         if(L->use_light_pass) {
218                 if(bounce == 0)
219                         L->emission += throughput*value;
220                 else if(bounce == 1)
221                         L->direct_emission += throughput*value;
222                 else
223                         L->indirect += throughput*value;
224         }
225         else
226                 L->emission += throughput*value;
227 #else
228         *L += throughput*value;
229 #endif
230 }
231
232 ccl_device_inline void path_radiance_accum_ao(PathRadiance *L, float3 throughput, float3 alpha, float3 bsdf, float3 ao, int bounce)
233 {
234 #ifdef __PASSES__
235         if(L->use_light_pass) {
236                 if(bounce == 0) {
237                         /* directly visible lighting */
238                         L->direct_diffuse += throughput*bsdf*ao;
239                         L->ao += alpha*throughput*ao;
240                 }
241                 else {
242                         /* indirectly visible lighting after BSDF bounce */
243                         L->indirect += throughput*bsdf*ao;
244                 }
245         }
246         else
247                 L->emission += throughput*bsdf*ao;
248 #else
249         *L += throughput*bsdf*ao;
250 #endif
251 }
252
253 ccl_device_inline void path_radiance_accum_light(PathRadiance *L, float3 throughput, BsdfEval *bsdf_eval, float3 shadow, float shadow_fac, int bounce, bool is_lamp)
254 {
255 #ifdef __PASSES__
256         if(L->use_light_pass) {
257                 if(bounce == 0) {
258                         /* directly visible lighting */
259                         L->direct_diffuse += throughput*bsdf_eval->diffuse*shadow;
260                         L->direct_glossy += throughput*bsdf_eval->glossy*shadow;
261                         L->direct_transmission += throughput*bsdf_eval->transmission*shadow;
262                         L->direct_subsurface += throughput*bsdf_eval->subsurface*shadow;
263                         L->direct_scatter += throughput*bsdf_eval->scatter*shadow;
264
265                         if(is_lamp) {
266                                 L->shadow.x += shadow.x*shadow_fac;
267                                 L->shadow.y += shadow.y*shadow_fac;
268                                 L->shadow.z += shadow.z*shadow_fac;
269                         }
270                 }
271                 else {
272                         /* indirectly visible lighting after BSDF bounce */
273                         float3 sum = bsdf_eval->diffuse + bsdf_eval->glossy + bsdf_eval->transmission + bsdf_eval->subsurface + bsdf_eval->scatter;
274                         L->indirect += throughput*sum*shadow;
275                 }
276         }
277         else
278                 L->emission += throughput*bsdf_eval->diffuse*shadow;
279 #else
280         *L += throughput*(*bsdf_eval)*shadow;
281 #endif
282 }
283
284 ccl_device_inline void path_radiance_accum_background(PathRadiance *L, float3 throughput, float3 value, int bounce)
285 {
286 #ifdef __PASSES__
287         if(L->use_light_pass) {
288                 if(bounce == 0)
289                         L->background += throughput*value;
290                 else if(bounce == 1)
291                         L->direct_emission += throughput*value;
292                 else
293                         L->indirect += throughput*value;
294         }
295         else
296                 L->emission += throughput*value;
297 #else
298         *L += throughput*value;
299 #endif
300 }
301
302 ccl_device_inline void path_radiance_sum_indirect(PathRadiance *L)
303 {
304 #ifdef __PASSES__
305         /* this division is a bit ugly, but means we only have to keep track of
306          * only a single throughput further along the path, here we recover just
307          * the indirect path that is not influenced by any particular BSDF type */
308         if(L->use_light_pass) {
309                 L->direct_emission = safe_divide_color(L->direct_emission, L->direct_throughput);
310                 L->direct_diffuse += L->path_diffuse*L->direct_emission;
311                 L->direct_glossy += L->path_glossy*L->direct_emission;
312                 L->direct_transmission += L->path_transmission*L->direct_emission;
313                 L->direct_subsurface += L->path_subsurface*L->direct_emission;
314                 L->direct_scatter += L->path_scatter*L->direct_emission;
315
316                 L->indirect = safe_divide_color(L->indirect, L->direct_throughput);
317                 L->indirect_diffuse += L->path_diffuse*L->indirect;
318                 L->indirect_glossy += L->path_glossy*L->indirect;
319                 L->indirect_transmission += L->path_transmission*L->indirect;
320                 L->indirect_subsurface += L->path_subsurface*L->indirect;
321                 L->indirect_scatter += L->path_scatter*L->indirect;
322         }
323 #endif
324 }
325
326 ccl_device_inline void path_radiance_reset_indirect(PathRadiance *L)
327 {
328 #ifdef __PASSES__
329         if(L->use_light_pass) {
330                 L->path_diffuse = make_float3(0.0f, 0.0f, 0.0f);
331                 L->path_glossy = make_float3(0.0f, 0.0f, 0.0f);
332                 L->path_transmission = make_float3(0.0f, 0.0f, 0.0f);
333                 L->path_subsurface = make_float3(0.0f, 0.0f, 0.0f);
334                 L->path_scatter = make_float3(0.0f, 0.0f, 0.0f);
335
336                 L->direct_emission = make_float3(0.0f, 0.0f, 0.0f);
337                 L->indirect = make_float3(0.0f, 0.0f, 0.0f);
338         }
339 #endif
340 }
341
342 ccl_device_inline void path_radiance_copy_indirect(PathRadiance *L,
343                                                    const PathRadiance *L_src)
344 {
345 #ifdef __PASSES__
346         if(L->use_light_pass) {
347                 L->path_diffuse = L_src->path_diffuse;
348                 L->path_glossy = L_src->path_glossy;
349                 L->path_transmission = L_src->path_transmission;
350                 L->path_subsurface = L_src->path_subsurface;
351                 L->path_scatter = L_src->path_scatter;
352
353                 L->direct_emission = L_src->direct_emission;
354                 L->indirect = L_src->indirect;
355         }
356 #endif
357 }
358
359 ccl_device_inline float3 path_radiance_clamp_and_sum(KernelGlobals *kg, PathRadiance *L)
360 {
361         float3 L_sum;
362         /* Light Passes are used */
363 #ifdef __PASSES__
364         float3 L_direct, L_indirect;
365         float clamp_direct = kernel_data.integrator.sample_clamp_direct;
366         float clamp_indirect = kernel_data.integrator.sample_clamp_indirect;
367         if(L->use_light_pass) {
368                 path_radiance_sum_indirect(L);
369
370                 L_direct = L->direct_diffuse + L->direct_glossy + L->direct_transmission + L->direct_subsurface + L->direct_scatter + L->emission;
371                 L_indirect = L->indirect_diffuse + L->indirect_glossy + L->indirect_transmission + L->indirect_subsurface + L->indirect_scatter;
372
373                 if(!kernel_data.background.transparent)
374                         L_direct += L->background;
375
376                 L_sum = L_direct + L_indirect;
377                 float sum = fabsf((L_sum).x) + fabsf((L_sum).y) + fabsf((L_sum).z);
378
379                 /* Reject invalid value */
380                 if(!isfinite(sum)) {
381                         kernel_assert(!"Non-finite sum in path_radiance_clamp_and_sum!");
382                         L_sum = make_float3(0.0f, 0.0f, 0.0f);
383
384                         L->direct_diffuse = make_float3(0.0f, 0.0f, 0.0f);
385                         L->direct_glossy = make_float3(0.0f, 0.0f, 0.0f);
386                         L->direct_transmission = make_float3(0.0f, 0.0f, 0.0f);
387                         L->direct_subsurface = make_float3(0.0f, 0.0f, 0.0f);
388                         L->direct_scatter = make_float3(0.0f, 0.0f, 0.0f);
389
390                         L->indirect_diffuse = make_float3(0.0f, 0.0f, 0.0f);
391                         L->indirect_glossy = make_float3(0.0f, 0.0f, 0.0f);
392                         L->indirect_transmission = make_float3(0.0f, 0.0f, 0.0f);
393                         L->indirect_subsurface = make_float3(0.0f, 0.0f, 0.0f);
394                         L->indirect_scatter = make_float3(0.0f, 0.0f, 0.0f);
395
396                         L->emission = make_float3(0.0f, 0.0f, 0.0f);
397                 }
398
399                 /* Clamp direct and indirect samples */
400 #ifdef __CLAMP_SAMPLE__
401                 else if(sum > clamp_direct || sum > clamp_indirect) {
402                         float scale;
403
404                         /* Direct */
405                         float sum_direct = fabsf(L_direct.x) + fabsf(L_direct.y) + fabsf(L_direct.z);
406                         if(sum_direct > clamp_direct) {
407                                 scale = clamp_direct/sum_direct;
408                                 L_direct *= scale;
409
410                                 L->direct_diffuse *= scale;
411                                 L->direct_glossy *= scale;
412                                 L->direct_transmission *= scale;
413                                 L->direct_subsurface *= scale;
414                                 L->direct_scatter *= scale;
415                                 L->emission *= scale;
416                                 L->background *= scale;
417                         }
418
419                         /* Indirect */
420                         float sum_indirect = fabsf(L_indirect.x) + fabsf(L_indirect.y) + fabsf(L_indirect.z);
421                         if(sum_indirect > clamp_indirect) {
422                                 scale = clamp_indirect/sum_indirect;
423                                 L_indirect *= scale;
424
425                                 L->indirect_diffuse *= scale;
426                                 L->indirect_glossy *= scale;
427                                 L->indirect_transmission *= scale;
428                                 L->indirect_subsurface *= scale;
429                                 L->indirect_scatter *= scale;
430                         }
431
432                         /* Sum again, after clamping */
433                         L_sum = L_direct + L_indirect;
434                 }
435 #endif
436
437                 return L_sum;
438         }
439
440         /* No Light Passes */
441         else
442                 L_sum = L->emission;
443 #else
444         L_sum = *L;
445 #endif
446
447         /* Reject invalid value */
448         float sum = fabsf((L_sum).x) + fabsf((L_sum).y) + fabsf((L_sum).z);
449         if(!isfinite(sum)) {
450                 kernel_assert(!"Non-finite final sum in path_radiance_clamp_and_sum!");
451                 L_sum = make_float3(0.0f, 0.0f, 0.0f);
452         }
453
454         return L_sum;
455 }
456
457 ccl_device_inline void path_radiance_accum_sample(PathRadiance *L, PathRadiance *L_sample, int num_samples)
458 {
459         float fac = 1.0f/num_samples;
460
461 #ifdef __PASSES__
462         L->direct_diffuse += L_sample->direct_diffuse*fac;
463         L->direct_glossy += L_sample->direct_glossy*fac;
464         L->direct_transmission += L_sample->direct_transmission*fac;
465         L->direct_subsurface += L_sample->direct_subsurface*fac;
466         L->direct_scatter += L_sample->direct_scatter*fac;
467
468         L->indirect_diffuse += L_sample->indirect_diffuse*fac;
469         L->indirect_glossy += L_sample->indirect_glossy*fac;
470         L->indirect_transmission += L_sample->indirect_transmission*fac;
471         L->indirect_subsurface += L_sample->indirect_subsurface*fac;
472         L->indirect_scatter += L_sample->indirect_scatter*fac;
473
474         L->emission += L_sample->emission*fac;
475         L->background += L_sample->background*fac;
476         L->ao += L_sample->ao*fac;
477         L->shadow += L_sample->shadow*fac;
478         L->mist += L_sample->mist*fac;
479 #else
480         *L += *L_sample * fac;
481 #endif
482 }
483
484 CCL_NAMESPACE_END
485