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