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