Blender V4.5
kernel/integrator/guiding.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/globals.h"
8#include "kernel/types.h"
9
12
13/* FIXME: The below include could be guarded behind `ifdef WITH_CYCLES_DEBUG`, but Metal
14 * pre-processing is not expanding guarded include files properly. */
15#include "kernel/closure/bsdf.h"
16
17#include "util/color.h"
18
20
21/* Utilities. */
22
26 /* The relative IOR of the outgoing media and the incoming media. */
27 float eta{1.0f};
28 int label;
30 float bsdf_pdf{0.0f};
31 float guide_pdf{0.0f};
32 float ris_target{0.0f};
33 float ris_pdf{0.0f};
34 float ris_weight{0.0f};
35
38 float avg_bsdf_eval{0.0f};
40};
41
43 const ccl_private float guiding_sampling_prob)
44{
45#if defined(__PATH_GUIDING__)
46 const float pi_factor = 2.0f;
47 if (ris_sample->avg_bsdf_eval > 0.0f && ris_sample->bsdf_pdf > 1e-10f &&
48 ris_sample->guide_pdf > 0.0f)
49 {
50 ris_sample->ris_target = (ris_sample->avg_bsdf_eval *
51 ((((1.0f - guiding_sampling_prob) * (1.0f / (pi_factor * M_PI_F))) +
52 (guiding_sampling_prob * ris_sample->incoming_radiance_pdf))));
53 ris_sample->ris_pdf = (0.5f * (ris_sample->bsdf_pdf + ris_sample->guide_pdf));
54 ris_sample->ris_weight = ris_sample->ris_target / ris_sample->ris_pdf;
55 return true;
56 }
57 ris_sample->ris_target = 0.0f;
58 ris_sample->ris_pdf = 0.0f;
59 return false;
60#else
61 return false;
62#endif
63}
64
65#if defined(__PATH_GUIDING__)
66static pgl_vec3f guiding_vec3f(const float3 v)
67{
68 return openpgl::cpp::Vector3(v.x, v.y, v.z);
69}
70
71static pgl_point3f guiding_point3f(const float3 v)
72{
73 return openpgl::cpp::Point3(v.x, v.y, v.z);
74}
75#endif
76
77/* Path recording for guiding. */
78
79/* Record Surface Interactions */
80
81/* Records/Adds a new path segment with the current path vertex on a surface.
82 * If the path is not terminated this call is usually followed by a call of
83 * guiding_record_surface_bounce. */
86 const ccl_private ShaderData *sd)
87{
88#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
89 if (!kernel_data.integrator.train_guiding) {
90 return;
91 }
92
94
95 const pgl_vec3f zero = guiding_vec3f(zero_float3());
96 const pgl_vec3f one = guiding_vec3f(one_float3());
97
98 state->guiding.path_segment = kg->opgl_path_segment_storage->NextSegment();
99 openpgl::cpp::SetPosition(state->guiding.path_segment, guiding_point3f(sd->P));
100 openpgl::cpp::SetDirectionOut(state->guiding.path_segment, guiding_vec3f(sd->wi));
101 openpgl::cpp::SetVolumeScatter(state->guiding.path_segment, false);
102 openpgl::cpp::SetScatteredContribution(state->guiding.path_segment, zero);
103 openpgl::cpp::SetDirectContribution(state->guiding.path_segment, zero);
104 openpgl::cpp::SetTransmittanceWeight(state->guiding.path_segment, one);
105 openpgl::cpp::SetEta(state->guiding.path_segment, 1.0);
106#endif
107}
108
109/* Records the surface scattering event at the current vertex position of the segment. */
112 const ccl_private ShaderData *sd,
113 const Spectrum weight,
114 const float pdf,
115 const float3 N,
116 const float3 wo,
117 const float2 roughness,
118 const float eta)
119{
120#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
121 if (!kernel_data.integrator.train_guiding) {
122 return;
123 }
124
126
127 const float min_roughness = safe_sqrtf(fminf(roughness.x, roughness.y));
128 const bool is_delta = (min_roughness == 0.0f);
129 const float3 weight_rgb = spectrum_to_rgb(weight);
130 const float3 normal = clamp(N, -one_float3(), one_float3());
131
132 kernel_assert(state->guiding.path_segment != nullptr);
133
134 openpgl::cpp::SetTransmittanceWeight(state->guiding.path_segment, guiding_vec3f(one_float3()));
135 openpgl::cpp::SetVolumeScatter(state->guiding.path_segment, false);
136 openpgl::cpp::SetNormal(state->guiding.path_segment, guiding_vec3f(normal));
137 openpgl::cpp::SetDirectionIn(state->guiding.path_segment, guiding_vec3f(wo));
138 openpgl::cpp::SetPDFDirectionIn(state->guiding.path_segment, pdf);
139 openpgl::cpp::SetScatteringWeight(state->guiding.path_segment, guiding_vec3f(weight_rgb));
140 openpgl::cpp::SetIsDelta(state->guiding.path_segment, is_delta);
141 openpgl::cpp::SetEta(state->guiding.path_segment, eta);
142 openpgl::cpp::SetRoughness(state->guiding.path_segment, min_roughness);
143#endif
144}
145
146/* Records the emission at the current surface intersection (physical or virtual) */
149 const Spectrum Le,
150 const float mis_weight)
151{
152#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
153 if (!kernel_data.integrator.train_guiding) {
154 return;
155 }
156
158
159 const float3 Le_rgb = spectrum_to_rgb(Le);
160
161 openpgl::cpp::SetDirectContribution(state->guiding.path_segment, guiding_vec3f(Le_rgb));
162 openpgl::cpp::SetMiWeight(state->guiding.path_segment, mis_weight);
163#endif
164}
165
166/* Record BSSRDF Interactions */
167
168/* Records/Adds a new path segment where the vertex position is the point of entry
169 * of the sub surface scattering boundary.
170 * If the path is not terminated this call is usually followed by a call of
171 * guiding_record_bssrdf_weight and guiding_record_bssrdf_bounce. */
174 const float3 P,
175 const float3 wi)
176{
177#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
178 if (!kernel_data.integrator.train_guiding) {
179 return;
180 }
181
183
184 const pgl_vec3f zero = guiding_vec3f(zero_float3());
185 const pgl_vec3f one = guiding_vec3f(one_float3());
186
187 state->guiding.path_segment = kg->opgl_path_segment_storage->NextSegment();
188 openpgl::cpp::SetPosition(state->guiding.path_segment, guiding_point3f(P));
189 openpgl::cpp::SetDirectionOut(state->guiding.path_segment, guiding_vec3f(wi));
190 openpgl::cpp::SetVolumeScatter(state->guiding.path_segment, true);
191 openpgl::cpp::SetScatteredContribution(state->guiding.path_segment, zero);
192 openpgl::cpp::SetDirectContribution(state->guiding.path_segment, zero);
193 openpgl::cpp::SetTransmittanceWeight(state->guiding.path_segment, one);
194 openpgl::cpp::SetEta(state->guiding.path_segment, 1.0);
195#endif
196}
197
198/* Records the transmission of the path at the point of entry while passing
199 * the surface boundary. */
202 const Spectrum weight,
203 const Spectrum albedo)
204{
205#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
206 if (!kernel_data.integrator.train_guiding) {
207 return;
208 }
209
211
212 /* Note albedo left out here, will be included in guiding_record_bssrdf_bounce. */
213 const float3 weight_rgb = spectrum_to_rgb(safe_divide_color(weight, albedo));
214
215 kernel_assert(state->guiding.path_segment != nullptr);
216
217 openpgl::cpp::SetTransmittanceWeight(state->guiding.path_segment, guiding_vec3f(zero_float3()));
218 openpgl::cpp::SetScatteringWeight(state->guiding.path_segment, guiding_vec3f(weight_rgb));
219 openpgl::cpp::SetIsDelta(state->guiding.path_segment, false);
220 openpgl::cpp::SetEta(state->guiding.path_segment, 1.0f);
221 openpgl::cpp::SetRoughness(state->guiding.path_segment, 1.0f);
222#endif
223}
224
225/* Records the direction at the point of entry the path takes when sampling the SSS contribution.
226 * If not terminated this function is usually followed by a call of
227 * guiding_record_volume_transmission to record the transmittance between the point of entry and
228 * the point of exit. */
231 const float pdf,
232 const float3 N,
233 const float3 wo,
234 const Spectrum weight,
235 const Spectrum albedo)
236{
237#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
238 if (!kernel_data.integrator.train_guiding) {
239 return;
240 }
241
243
244 const float3 normal = clamp(N, -one_float3(), one_float3());
245 const float3 weight_rgb = spectrum_to_rgb(weight * albedo);
246
247 kernel_assert(state->guiding.path_segment != nullptr);
248
249 openpgl::cpp::SetVolumeScatter(state->guiding.path_segment, false);
250 openpgl::cpp::SetNormal(state->guiding.path_segment, guiding_vec3f(normal));
251 openpgl::cpp::SetDirectionIn(state->guiding.path_segment, guiding_vec3f(wo));
252 openpgl::cpp::SetPDFDirectionIn(state->guiding.path_segment, pdf);
253 openpgl::cpp::SetTransmittanceWeight(state->guiding.path_segment, guiding_vec3f(weight_rgb));
254#endif
255}
256
257/* Record Volume Interactions */
258
259/* Records/Adds a new path segment with the current path vertex being inside a volume.
260 * If the path is not terminated this call is usually followed by a call of
261 * guiding_record_volume_bounce. */
264 const float3 P,
265 const float3 I)
266{
267#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
268 if (!kernel_data.integrator.train_guiding) {
269 return;
270 }
271
273
274 const pgl_vec3f zero = guiding_vec3f(zero_float3());
275 const pgl_vec3f one = guiding_vec3f(one_float3());
276
277 state->guiding.path_segment = kg->opgl_path_segment_storage->NextSegment();
278
279 openpgl::cpp::SetPosition(state->guiding.path_segment, guiding_point3f(P));
280 openpgl::cpp::SetDirectionOut(state->guiding.path_segment, guiding_vec3f(I));
281 openpgl::cpp::SetVolumeScatter(state->guiding.path_segment, true);
282 openpgl::cpp::SetScatteredContribution(state->guiding.path_segment, zero);
283 openpgl::cpp::SetDirectContribution(state->guiding.path_segment, zero);
284 openpgl::cpp::SetTransmittanceWeight(state->guiding.path_segment, one);
285 openpgl::cpp::SetEta(state->guiding.path_segment, 1.0);
286#endif
287}
288
289/* Records the volume scattering event at the current vertex position of the segment. */
292 const ccl_private ShaderData *sd,
293 const Spectrum weight,
294 const float pdf,
295 const float3 wo,
296 const float roughness)
297{
298#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
299 if (!kernel_data.integrator.train_guiding) {
300 return;
301 }
302
304
305 const float3 weight_rgb = spectrum_to_rgb(weight);
306 const float3 normal = make_float3(0.0f, 0.0f, 1.0f);
307
308 kernel_assert(state->guiding.path_segment != nullptr);
309
310 openpgl::cpp::SetVolumeScatter(state->guiding.path_segment, true);
311 openpgl::cpp::SetTransmittanceWeight(state->guiding.path_segment, guiding_vec3f(one_float3()));
312 openpgl::cpp::SetNormal(state->guiding.path_segment, guiding_vec3f(normal));
313 openpgl::cpp::SetDirectionIn(state->guiding.path_segment, guiding_vec3f(wo));
314 openpgl::cpp::SetPDFDirectionIn(state->guiding.path_segment, pdf);
315 openpgl::cpp::SetScatteringWeight(state->guiding.path_segment, guiding_vec3f(weight_rgb));
316 openpgl::cpp::SetIsDelta(state->guiding.path_segment, false);
317 openpgl::cpp::SetEta(state->guiding.path_segment, 1.0f);
318 openpgl::cpp::SetRoughness(state->guiding.path_segment, roughness);
319#endif
320}
321
322/* Records the transmission (a.k.a. transmittance weight) between the current path segment
323 * and the next one, when the path is inside or passes a volume. */
326 const float3 transmittance_weight)
327{
328#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
329 if (!kernel_data.integrator.train_guiding) {
330 return;
331 }
332
334
335 if (state->guiding.path_segment) {
336 // TODO (sherholz): need to find a better way to avoid this check
337 if ((transmittance_weight[0] < 0.0f || !std::isfinite(transmittance_weight[0]) ||
338 std::isnan(transmittance_weight[0])) ||
339 (transmittance_weight[1] < 0.0f || !std::isfinite(transmittance_weight[1]) ||
340 std::isnan(transmittance_weight[1])) ||
341 (transmittance_weight[2] < 0.0f || !std::isfinite(transmittance_weight[2]) ||
342 std::isnan(transmittance_weight[2])))
343 {
344 }
345 else {
346 openpgl::cpp::SetTransmittanceWeight(state->guiding.path_segment,
347 guiding_vec3f(transmittance_weight));
348 }
349 }
350#endif
351}
352
353/* Records the emission of a volume at the vertex of the current path segment. */
356 const Spectrum Le)
357{
358#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
359 if (!kernel_data.integrator.train_guiding) {
360 return;
361 }
362
364
365 if (state->guiding.path_segment) {
366 const float3 Le_rgb = spectrum_to_rgb(Le);
367
368 openpgl::cpp::SetDirectContribution(state->guiding.path_segment, guiding_vec3f(Le_rgb));
369 openpgl::cpp::SetMiWeight(state->guiding.path_segment, 1.0f);
370 }
371#endif
372}
373
374/* Record Light Interactions */
375
376/* Adds a pseudo path vertex/segment when intersecting a virtual light source.
377 * (e.g., area, sphere, or disk light). This call is often followed
378 * a call of guiding_record_surface_emission, if the intersected light source
379 * emits light in the direction of the path. */
382{
383#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
384 if (!kernel_data.integrator.train_guiding) {
385 return;
386 }
387
389
390 const pgl_vec3f zero = guiding_vec3f(zero_float3());
391 const pgl_vec3f one = guiding_vec3f(one_float3());
392 const float3 ray_P = INTEGRATOR_STATE(state, ray, P);
393 const float3 ray_D = INTEGRATOR_STATE(state, ray, D);
394 const float3 P = ray_P + isect->t * ray_D;
395
396 state->guiding.path_segment = kg->opgl_path_segment_storage->NextSegment();
397 openpgl::cpp::SetPosition(state->guiding.path_segment, guiding_point3f(P));
398 openpgl::cpp::SetDirectionOut(state->guiding.path_segment, guiding_vec3f(-ray_D));
399 openpgl::cpp::SetNormal(state->guiding.path_segment, guiding_vec3f(-ray_D));
400 openpgl::cpp::SetDirectionIn(state->guiding.path_segment, guiding_vec3f(ray_D));
401 openpgl::cpp::SetPDFDirectionIn(state->guiding.path_segment, 1.0f);
402 openpgl::cpp::SetVolumeScatter(state->guiding.path_segment, false);
403 openpgl::cpp::SetScatteredContribution(state->guiding.path_segment, zero);
404 openpgl::cpp::SetDirectContribution(state->guiding.path_segment, zero);
405 openpgl::cpp::SetTransmittanceWeight(state->guiding.path_segment, one);
406 openpgl::cpp::SetScatteringWeight(state->guiding.path_segment, one);
407 openpgl::cpp::SetEta(state->guiding.path_segment, 1.0f);
408#endif
409}
410
411/* Records/Adds a final path segment when the path leaves the scene and
412 * intersects with a background light (e.g., background color,
413 * distant light, or env map). The vertex for this segment is placed along
414 * the current ray far out the scene. */
417 const Spectrum L,
418 const float mis_weight)
419{
420#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
421 if (!kernel_data.integrator.train_guiding) {
422 return;
423 }
424
426
427 const float3 L_rgb = spectrum_to_rgb(L);
428 const float3 ray_P = INTEGRATOR_STATE(state, ray, P);
429 const float3 ray_D = INTEGRATOR_STATE(state, ray, D);
430 const float3 P = ray_P + (1e6f) * ray_D;
431 const float3 normal = make_float3(0.0f, 0.0f, 1.0f);
432
433 openpgl::cpp::PathSegment background_segment;
434 openpgl::cpp::SetPosition(&background_segment, guiding_vec3f(P));
435 openpgl::cpp::SetNormal(&background_segment, guiding_vec3f(normal));
436 openpgl::cpp::SetDirectionOut(&background_segment, guiding_vec3f(-ray_D));
437 openpgl::cpp::SetDirectContribution(&background_segment, guiding_vec3f(L_rgb));
438 openpgl::cpp::SetMiWeight(&background_segment, mis_weight);
439 kg->opgl_path_segment_storage->AddSegment(background_segment);
440#endif
441}
442
443/* Records direct lighting from either next event estimation or a dedicated BSDF
444 * sampled shadow ray. */
447{
448#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
449 if (!kernel_data.integrator.train_guiding) {
450 return;
451 }
452 if (state->shadow_path.path_segment) {
453 const Spectrum Lo = safe_divide_color(INTEGRATOR_STATE(state, shadow_path, throughput),
454 INTEGRATOR_STATE(state, shadow_path, unlit_throughput));
455
456 const float3 Lo_rgb = spectrum_to_rgb(Lo);
457
458 const float mis_weight = INTEGRATOR_STATE(state, shadow_path, guiding_mis_weight);
459
460 if (mis_weight == 0.0f) {
461 /* Scattered contribution of a next event estimation (i.e., a direct light estimate
462 * scattered at the current path vertex towards the previous vertex). */
463 openpgl::cpp::AddScatteredContribution(state->shadow_path.path_segment,
464 guiding_vec3f(Lo_rgb));
465 }
466 else {
467 /* Dedicated shadow ray for BSDF sampled ray direction.
468 * The mis weight was already folded into the throughput, so need to divide it out. */
469 openpgl::cpp::SetDirectContribution(state->shadow_path.path_segment,
470 guiding_vec3f(Lo_rgb / mis_weight));
471 openpgl::cpp::SetMiWeight(state->shadow_path.path_segment, mis_weight);
472 }
473 }
474#endif
475}
476
477/* Record Russian Roulette */
478/* Records the probability of continuing the path at the current path segment. */
480 KernelGlobals kg, IntegratorState state, const float continuation_probability)
481{
482#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1
483 if (!kernel_data.integrator.train_guiding) {
484 return;
485 }
486
488
489 if (state->guiding.path_segment) {
490 openpgl::cpp::SetRussianRouletteProbability(state->guiding.path_segment,
491 continuation_probability);
492 }
493#endif
494}
495
496/* Path guiding debug render passes. */
497
498/* Write a set of path guiding related debug information (e.g., guiding probability at first
499 * bounce) into separate rendering passes. */
502 const ccl_private ShaderData *sd,
505{
506#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
507# ifdef WITH_CYCLES_DEBUG
508 if (!kernel_data.integrator.train_guiding) {
509 return;
510 }
511
512 if (INTEGRATOR_STATE(state, path, bounce) != 0) {
513 return;
514 }
515
517
518 if (kernel_data.film.pass_guiding_probability != PASS_UNUSED) {
519 float guiding_prob = state->guiding.surface_guiding_sampling_prob;
520 film_write_pass_float(buffer + kernel_data.film.pass_guiding_probability, guiding_prob);
521 }
522
523 if (kernel_data.film.pass_guiding_avg_roughness != PASS_UNUSED) {
524 float avg_roughness = 0.0f;
525 float sum_sample_weight = 0.0f;
526 for (int i = 0; i < sd->num_closure; i++) {
527 const ccl_private ShaderClosure *sc = &sd->closure[i];
528
529 if (!CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
530 continue;
531 }
532 avg_roughness += sc->sample_weight * bsdf_get_specular_roughness_squared(sc);
533 sum_sample_weight += sc->sample_weight;
534 }
535
536 avg_roughness = avg_roughness > 0.0f ? avg_roughness / sum_sample_weight : 0.0f;
537
538 film_write_pass_float(buffer + kernel_data.film.pass_guiding_avg_roughness, avg_roughness);
539 }
540# endif
541#endif
542}
543
544/* Guided BSDFs */
545
548 const float3 P,
549 const float3 N,
550 ccl_private float &rand)
551{
552#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
553 if (kg->opgl_surface_sampling_distribution->Init(
554 kg->opgl_guiding_field, guiding_point3f(P), rand))
555 {
556 kg->opgl_surface_sampling_distribution->ApplyCosineProduct(guiding_point3f(N));
557 return true;
558 }
559#endif
560
561 return false;
562}
563
566 const float2 rand_bsdf,
568{
569#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
570 pgl_vec3f pgl_wo;
571 const pgl_point2f rand = openpgl::cpp::Point2(rand_bsdf.x, rand_bsdf.y);
572 const float pdf = kg->opgl_surface_sampling_distribution->SamplePDF(rand, pgl_wo);
573 *wo = make_float3(pgl_wo.x, pgl_wo.y, pgl_wo.z);
574 return pdf;
575#else
576 return 0.0f;
577#endif
578}
579
582 const float3 wo)
583{
584#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
585 return kg->opgl_surface_sampling_distribution->PDF(guiding_vec3f(wo));
586#else
587 return 0.0f;
588#endif
589}
590
593 const float3 wo)
594{
595#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
596 return kg->opgl_surface_sampling_distribution->IncomingRadiancePDF(guiding_vec3f(wo));
597#else
598 return 0.0f;
599#endif
600}
601
602/* Guided Volume Phases */
603
606 const float3 P,
607 const float3 D,
608 const float g,
609 ccl_private float &rand)
610{
611#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
612 /* we do not need to guide almost delta phase functions */
613 if (fabsf(g) >= 0.99f) {
614 return false;
615 }
616
617 if (kg->opgl_volume_sampling_distribution->Init(
618 kg->opgl_guiding_field, guiding_point3f(P), rand))
619 {
620 kg->opgl_volume_sampling_distribution->ApplySingleLobeHenyeyGreensteinProduct(guiding_vec3f(D),
621 g);
622 return true;
623 }
624#endif
625
626 return false;
627}
628
631 const float2 rand_phase,
633{
634#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
635 pgl_vec3f pgl_wo;
636 const pgl_point2f rand = openpgl::cpp::Point2(rand_phase.x, rand_phase.y);
637 const float pdf = kg->opgl_volume_sampling_distribution->SamplePDF(rand, pgl_wo);
638 *wo = make_float3(pgl_wo.x, pgl_wo.y, pgl_wo.z);
639 return pdf;
640#else
641 return 0.0f;
642#endif
643}
644
647 const float3 wo)
648{
649#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
650 return kg->opgl_volume_sampling_distribution->PDF(guiding_vec3f(wo));
651#else
652 return 0.0f;
653#endif
654}
655
#define D
MINLINE float safe_sqrtf(float a)
ATTR_WARN_UNUSED_RESULT const BMVert * v
CCL_NAMESPACE_BEGIN ccl_device_inline float bsdf_get_specular_roughness_squared(const ccl_private ShaderClosure *sc)
Definition bsdf.h:29
ccl_device_inline Spectrum safe_divide_color(Spectrum a, Spectrum b, const float fallback=0.0f)
Definition color.h:388
#define kernel_assert(cond)
#define kernel_data
#define PASS_UNUSED
#define ccl_restrict
#define ccl_device_forceinline
#define zero_spectrum
#define ccl_private
const ThreadKernelGlobalsCPU * KernelGlobals
#define M_PI_F
#define ccl_global
#define CLOSURE_IS_BSDF_OR_BSSRDF(type)
#define CCL_NAMESPACE_END
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
#define fminf(x, y)
#define fabsf(x)
#define assert(assertion)
constexpr T clamp(T, U, U) RET
ccl_gpu_kernel_postfix ccl_global KernelWorkTile const int ccl_global float * render_buffer
ccl_device_forceinline float guiding_bsdf_pdf(KernelGlobals kg, IntegratorState state, const float3 wo)
ccl_device_forceinline void guiding_write_debug_passes(KernelGlobals kg, IntegratorState state, const ccl_private ShaderData *sd, ccl_global float *ccl_restrict render_buffer)
ccl_device_forceinline void guiding_record_background(KernelGlobals kg, IntegratorState state, const Spectrum L, const float mis_weight)
ccl_device_forceinline void guiding_record_volume_segment(KernelGlobals kg, IntegratorState state, const float3 P, const float3 I)
ccl_device_forceinline void guiding_record_volume_bounce(KernelGlobals kg, IntegratorState state, const ccl_private ShaderData *sd, const Spectrum weight, const float pdf, const float3 wo, const float roughness)
ccl_device_forceinline void guiding_record_light_surface_segment(KernelGlobals kg, IntegratorState state, const ccl_private Intersection *ccl_restrict isect)
ccl_device_forceinline void guiding_record_surface_emission(KernelGlobals kg, IntegratorState state, const Spectrum Le, const float mis_weight)
ccl_device_forceinline float guiding_phase_sample(KernelGlobals kg, IntegratorState state, const float2 rand_phase, ccl_private float3 *wo)
ccl_device_forceinline void guiding_record_surface_bounce(KernelGlobals kg, IntegratorState state, const ccl_private ShaderData *sd, const Spectrum weight, const float pdf, const float3 N, const float3 wo, const float2 roughness, const float eta)
ccl_device_forceinline float guiding_phase_pdf(KernelGlobals kg, IntegratorState state, const float3 wo)
ccl_device_forceinline void guiding_record_volume_emission(KernelGlobals kg, IntegratorState state, const Spectrum Le)
ccl_device_forceinline void guiding_record_bssrdf_bounce(KernelGlobals kg, IntegratorState state, const float pdf, const float3 N, const float3 wo, const Spectrum weight, const Spectrum albedo)
ccl_device_forceinline void guiding_record_direct_light(KernelGlobals kg, IntegratorShadowState state)
ccl_device_forceinline bool calculate_ris_target(ccl_private GuidingRISSample *ris_sample, const ccl_private float guiding_sampling_prob)
ccl_device_forceinline void guiding_record_continuation_probability(KernelGlobals kg, IntegratorState state, const float continuation_probability)
ccl_device_forceinline void guiding_record_volume_transmission(KernelGlobals kg, IntegratorState state, const float3 transmittance_weight)
ccl_device_forceinline float guiding_bsdf_sample(KernelGlobals kg, IntegratorState state, const float2 rand_bsdf, ccl_private float3 *wo)
ccl_device_forceinline void guiding_record_surface_segment(KernelGlobals kg, IntegratorState state, const ccl_private ShaderData *sd)
ccl_device_forceinline float guiding_surface_incoming_radiance_pdf(KernelGlobals kg, IntegratorState state, const float3 wo)
ccl_device_forceinline bool guiding_phase_init(KernelGlobals kg, IntegratorState state, const float3 P, const float3 D, const float g, ccl_private float &rand)
ccl_device_forceinline void guiding_record_bssrdf_segment(KernelGlobals kg, IntegratorState state, const float3 P, const float3 wi)
ccl_device_forceinline void guiding_record_bssrdf_weight(KernelGlobals kg, IntegratorState state, const Spectrum weight, const Spectrum albedo)
ccl_device_forceinline bool guiding_bsdf_init(KernelGlobals kg, IntegratorState state, const float3 P, const float3 N, ccl_private float &rand)
@ PATH_RAY_SHADOW_CATCHER_PASS
ccl_device_inline float3 spectrum_to_rgb(Spectrum s)
ccl_device_inline float3 one_float3()
Definition math_float3.h:24
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
Definition math_float3.h:15
static ulong state[N]
#define N
#define L
#define I
IntegratorShadowStateCPU * IntegratorShadowState
Definition state.h:230
#define INTEGRATOR_STATE(state, nested_struct, member)
Definition state.h:235
IntegratorStateCPU * IntegratorState
Definition state.h:228
float x
float y
i
Definition text_draw.cc:230
float3 Spectrum
uint8_t flag
Definition wm_window.cc:139
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