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