Blender  V3.3
accumulate.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright 2011-2022 Blender Foundation */
3 
4 #pragma once
5 
8 
10 
12 
13 /* --------------------------------------------------------------------
14  * BSDF Evaluation
15  *
16  * BSDF evaluation result, split between diffuse and glossy. This is used to
17  * accumulate render passes separately. Note that reflection, transmission
18  * and volume scattering are written to different render passes, but we assume
19  * that only one of those can happen at a bounce, and so do not need to accumulate
20  * them separately. */
21 
23  const ClosureType closure_type,
24  float3 value)
25 {
26  eval->diffuse = zero_float3();
27  eval->glossy = zero_float3();
28 
29  if (CLOSURE_IS_BSDF_DIFFUSE(closure_type)) {
30  eval->diffuse = value;
31  }
32  else if (CLOSURE_IS_BSDF_GLOSSY(closure_type)) {
33  eval->glossy = value;
34  }
35 
36  eval->sum = value;
37 }
38 
40  const ClosureType closure_type,
41  float3 value)
42 {
43  if (CLOSURE_IS_BSDF_DIFFUSE(closure_type)) {
44  eval->diffuse += value;
45  }
46  else if (CLOSURE_IS_BSDF_GLOSSY(closure_type)) {
47  eval->glossy += value;
48  }
49 
50  eval->sum += value;
51 }
52 
54 {
55  return is_zero(eval->sum);
56 }
57 
59 {
60  eval->diffuse *= value;
61  eval->glossy *= value;
62  eval->sum *= value;
63 }
64 
66 {
67  eval->diffuse *= value;
68  eval->glossy *= value;
69  eval->sum *= value;
70 }
71 
73 {
74  return eval->sum;
75 }
76 
78 {
79  /* Ratio of diffuse weight to recover proportions for writing to render pass.
80  * We assume reflection, transmission and volume scatter to be exclusive. */
81  return safe_divide(eval->diffuse, eval->sum);
82 }
83 
85 {
86  /* Ratio of glossy weight to recover proportions for writing to render pass.
87  * We assume reflection, transmission and volume scatter to be exclusive. */
88  return safe_divide(eval->glossy, eval->sum);
89 }
90 
91 /* --------------------------------------------------------------------
92  * Clamping
93  *
94  * Clamping is done on a per-contribution basis so that we can write directly
95  * to render buffers instead of using per-thread memory, and to avoid the
96  * impact of clamping on other contributions. */
97 
99 {
100 #ifdef __KERNEL_DEBUG_NAN__
101  if (!isfinite_safe(*L)) {
102  kernel_assert(!"Cycles sample with non-finite value detected");
103  }
104 #endif
105  /* Make sure all components are finite, allowing the contribution to be usable by adaptive
106  * sampling convergence check, but also to make it so render result never causes issues with
107  * post-processing. */
108  *L = ensure_finite(*L);
109 
110 #ifdef __CLAMP_SAMPLE__
111  float limit = (bounce > 0) ? kernel_data.integrator.sample_clamp_indirect :
112  kernel_data.integrator.sample_clamp_direct;
113  float sum = reduce_add(fabs(*L));
114  if (sum > limit) {
115  *L *= limit / sum;
116  }
117 #endif
118 }
119 
120 /* --------------------------------------------------------------------
121  * Pass accumulation utilities.
122  */
123 
124 /* Get pointer to pixel in render buffer. */
127 {
129  const uint64_t render_buffer_offset = (uint64_t)render_pixel_index *
130  kernel_data.film.pass_stride;
131  return render_buffer + render_buffer_offset;
132 }
133 
134 /* --------------------------------------------------------------------
135  * Adaptive sampling.
136  */
137 
141  int sample,
142  int sample_offset)
143 {
144  if (kernel_data.film.pass_sample_count == PASS_UNUSED) {
145  return sample;
146  }
147 
149 
151  (ccl_global uint *)(buffer) + kernel_data.film.pass_sample_count, 1) +
152  sample_offset;
153 }
154 
156  const int sample,
157  const float3 contribution,
159 {
160  /* Adaptive Sampling. Fill the additional buffer with the odd samples and calculate our stopping
161  * criteria. This is the heuristic from "A hierarchical automatic stopping condition for Monte
162  * Carlo global illumination" except that here it is applied per pixel and not in hierarchical
163  * tiles. */
164 
165  if (kernel_data.film.pass_adaptive_aux_buffer == PASS_UNUSED) {
166  return;
167  }
168 
169  if (sample_is_even(kernel_data.integrator.sampling_pattern, sample)) {
171  buffer + kernel_data.film.pass_adaptive_aux_buffer,
172  make_float4(contribution.x * 2.0f, contribution.y * 2.0f, contribution.z * 2.0f, 0.0f));
173  }
174 }
175 
176 /* --------------------------------------------------------------------
177  * Shadow catcher.
178  */
179 
180 #ifdef __SHADOW_CATCHER__
181 
182 /* Accumulate contribution to the Shadow Catcher pass.
183  *
184  * Returns truth if the contribution is fully handled here and is not to be added to the other
185  * passes (like combined, adaptive sampling). */
186 
187 ccl_device bool kernel_accum_shadow_catcher(KernelGlobals kg,
188  const uint32_t path_flag,
189  const float3 contribution,
191 {
192  if (!kernel_data.integrator.has_shadow_catcher) {
193  return false;
194  }
195 
196  kernel_assert(kernel_data.film.pass_shadow_catcher != PASS_UNUSED);
197  kernel_assert(kernel_data.film.pass_shadow_catcher_matte != PASS_UNUSED);
198 
199  /* Matte pass. */
200  if (kernel_shadow_catcher_is_matte_path(path_flag)) {
201  kernel_write_pass_float3(buffer + kernel_data.film.pass_shadow_catcher_matte, contribution);
202  /* NOTE: Accumulate the combined pass and to the samples count pass, so that the adaptive
203  * sampling is based on how noisy the combined pass is as if there were no catchers in the
204  * scene. */
205  }
206 
207  /* Shadow catcher pass. */
208  if (kernel_shadow_catcher_is_object_pass(path_flag)) {
209  kernel_write_pass_float3(buffer + kernel_data.film.pass_shadow_catcher, contribution);
210  return true;
211  }
212 
213  return false;
214 }
215 
216 ccl_device bool kernel_accum_shadow_catcher_transparent(KernelGlobals kg,
217  const uint32_t path_flag,
218  const float3 contribution,
219  const float transparent,
221 {
222  if (!kernel_data.integrator.has_shadow_catcher) {
223  return false;
224  }
225 
226  kernel_assert(kernel_data.film.pass_shadow_catcher != PASS_UNUSED);
227  kernel_assert(kernel_data.film.pass_shadow_catcher_matte != PASS_UNUSED);
228 
229  if (path_flag & PATH_RAY_SHADOW_CATCHER_BACKGROUND) {
230  return true;
231  }
232 
233  /* Matte pass. */
234  if (kernel_shadow_catcher_is_matte_path(path_flag)) {
236  buffer + kernel_data.film.pass_shadow_catcher_matte,
237  make_float4(contribution.x, contribution.y, contribution.z, transparent));
238  /* NOTE: Accumulate the combined pass and to the samples count pass, so that the adaptive
239  * sampling is based on how noisy the combined pass is as if there were no catchers in the
240  * scene. */
241  }
242 
243  /* Shadow catcher pass. */
244  if (kernel_shadow_catcher_is_object_pass(path_flag)) {
245  /* NOTE: The transparency of the shadow catcher pass is ignored. It is not needed for the
246  * calculation and the alpha channel of the pass contains numbers of samples contributed to a
247  * pixel of the pass. */
248  kernel_write_pass_float3(buffer + kernel_data.film.pass_shadow_catcher, contribution);
249  return true;
250  }
251 
252  return false;
253 }
254 
255 ccl_device void kernel_accum_shadow_catcher_transparent_only(KernelGlobals kg,
256  const uint32_t path_flag,
257  const float transparent,
259 {
260  if (!kernel_data.integrator.has_shadow_catcher) {
261  return;
262  }
263 
264  kernel_assert(kernel_data.film.pass_shadow_catcher_matte != PASS_UNUSED);
265 
266  /* Matte pass. */
267  if (kernel_shadow_catcher_is_matte_path(path_flag)) {
268  kernel_write_pass_float(buffer + kernel_data.film.pass_shadow_catcher_matte + 3, transparent);
269  }
270 }
271 
272 #endif /* __SHADOW_CATCHER__ */
273 
274 /* --------------------------------------------------------------------
275  * Render passes.
276  */
277 
278 /* Write combined pass. */
280  const uint32_t path_flag,
281  const int sample,
282  const float3 contribution,
284 {
285 #ifdef __SHADOW_CATCHER__
286  if (kernel_accum_shadow_catcher(kg, path_flag, contribution, buffer)) {
287  return;
288  }
289 #endif
290 
291  if (kernel_data.film.light_pass_flag & PASSMASK(COMBINED)) {
292  kernel_write_pass_float3(buffer + kernel_data.film.pass_combined, contribution);
293  }
294 
295  kernel_accum_adaptive_buffer(kg, sample, contribution, buffer);
296 }
297 
298 /* Write combined pass with transparency. */
300  const uint32_t path_flag,
301  const int sample,
302  const float3 contribution,
303  const float transparent,
304  ccl_global float *ccl_restrict
305  buffer)
306 {
307 #ifdef __SHADOW_CATCHER__
308  if (kernel_accum_shadow_catcher_transparent(kg, path_flag, contribution, transparent, buffer)) {
309  return;
310  }
311 #endif
312 
313  if (kernel_data.film.light_pass_flag & PASSMASK(COMBINED)) {
315  buffer + kernel_data.film.pass_combined,
316  make_float4(contribution.x, contribution.y, contribution.z, transparent));
317  }
318 
319  kernel_accum_adaptive_buffer(kg, sample, contribution, buffer);
320 }
321 
322 /* Write background or emission to appropriate pass. */
324  KernelGlobals kg,
326  float3 contribution,
328  const int pass,
329  const int lightgroup = LIGHTGROUP_NONE)
330 {
331  if (!(kernel_data.film.light_pass_flag & PASS_ANY)) {
332  return;
333  }
334 
335 #ifdef __PASSES__
336  const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
337  int pass_offset = PASS_UNUSED;
338 
339  /* Denoising albedo. */
340 # ifdef __DENOISING_FEATURES__
341  if (path_flag & PATH_RAY_DENOISING_FEATURES) {
342  if (kernel_data.film.pass_denoising_albedo != PASS_UNUSED) {
343  const float3 denoising_feature_throughput = INTEGRATOR_STATE(
344  state, path, denoising_feature_throughput);
345  const float3 denoising_albedo = denoising_feature_throughput * contribution;
346  kernel_write_pass_float3(buffer + kernel_data.film.pass_denoising_albedo, denoising_albedo);
347  }
348  }
349 # endif /* __DENOISING_FEATURES__ */
350 
351  const bool is_shadowcatcher = (path_flag & PATH_RAY_SHADOW_CATCHER_HIT) != 0;
352  if (!is_shadowcatcher && lightgroup != LIGHTGROUP_NONE &&
353  kernel_data.film.pass_lightgroup != PASS_UNUSED) {
354  kernel_write_pass_float3(buffer + kernel_data.film.pass_lightgroup + 3 * lightgroup,
355  contribution);
356  }
357 
358  if (!(path_flag & PATH_RAY_ANY_PASS)) {
359  /* Directly visible, write to emission or background pass. */
360  pass_offset = pass;
361  }
362  else if (is_shadowcatcher) {
363  /* Don't write any light passes for shadow catcher, for easier
364  * compositing back together of the combined pass. */
365  return;
366  }
367  else if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) {
368  if (path_flag & PATH_RAY_SURFACE_PASS) {
369  /* Indirectly visible through reflection. */
370  const float3 diffuse_weight = INTEGRATOR_STATE(state, path, pass_diffuse_weight);
371  const float3 glossy_weight = INTEGRATOR_STATE(state, path, pass_glossy_weight);
372 
373  /* Glossy */
374  const int glossy_pass_offset = ((INTEGRATOR_STATE(state, path, bounce) == 1) ?
375  kernel_data.film.pass_glossy_direct :
376  kernel_data.film.pass_glossy_indirect);
377  if (glossy_pass_offset != PASS_UNUSED) {
378  kernel_write_pass_float3(buffer + glossy_pass_offset, glossy_weight * contribution);
379  }
380 
381  /* Transmission */
382  const int transmission_pass_offset = ((INTEGRATOR_STATE(state, path, bounce) == 1) ?
383  kernel_data.film.pass_transmission_direct :
384  kernel_data.film.pass_transmission_indirect);
385 
386  if (transmission_pass_offset != PASS_UNUSED) {
387  /* Transmission is what remains if not diffuse and glossy, not stored explicitly to save
388  * GPU memory. */
389  const float3 transmission_weight = one_float3() - diffuse_weight - glossy_weight;
390  kernel_write_pass_float3(buffer + transmission_pass_offset,
391  transmission_weight * contribution);
392  }
393 
394  /* Reconstruct diffuse subset of throughput. */
395  pass_offset = (INTEGRATOR_STATE(state, path, bounce) == 1) ?
396  kernel_data.film.pass_diffuse_direct :
397  kernel_data.film.pass_diffuse_indirect;
398  if (pass_offset != PASS_UNUSED) {
399  contribution *= diffuse_weight;
400  }
401  }
402  else if (path_flag & PATH_RAY_VOLUME_PASS) {
403  /* Indirectly visible through volume. */
404  pass_offset = (INTEGRATOR_STATE(state, path, bounce) == 1) ?
405  kernel_data.film.pass_volume_direct :
406  kernel_data.film.pass_volume_indirect;
407  }
408  }
409 
410  /* Single write call for GPU coherence. */
411  if (pass_offset != PASS_UNUSED) {
412  kernel_write_pass_float3(buffer + pass_offset, contribution);
413  }
414 #endif /* __PASSES__ */
415 }
416 
417 /* Write light contribution to render buffer. */
421 {
422  /* The throughput for shadow paths already contains the light shader evaluation. */
423  float3 contribution = INTEGRATOR_STATE(state, shadow_path, throughput);
424  kernel_accum_clamp(kg, &contribution, INTEGRATOR_STATE(state, shadow_path, bounce));
425 
427  const uint64_t render_buffer_offset = (uint64_t)render_pixel_index *
428  kernel_data.film.pass_stride;
429  ccl_global float *buffer = render_buffer + render_buffer_offset;
430 
431  const uint32_t path_flag = INTEGRATOR_STATE(state, shadow_path, flag);
432  const int sample = INTEGRATOR_STATE(state, shadow_path, sample);
433 
434  /* Ambient occlusion. */
435  if (path_flag & PATH_RAY_SHADOW_FOR_AO) {
436  if ((kernel_data.kernel_features & KERNEL_FEATURE_AO_PASS) && (path_flag & PATH_RAY_CAMERA)) {
437  kernel_write_pass_float3(buffer + kernel_data.film.pass_ao, contribution);
438  }
439  if (kernel_data.kernel_features & KERNEL_FEATURE_AO_ADDITIVE) {
440  const float3 ao_weight = INTEGRATOR_STATE(state, shadow_path, unshadowed_throughput);
441  kernel_accum_combined_pass(kg, path_flag, sample, contribution * ao_weight, buffer);
442  }
443  return;
444  }
445 
446  /* Direct light shadow. */
447  kernel_accum_combined_pass(kg, path_flag, sample, contribution, buffer);
448 
449 #ifdef __PASSES__
450  if (kernel_data.film.light_pass_flag & PASS_ANY) {
451  const uint32_t path_flag = INTEGRATOR_STATE(state, shadow_path, flag);
452 
453  /* Don't write any light passes for shadow catcher, for easier
454  * compositing back together of the combined pass. */
455  if (path_flag & PATH_RAY_SHADOW_CATCHER_HIT) {
456  return;
457  }
458 
459  /* Write lightgroup pass. LIGHTGROUP_NONE is ~0 so decode from unsigned to signed */
460  const int lightgroup = (int)(INTEGRATOR_STATE(state, shadow_path, lightgroup)) - 1;
461  if (lightgroup != LIGHTGROUP_NONE && kernel_data.film.pass_lightgroup != PASS_UNUSED) {
462  kernel_write_pass_float3(buffer + kernel_data.film.pass_lightgroup + 3 * lightgroup,
463  contribution);
464  }
465 
466  if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) {
467  int pass_offset = PASS_UNUSED;
468 
469  if (path_flag & PATH_RAY_SURFACE_PASS) {
470  /* Indirectly visible through reflection. */
471  const float3 diffuse_weight = INTEGRATOR_STATE(state, shadow_path, pass_diffuse_weight);
472  const float3 glossy_weight = INTEGRATOR_STATE(state, shadow_path, pass_glossy_weight);
473 
474  /* Glossy */
475  const int glossy_pass_offset = ((INTEGRATOR_STATE(state, shadow_path, bounce) == 0) ?
476  kernel_data.film.pass_glossy_direct :
477  kernel_data.film.pass_glossy_indirect);
478  if (glossy_pass_offset != PASS_UNUSED) {
479  kernel_write_pass_float3(buffer + glossy_pass_offset, glossy_weight * contribution);
480  }
481 
482  /* Transmission */
483  const int transmission_pass_offset = ((INTEGRATOR_STATE(state, shadow_path, bounce) == 0) ?
484  kernel_data.film.pass_transmission_direct :
485  kernel_data.film.pass_transmission_indirect);
486 
487  if (transmission_pass_offset != PASS_UNUSED) {
488  /* Transmission is what remains if not diffuse and glossy, not stored explicitly to save
489  * GPU memory. */
490  const float3 transmission_weight = one_float3() - diffuse_weight - glossy_weight;
491  kernel_write_pass_float3(buffer + transmission_pass_offset,
492  transmission_weight * contribution);
493  }
494 
495  /* Reconstruct diffuse subset of throughput. */
496  pass_offset = (INTEGRATOR_STATE(state, shadow_path, bounce) == 0) ?
497  kernel_data.film.pass_diffuse_direct :
498  kernel_data.film.pass_diffuse_indirect;
499  if (pass_offset != PASS_UNUSED) {
500  contribution *= diffuse_weight;
501  }
502  }
503  else if (path_flag & PATH_RAY_VOLUME_PASS) {
504  /* Indirectly visible through volume. */
505  pass_offset = (INTEGRATOR_STATE(state, shadow_path, bounce) == 0) ?
506  kernel_data.film.pass_volume_direct :
507  kernel_data.film.pass_volume_indirect;
508  }
509 
510  /* Single write call for GPU coherence. */
511  if (pass_offset != PASS_UNUSED) {
512  kernel_write_pass_float3(buffer + pass_offset, contribution);
513  }
514  }
515 
516  /* Write shadow pass. */
517  if (kernel_data.film.pass_shadow != PASS_UNUSED && (path_flag & PATH_RAY_SHADOW_FOR_LIGHT) &&
518  (path_flag & PATH_RAY_TRANSPARENT_BACKGROUND)) {
519  const float3 unshadowed_throughput = INTEGRATOR_STATE(
520  state, shadow_path, unshadowed_throughput);
521  const float3 shadowed_throughput = INTEGRATOR_STATE(state, shadow_path, throughput);
522  const float3 shadow = safe_divide(shadowed_throughput, unshadowed_throughput) *
523  kernel_data.film.pass_shadow_scale;
524  kernel_write_pass_float3(buffer + kernel_data.film.pass_shadow, shadow);
525  }
526  }
527 #endif
528 }
529 
530 /* Write transparency to render buffer.
531  *
532  * Note that we accumulate transparency = 1 - alpha in the render buffer.
533  * Otherwise we'd have to write alpha on path termination, which happens
534  * in many places. */
537  const uint32_t path_flag,
538  const float transparent,
540 {
541  if (kernel_data.film.light_pass_flag & PASSMASK(COMBINED)) {
542  kernel_write_pass_float(buffer + kernel_data.film.pass_combined + 3, transparent);
543  }
544 
545  kernel_accum_shadow_catcher_transparent_only(kg, path_flag, transparent, buffer);
546 }
547 
548 /* Write holdout to render buffer. */
551  const uint32_t path_flag,
552  const float transparent,
554 {
556  kernel_accum_transparent(kg, state, path_flag, transparent, buffer);
557 }
558 
559 /* Write background contribution to render buffer.
560  *
561  * Includes transparency, matching kernel_accum_transparent. */
564  const float3 L,
565  const float transparent,
566  const bool is_transparent_background_ray,
568 {
569  float3 contribution = float3(INTEGRATOR_STATE(state, path, throughput)) * L;
570  kernel_accum_clamp(kg, &contribution, INTEGRATOR_STATE(state, path, bounce) - 1);
571 
573  const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
574 
575  if (is_transparent_background_ray) {
576  kernel_accum_transparent(kg, state, path_flag, transparent, buffer);
577  }
578  else {
579  const int sample = INTEGRATOR_STATE(state, path, sample);
581  kg, path_flag, sample, contribution, transparent, buffer);
582  }
584  state,
585  contribution,
586  buffer,
587  kernel_data.film.pass_background,
588  kernel_data.background.lightgroup);
589 }
590 
591 /* Write emission to render buffer. */
594  const float3 L,
596  const int lightgroup = LIGHTGROUP_NONE)
597 {
598  float3 contribution = L;
599  kernel_accum_clamp(kg, &contribution, INTEGRATOR_STATE(state, path, bounce) - 1);
600 
602  const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
603  const int sample = INTEGRATOR_STATE(state, path, sample);
604 
605  kernel_accum_combined_pass(kg, path_flag, sample, contribution, buffer);
607  kg, state, contribution, buffer, kernel_data.film.pass_emission, lightgroup);
608 }
609 
unsigned int uint
Definition: BLI_sys_types.h:67
float float3[3]
ccl_device_inline float3 bsdf_eval_pass_diffuse_weight(ccl_private const BsdfEval *eval)
Definition: accumulate.h:77
ccl_device_inline void bsdf_eval_accum(ccl_private BsdfEval *eval, const ClosureType closure_type, float3 value)
Definition: accumulate.h:39
ccl_device_inline void kernel_accum_transparent(KernelGlobals kg, ConstIntegratorState state, const uint32_t path_flag, const float transparent, ccl_global float *ccl_restrict buffer)
Definition: accumulate.h:535
ccl_device_inline void bsdf_eval_mul(ccl_private BsdfEval *eval, float value)
Definition: accumulate.h:58
ccl_device_inline void kernel_accum_background(KernelGlobals kg, ConstIntegratorState state, const float3 L, const float transparent, const bool is_transparent_background_ray, ccl_global float *ccl_restrict render_buffer)
Definition: accumulate.h:562
ccl_device_inline float3 bsdf_eval_pass_glossy_weight(ccl_private const BsdfEval *eval)
Definition: accumulate.h:84
ccl_device_inline bool bsdf_eval_is_zero(ccl_private BsdfEval *eval)
Definition: accumulate.h:53
ccl_device_inline void kernel_accum_emission_or_background_pass(KernelGlobals kg, ConstIntegratorState state, float3 contribution, ccl_global float *ccl_restrict buffer, const int pass, const int lightgroup=LIGHTGROUP_NONE)
Definition: accumulate.h:323
ccl_device_inline void kernel_accum_holdout(KernelGlobals kg, ConstIntegratorState state, const uint32_t path_flag, const float transparent, ccl_global float *ccl_restrict render_buffer)
Definition: accumulate.h:549
ccl_device_forceinline void kernel_accum_clamp(KernelGlobals kg, ccl_private float3 *L, int bounce)
Definition: accumulate.h:98
ccl_device_inline void kernel_accum_emission(KernelGlobals kg, ConstIntegratorState state, const float3 L, ccl_global float *ccl_restrict render_buffer, const int lightgroup=LIGHTGROUP_NONE)
Definition: accumulate.h:592
ccl_device_forceinline ccl_global float * kernel_accum_pixel_render_buffer(KernelGlobals kg, ConstIntegratorState state, ccl_global float *ccl_restrict render_buffer)
Definition: accumulate.h:125
ccl_device_inline float3 bsdf_eval_sum(ccl_private const BsdfEval *eval)
Definition: accumulate.h:72
ccl_device_inline void kernel_accum_light(KernelGlobals kg, ConstIntegratorShadowState state, ccl_global float *ccl_restrict render_buffer)
Definition: accumulate.h:418
ccl_device_inline void kernel_accum_combined_transparent_pass(KernelGlobals kg, const uint32_t path_flag, const int sample, const float3 contribution, const float transparent, ccl_global float *ccl_restrict buffer)
Definition: accumulate.h:299
ccl_device void kernel_accum_adaptive_buffer(KernelGlobals kg, const int sample, const float3 contribution, ccl_global float *ccl_restrict buffer)
Definition: accumulate.h:155
ccl_device_inline void kernel_accum_combined_pass(KernelGlobals kg, const uint32_t path_flag, const int sample, const float3 contribution, ccl_global float *ccl_restrict buffer)
Definition: accumulate.h:279
ccl_device_inline int kernel_accum_sample(KernelGlobals kg, ConstIntegratorState state, ccl_global float *ccl_restrict render_buffer, int sample, int sample_offset)
Definition: accumulate.h:138
CCL_NAMESPACE_BEGIN ccl_device_inline void bsdf_eval_init(ccl_private BsdfEval *eval, const ClosureType closure_type, float3 value)
Definition: accumulate.h:22
ATOMIC_INLINE uint32_t atomic_fetch_and_add_uint32(uint32_t *p, uint32_t x)
__forceinline int reduce_add(const avxi &v)
Definition: avxi.h:696
static T sum(const btAlignedObjectArray< T > &items)
#define kernel_assert(cond)
Definition: cpu/compat.h:34
#define ccl_restrict
Definition: cuda/compat.h:50
#define ccl_device_forceinline
Definition: cuda/compat.h:35
#define ccl_device
Definition: cuda/compat.h:32
#define ccl_private
Definition: cuda/compat.h:48
#define ccl_device_inline
Definition: cuda/compat.h:34
#define ccl_global
Definition: cuda/compat.h:43
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
#define kernel_data
const KernelGlobalsCPU *ccl_restrict KernelGlobals
ccl_global float * buffer
ccl_gpu_kernel_postfix ccl_global KernelWorkTile const int ccl_global float * render_buffer
const uint64_t render_pixel_index
const int state
#define CLOSURE_IS_BSDF_GLOSSY(type)
#define CLOSURE_IS_BSDF_DIFFUSE(type)
ClosureType
#define PASS_UNUSED
Definition: kernel/types.h:44
@ PATH_RAY_SHADOW_FOR_AO
Definition: kernel/types.h:275
@ PATH_RAY_SHADOW_CATCHER_HIT
Definition: kernel/types.h:278
@ PATH_RAY_VOLUME_PASS
Definition: kernel/types.h:270
@ PATH_RAY_DENOISING_FEATURES
Definition: kernel/types.h:266
@ PATH_RAY_SHADOW_FOR_LIGHT
Definition: kernel/types.h:274
@ PATH_RAY_SURFACE_PASS
Definition: kernel/types.h:269
@ PATH_RAY_TRANSPARENT_BACKGROUND
Definition: kernel/types.h:235
@ PATH_RAY_SHADOW_CATCHER_BACKGROUND
Definition: kernel/types.h:288
@ PATH_RAY_CAMERA
Definition: kernel/types.h:194
@ PATH_RAY_ANY_PASS
Definition: kernel/types.h:271
@ KERNEL_FEATURE_LIGHT_PASSES
@ KERNEL_FEATURE_AO_PASS
@ KERNEL_FEATURE_AO_ADDITIVE
#define LIGHTGROUP_NONE
Definition: kernel/types.h:45
#define PASSMASK(pass)
Definition: kernel/types.h:331
#define PASS_ANY
Definition: kernel/types.h:405
ccl_device_inline float2 fabs(const float2 &a)
Definition: math_float2.h:222
ccl_device_inline float3 one_float3()
Definition: math_float3.h:89
ccl_device_inline float3 zero_float3()
Definition: math_float3.h:80
#define L
#define make_float4(x, y, z, w)
Definition: metal/compat.h:205
bool is_zero(const T &a)
T safe_divide(const T &a, const T &b)
ccl_device_inline bool sample_is_even(int pattern, int sample)
Definition: pattern.h:148
const IntegratorShadowStateCPU *ccl_restrict ConstIntegratorShadowState
Definition: state.h:150
const IntegratorStateCPU *ccl_restrict ConstIntegratorState
Definition: state.h:148
#define INTEGRATOR_STATE(state, nested_struct, member)
Definition: state.h:154
unsigned int uint32_t
Definition: stdint.h:80
unsigned __int64 uint64_t
Definition: stdint.h:90
float z
float y
float x
ccl_device_inline float ensure_finite(float v)
Definition: util/math.h:361
ccl_device_inline bool isfinite_safe(float f)
Definition: util/math.h:353
CCL_NAMESPACE_BEGIN ccl_device_inline void kernel_write_pass_float(ccl_global float *ccl_restrict buffer, float value)
Definition: write_passes.h:12
ccl_device_inline void kernel_write_pass_float3(ccl_global float *ccl_restrict buffer, float3 value)
Definition: write_passes.h:21
ccl_device_inline void kernel_write_pass_float4(ccl_global float *ccl_restrict buffer, float4 value)
Definition: write_passes.h:39