Blender V5.0
surface_shader.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/* Functions to evaluate shaders. */
6
7#pragma once
8
11
13
15
16#ifdef __SVM__
17# include "kernel/svm/svm.h"
18#endif
19#ifdef __OSL__
20# include "kernel/osl/osl.h"
21#endif
22
24
25/* Guiding */
26
27#if defined(__PATH_GUIDING__)
28
29ccl_device float surface_shader_average_sample_weight_squared_roughness(
30 const ccl_private ShaderData *sd)
31{
32 float avg_squared_roughness = 0.0f;
33 float sum_sample_weight = 0.0f;
34 for (int i = 0; i < sd->num_closure; i++) {
35 const ccl_private ShaderClosure *sc = &sd->closure[i];
36
37 if (!CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
38 continue;
39 }
40 avg_squared_roughness += sc->sample_weight * bsdf_get_specular_roughness_squared(sc);
41 sum_sample_weight += sc->sample_weight;
42 }
43
44 avg_squared_roughness = avg_squared_roughness > 0.0f ?
45 avg_squared_roughness / sum_sample_weight :
46 0.0f;
47 return avg_squared_roughness;
48}
49
50ccl_device_inline void surface_shader_prepare_guiding(KernelGlobals kg,
52 ccl_private ShaderData *sd,
53 const ccl_private RNGState *rng_state)
54{
55 /* Have any BSDF to guide? */
56 if (!(kernel_data.integrator.use_surface_guiding && (sd->flag & SD_BSDF_HAS_EVAL))) {
57 INTEGRATOR_STATE_WRITE(state, guiding, use_surface_guiding) = false;
58 return;
59 }
60
61 const float surface_guiding_probability = kernel_data.integrator.surface_guiding_probability;
62 const int guiding_directional_sampling_type =
63 kernel_data.integrator.guiding_directional_sampling_type;
64 const float guiding_roughness_threshold = kernel_data.integrator.guiding_roughness_threshold;
65 float rand_bsdf_guiding = path_state_rng_1D(kg, rng_state, PRNG_SURFACE_BSDF_GUIDING);
66
67 /* Compute proportion of diffuse BSDF and BSSRDFs. */
68 float diffuse_sampling_fraction = 0.0f;
69 float bssrdf_sampling_fraction = 0.0f;
70 float bsdf_bssrdf_sampling_sum = 0.0f;
71
72 bool fully_opaque = true;
73
74 for (int i = 0; i < sd->num_closure; i++) {
75 ShaderClosure *sc = &sd->closure[i];
76 if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
77 const float sweight = sc->sample_weight;
78 kernel_assert(sweight >= 0.0f);
79
80 bsdf_bssrdf_sampling_sum += sweight;
81 if (CLOSURE_IS_BSDF_DIFFUSE(sc->type) && sc->type < CLOSURE_BSDF_TRANSLUCENT_ID) {
82 diffuse_sampling_fraction += sweight;
83 }
84 if (CLOSURE_IS_BSSRDF(sc->type)) {
85 bssrdf_sampling_fraction += sweight;
86 }
87
89 fully_opaque = false;
90 }
91 }
92 }
93
94 if (bsdf_bssrdf_sampling_sum > 0.0f) {
95 diffuse_sampling_fraction /= bsdf_bssrdf_sampling_sum;
96 bssrdf_sampling_fraction /= bsdf_bssrdf_sampling_sum;
97 }
98
99 /* Initial guiding */
100 /* The roughness because the function returns `alpha.x * alpha.y`.
101 * In addition alpha is squared again. */
102 float avg_roughness = surface_shader_average_sample_weight_squared_roughness(sd);
103 avg_roughness = safe_sqrtf(avg_roughness);
104 if (!fully_opaque || avg_roughness < guiding_roughness_threshold ||
105 ((guiding_directional_sampling_type == GUIDING_DIRECTIONAL_SAMPLING_TYPE_PRODUCT_MIS) &&
106 (diffuse_sampling_fraction <= 0.0f)) ||
107 !guiding_bsdf_init(kg, sd->P, sd->N, rand_bsdf_guiding))
108 {
109 INTEGRATOR_STATE_WRITE(state, guiding, use_surface_guiding) = false;
110 INTEGRATOR_STATE_WRITE(state, guiding, surface_guiding_sampling_prob) = 0.f;
111 return;
112 }
113
114 INTEGRATOR_STATE_WRITE(state, guiding, use_surface_guiding) = true;
115 if (kernel_data.integrator.guiding_directional_sampling_type ==
117 {
119 state, guiding, surface_guiding_sampling_prob) = surface_guiding_probability *
120 diffuse_sampling_fraction;
121 }
122 else if (kernel_data.integrator.guiding_directional_sampling_type ==
124 {
126 state, guiding, surface_guiding_sampling_prob) = surface_guiding_probability;
127 }
128 else { // GUIDING_DIRECTIONAL_SAMPLING_TYPE_ROUGHNESS
130 state, guiding, surface_guiding_sampling_prob) = surface_guiding_probability *
131 avg_roughness;
132 }
133 INTEGRATOR_STATE_WRITE(state, guiding, bssrdf_sampling_prob) = bssrdf_sampling_fraction;
134 INTEGRATOR_STATE_WRITE(state, guiding, sample_surface_guiding_rand) = rand_bsdf_guiding;
135
136 kernel_assert(INTEGRATOR_STATE(state, guiding, surface_guiding_sampling_prob) > 0.0f &&
137 INTEGRATOR_STATE(state, guiding, surface_guiding_sampling_prob) <= 1.0f);
138}
139#endif
140
143 ccl_private ShaderData *sd,
144 const uint32_t path_flag)
145{
146 /* Filter out closures. */
147 if (kernel_data.integrator.filter_closures) {
148 const int filter_closures = kernel_data.integrator.filter_closures;
149 if (filter_closures & FILTER_CLOSURE_EMISSION) {
150 sd->closure_emission_background = zero_spectrum();
151 }
152
153 if (path_flag & PATH_RAY_CAMERA) {
154 if (filter_closures & FILTER_CLOSURE_DIRECT_LIGHT) {
155 sd->flag &= ~SD_BSDF_HAS_EVAL;
156 }
157
158 for (int i = 0; i < sd->num_closure; i++) {
159 ccl_private ShaderClosure *sc = &sd->closure[i];
160
161 const bool filter_diffuse = (filter_closures & FILTER_CLOSURE_DIFFUSE);
162 const bool filter_glossy = (filter_closures & FILTER_CLOSURE_GLOSSY);
163 const bool filter_transmission = (filter_closures & FILTER_CLOSURE_TRANSMISSION);
164 const bool filter_glass = filter_glossy && filter_transmission;
165 if ((CLOSURE_IS_BSDF_DIFFUSE(sc->type) && filter_diffuse) ||
166 (CLOSURE_IS_BSDF_GLOSSY(sc->type) && filter_glossy) ||
167 (CLOSURE_IS_BSDF_TRANSMISSION(sc->type) && filter_transmission) ||
168 (CLOSURE_IS_GLASS(sc->type) && filter_glass))
169 {
170 sc->type = CLOSURE_NONE_ID;
171 sc->sample_weight = 0.0f;
172 }
173 else if ((CLOSURE_IS_BSDF_TRANSPARENT(sc->type) &&
174 (filter_closures & FILTER_CLOSURE_TRANSPARENT)))
175 {
176 sc->type = CLOSURE_HOLDOUT_ID;
177 sc->sample_weight = 0.0f;
178 sd->flag |= SD_HOLDOUT;
179 }
180 }
181 }
182 }
183
184 /* Filter glossy.
185 *
186 * Blurring of bsdf after bounces, for rays that have a small likelihood
187 * of following this particular path (diffuse, rough glossy) */
188 if (kernel_data.integrator.filter_glossy != FLT_MAX
189#ifdef __MNEE__
190 && !(INTEGRATOR_STATE(state, path, mnee) & PATH_MNEE_VALID)
191#endif
192 )
193 {
194 const float blur_pdf = kernel_data.integrator.filter_glossy *
195 INTEGRATOR_STATE(state, path, min_ray_pdf);
196
197 if (blur_pdf < 1.0f) {
198 const float blur_roughness = sqrtf(1.0f - blur_pdf) * 0.5f;
199
200 for (int i = 0; i < sd->num_closure; i++) {
201 ccl_private ShaderClosure *sc = &sd->closure[i];
202 if (CLOSURE_IS_BSDF(sc->type)) {
203 bsdf_blur(sc, blur_roughness);
204 }
205 }
206
207 /* NOTE: this is a sufficient condition. If `blur_roughness < THRESH < original_roughness`
208 * then the flag was already set. */
209 if (sqr(blur_roughness) > BSDF_ROUGHNESS_SQ_THRESH) {
210 sd->flag |= SD_BSDF_HAS_EVAL;
211 }
212 }
213 }
214}
215
216/* BSDF */
217#ifdef WITH_CYCLES_DEBUG
218ccl_device_inline void surface_shader_validate_bsdf_sample(const KernelGlobals kg,
219 const ccl_private ShaderClosure *sc,
220 const float3 wo,
221 const int org_label,
222 const float2 org_roughness,
223 const float org_eta)
224{
225 /* Validate the #bsdf_label and #bsdf_roughness_eta functions
226 * by estimating the values after a BSDF sample. */
227 kernel_assert(org_label == bsdf_label(kg, sc, wo));
228 (void)kg;
229
230 float2 comp_roughness;
231 float comp_eta;
232 bsdf_roughness_eta(sc, wo, &comp_roughness, &comp_eta);
233 kernel_assert(org_eta == comp_eta);
234 kernel_assert(org_roughness.x == comp_roughness.x);
235 kernel_assert(org_roughness.y == comp_roughness.y);
236}
237#endif
238
240 const uint light_shader_flags)
241{
242 if (!(light_shader_flags & SHADER_EXCLUDE_ANY)) {
243 return false;
244 }
245 if (light_shader_flags & SHADER_EXCLUDE_DIFFUSE) {
246 if (CLOSURE_IS_BSDF_DIFFUSE(type)) {
247 return true;
248 }
249 }
250 if (light_shader_flags & SHADER_EXCLUDE_GLOSSY) {
251 if (CLOSURE_IS_BSDF_GLOSSY(type)) {
252 return true;
253 }
254 }
255 if (light_shader_flags & SHADER_EXCLUDE_TRANSMIT) {
257 return true;
258 }
259 }
260 /* Glass closures are both glossy and transmissive, so only exclude them if both are filtered. */
261 const uint exclude_glass = SHADER_EXCLUDE_TRANSMIT | SHADER_EXCLUDE_GLOSSY;
262 if ((light_shader_flags & exclude_glass) == exclude_glass) {
263 if (CLOSURE_IS_GLASS(type)) {
264 return true;
265 }
266 }
267 return false;
268}
269
271 ccl_private ShaderData *sd,
272 const float3 wo,
273 const ccl_private ShaderClosure *skip_sc,
274 ccl_private BsdfEval *result_eval,
275 float sum_pdf,
276 float sum_sample_weight,
277 const uint light_shader_flags)
278{
279 /* This is the veach one-sample model with balance heuristic,
280 * some PDF factors drop out when using balance heuristic weighting. */
281 for (int i = 0; i < sd->num_closure; i++) {
282 const ccl_private ShaderClosure *sc = &sd->closure[i];
283
284 if (sc == skip_sc) {
285 continue;
286 }
287
288 if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
289 if (CLOSURE_IS_BSDF(sc->type)) {
290 float bsdf_pdf = 0.0f;
291 const Spectrum eval = bsdf_eval(kg, sd, sc, wo, &bsdf_pdf);
292
293 if (bsdf_pdf != 0.0f) {
294 if (!_surface_shader_exclude(sc->type, light_shader_flags)) {
295 bsdf_eval_accum(result_eval, sc, wo, eval * sc->weight);
296 }
297 sum_pdf += bsdf_pdf * sc->sample_weight;
298 }
299 }
300
301 sum_sample_weight += sc->sample_weight;
302 }
303 }
304
305 return (sum_sample_weight > 0.0f) ? sum_pdf / sum_sample_weight : 0.0f;
306}
307
309 ccl_private ShaderData *sd,
310 const float3 wo,
311 ccl_private BsdfEval *result_eval,
312 ccl_private float *pdfs,
313 const uint light_shader_flags)
314{
315 /* This is the veach one-sample model with balance heuristic, some pdf
316 * factors drop out when using balance heuristic weighting. */
317 float sum_pdf = 0.0f;
318 float sum_sample_weight = 0.0f;
319 bsdf_eval_init(result_eval, zero_spectrum());
320 for (int i = 0; i < sd->num_closure; i++) {
321 const ccl_private ShaderClosure *sc = &sd->closure[i];
322
323 if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
324 if (CLOSURE_IS_BSDF(sc->type)) {
325 float bsdf_pdf = 0.0f;
326 const Spectrum eval = bsdf_eval(kg, sd, sc, wo, &bsdf_pdf);
327 kernel_assert(bsdf_pdf >= 0.0f);
328 if (bsdf_pdf != 0.0f) {
329 if (!_surface_shader_exclude(sc->type, light_shader_flags)) {
330 bsdf_eval_accum(result_eval, sc, wo, eval * sc->weight);
331 }
332 sum_pdf += bsdf_pdf * sc->sample_weight;
333 kernel_assert(bsdf_pdf * sc->sample_weight >= 0.0f);
334 pdfs[i] = bsdf_pdf * sc->sample_weight;
335 }
336 else {
337 pdfs[i] = 0.0f;
338 }
339 }
340 else {
341 pdfs[i] = 0.0f;
342 }
343
344 sum_sample_weight += sc->sample_weight;
345 }
346 else {
347 pdfs[i] = 0.0f;
348 }
349 }
350 if (sum_pdf > 0.0f) {
351 for (int i = 0; i < sd->num_closure; i++) {
352 pdfs[i] /= sum_pdf;
353 }
354 }
355
356 return (sum_sample_weight > 0.0f) ? sum_pdf / sum_sample_weight : 0.0f;
357}
358
359#ifndef __KERNEL_CUDA__
361#else
363#endif
364 float
367 ccl_private ShaderData *sd,
368 const float3 wo,
370 const uint light_shader_flags)
371{
373
375 kg, sd, wo, nullptr, bsdf_eval, 0.0f, 0.0f, light_shader_flags);
376
377 /* If the light does not use MIS, then it is only sampled via NEE, so the probability of hitting
378 * the light using BSDF sampling is zero. */
379 if (!(light_shader_flags & SHADER_USE_MIS)) {
380 pdf = 0.0f;
381 }
382
383#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
384 if ((kernel_data.kernel_features & KERNEL_FEATURE_PATH_GUIDING)) {
385 if (pdf > 0.0f && INTEGRATOR_STATE(state, guiding, use_surface_guiding)) {
386 const float guiding_sampling_prob = INTEGRATOR_STATE(
387 state, guiding, surface_guiding_sampling_prob);
388 const float bssrdf_sampling_prob = INTEGRATOR_STATE(state, guiding, bssrdf_sampling_prob);
389 const float guide_pdf = guiding_bsdf_pdf(kg, wo);
390
391 if (kernel_data.integrator.guiding_directional_sampling_type ==
393 {
394 pdf = (0.5f * guide_pdf * (1.0f - bssrdf_sampling_prob)) + 0.5f * pdf;
395 }
396 else {
397 pdf = (guiding_sampling_prob * guide_pdf * (1.0f - bssrdf_sampling_prob)) +
398 (1.0f - guiding_sampling_prob) * pdf;
399 }
400 }
401 }
402#endif
403
404 return pdf;
405}
406
407/* Randomly sample a BSSRDF or BSDF proportional to ShaderClosure.sample_weight. */
409 const ccl_private ShaderData *ccl_restrict sd, ccl_private float3 *rand_bsdf)
410{
411 int sampled = 0;
412
413 if (sd->num_closure > 1) {
414 /* Pick a BSDF or based on sample weights. */
415 float sum = 0.0f;
416
417 for (int i = 0; i < sd->num_closure; i++) {
418 const ccl_private ShaderClosure *sc = &sd->closure[i];
419
420 if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
421 sum += sc->sample_weight;
422 }
423 }
424
425 const float r = (*rand_bsdf).z * sum;
426 float partial_sum = 0.0f;
427
428 for (int i = 0; i < sd->num_closure; i++) {
429 const ccl_private ShaderClosure *sc = &sd->closure[i];
430
431 if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
432 const float next_sum = partial_sum + sc->sample_weight;
433
434 if (r < next_sum) {
435 sampled = i;
436
437 /* Rescale to reuse for direction sample, to better preserve stratification. */
438 (*rand_bsdf).z = (r - partial_sum) / sc->sample_weight;
439 break;
440 }
441
442 partial_sum = next_sum;
443 }
444 }
445 }
446
447 return &sd->closure[sampled];
448}
449
450/* Return weight for picked BSSRDF. */
453 const ccl_private ShaderClosure *ccl_restrict bssrdf_sc)
454{
455 Spectrum weight = bssrdf_sc->weight;
456
457 if (sd->num_closure > 1) {
458 float sum = 0.0f;
459 for (int i = 0; i < sd->num_closure; i++) {
460 const ccl_private ShaderClosure *sc = &sd->closure[i];
461
462 if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
463 sum += sc->sample_weight;
464 }
465 }
466 weight *= sum / bssrdf_sc->sample_weight;
467 }
468
469 return weight;
470}
471
472#if defined(__PATH_GUIDING__)
473/* Sample direction for picked BSDF, and return evaluation and pdf for all
474 * BSDFs combined using MIS. */
475
476ccl_device int surface_shader_bsdf_guided_sample_closure_mis(KernelGlobals kg,
478 ccl_private ShaderData *sd,
479 const ccl_private ShaderClosure *sc,
480 const float3 rand_bsdf,
483 ccl_private float *bsdf_pdf,
484 ccl_private float *unguided_bsdf_pdf,
485 ccl_private float2 *sampled_roughness,
486 ccl_private float *eta)
487{
488 /* BSSRDF should already have been handled elsewhere. */
490
491 const bool use_surface_guiding = INTEGRATOR_STATE(state, guiding, use_surface_guiding);
492 const float guiding_sampling_prob = INTEGRATOR_STATE(
493 state, guiding, surface_guiding_sampling_prob);
494 const float bssrdf_sampling_prob = INTEGRATOR_STATE(state, guiding, bssrdf_sampling_prob);
495
496 /* Decide between sampling guiding distribution and BSDF. */
497 bool sample_guiding = false;
498 float rand_bsdf_guiding = INTEGRATOR_STATE(state, guiding, sample_surface_guiding_rand);
499
500 if (use_surface_guiding && rand_bsdf_guiding < guiding_sampling_prob) {
501 sample_guiding = true;
502 rand_bsdf_guiding /= guiding_sampling_prob;
503 }
504 else {
505 rand_bsdf_guiding -= guiding_sampling_prob;
506 rand_bsdf_guiding /= (1.0f - guiding_sampling_prob);
507 }
508
509 /* Initialize to zero. */
510 int label = LABEL_NONE;
511 Spectrum eval = zero_spectrum();
513
514 *unguided_bsdf_pdf = 0.0f;
515 float guide_pdf = 0.0f;
516
517 if (sample_guiding) {
518 /* Sample guiding distribution. */
519 guide_pdf = guiding_bsdf_sample(kg, make_float2(rand_bsdf), wo);
520 *bsdf_pdf = 0.0f;
521
522 if (guide_pdf != 0.0f) {
523 float unguided_bsdf_pdfs[MAX_CLOSURE];
524
525 *unguided_bsdf_pdf = surface_shader_bsdf_eval_pdfs(
526 kg, sd, *wo, bsdf_eval, unguided_bsdf_pdfs, 0);
527 *bsdf_pdf = (guiding_sampling_prob * guide_pdf * (1.0f - bssrdf_sampling_prob)) +
528 ((1.0f - guiding_sampling_prob) * (*unguided_bsdf_pdf));
529 float sum_pdfs = 0.0f;
530
531 if (*unguided_bsdf_pdf > 0.0f) {
532 int idx = -1;
533 for (int i = 0; i < sd->num_closure; i++) {
534 sum_pdfs += unguided_bsdf_pdfs[i];
535 if (rand_bsdf_guiding <= sum_pdfs) {
536 idx = i;
537 break;
538 }
539 }
540
541 kernel_assert(idx >= 0);
542 /* Set the default idx to the last in the list.
543 * in case of numerical problems and rand_bsdf_guiding is just >=1.0f and
544 * the sum of all unguided_bsdf_pdfs is just < 1.0f. */
545 idx = (rand_bsdf_guiding > sum_pdfs) ? sd->num_closure - 1 : idx;
546
547 label = bsdf_label(kg, &sd->closure[idx], *wo);
548 }
549 else {
550 *bsdf_pdf = 0.0f;
551 *unguided_bsdf_pdf = 0.0f;
552 }
553 }
554
556
557 *sampled_roughness = make_float2(1.0f, 1.0f);
558 *eta = 1.0f;
559 }
560 else {
561 /* Sample BSDF. */
562 *bsdf_pdf = 0.0f;
563 label = bsdf_sample(
564 kg, sd, sc, rand_bsdf, &eval, wo, unguided_bsdf_pdf, sampled_roughness, eta);
565# ifdef WITH_CYCLES_DEBUG
566 /* Code path to validate the estimation of the label, sampled roughness and eta. This should be
567 * activated from time to time when the BSDFs change to check if everything is still working
568 * correctly. */
569 if (*unguided_bsdf_pdf > 0.0f) {
570 surface_shader_validate_bsdf_sample(kg, sc, *wo, label, *sampled_roughness, *eta);
571 }
572# endif
573
574 if (*unguided_bsdf_pdf != 0.0f) {
575 bsdf_eval_init(bsdf_eval, sc, *wo, eval * sc->weight);
576
578
579 if (sd->num_closure > 1) {
580 const float sweight = sc->sample_weight;
581 *unguided_bsdf_pdf = _surface_shader_bsdf_eval_mis(
582 kg, sd, *wo, sc, bsdf_eval, (*unguided_bsdf_pdf) * sweight, sweight, 0);
584 }
585 *bsdf_pdf = *unguided_bsdf_pdf;
586
587 if (use_surface_guiding) {
588 guide_pdf = guiding_bsdf_pdf(kg, *wo);
589 *bsdf_pdf *= 1.0f - guiding_sampling_prob;
590 *bsdf_pdf += guiding_sampling_prob * guide_pdf * (1.0f - bssrdf_sampling_prob);
591 }
592 }
593
595 }
596
597 return label;
598}
599
600ccl_device int surface_shader_bsdf_guided_sample_closure_ris(KernelGlobals kg,
602 ccl_private ShaderData *sd,
603 const ccl_private ShaderClosure *sc,
604 const float3 rand_bsdf,
605 const ccl_private RNGState *rng_state,
608 ccl_private float *bsdf_pdf,
609 ccl_private float *mis_pdf,
610 ccl_private float *unguided_bsdf_pdf,
611 ccl_private float2 *sampled_roughness,
612 ccl_private float *eta)
613{
614 /* BSSRDF should already have been handled elsewhere. */
616
617 const bool use_surface_guiding = INTEGRATOR_STATE(state, guiding, use_surface_guiding);
618 const float guiding_sampling_prob = INTEGRATOR_STATE(
619 state, guiding, surface_guiding_sampling_prob);
620 const float bssrdf_sampling_prob = INTEGRATOR_STATE(state, guiding, bssrdf_sampling_prob);
621
622 /* Decide between sampling guiding distribution and BSDF. */
623 const float rand_bsdf_guiding = INTEGRATOR_STATE(state, guiding, sample_surface_guiding_rand);
624
625 /* Initialize to zero. */
626 int label = LABEL_NONE;
627 Spectrum eval = zero_spectrum();
629
630 *unguided_bsdf_pdf = 0.0f;
631 float guide_pdf = 0.0f;
632
633 if (use_surface_guiding && guiding_sampling_prob > 0.0f) {
634 /* Performing guided sampling using RIS */
635
636 // selected RIS candidate
637 int ris_idx = 0;
638
639 // meta data for the two RIS candidates
640 GuidingRISSample ris_samples[2];
641 ris_samples[0].rand = rand_bsdf;
642 ris_samples[1].rand = path_state_rng_3D(kg, rng_state, PRNG_SURFACE_RIS_GUIDING_0);
643
644 // ----------------------------------------------------
645 // generate the first RIS candidate using a BSDF sample
646 // ----------------------------------------------------
647 ris_samples[0].label = bsdf_sample(kg,
648 sd,
649 sc,
650 ris_samples[0].rand,
651 &ris_samples[0].eval,
652 &ris_samples[0].wo,
653 &ris_samples[0].bsdf_pdf,
654 &ris_samples[0].sampled_roughness,
655 &ris_samples[0].eta);
656
658 &ris_samples[0].bsdf_eval, sc, ris_samples[0].wo, ris_samples[0].eval * sc->weight);
659 if (ris_samples[0].bsdf_pdf > 0.0f) {
660 if (sd->num_closure > 1) {
661 const float sweight = sc->sample_weight;
662 ris_samples[0].bsdf_pdf = _surface_shader_bsdf_eval_mis(kg,
663 sd,
664 ris_samples[0].wo,
665 sc,
666 &ris_samples[0].bsdf_eval,
667 (ris_samples[0].bsdf_pdf) *
668 sweight,
669 sweight,
670 0);
671 kernel_assert(reduce_min(bsdf_eval_sum(&ris_samples[0].bsdf_eval)) >= 0.0f);
672 }
673 ris_samples[0].avg_bsdf_eval = average(ris_samples[0].bsdf_eval.sum);
674 ris_samples[0].guide_pdf = guiding_bsdf_pdf(kg, ris_samples[0].wo);
675 ris_samples[0].guide_pdf *= (1.0f - bssrdf_sampling_prob);
677 kg, ris_samples[0].wo);
678 ris_samples[0].bsdf_pdf = max(0.0f, ris_samples[0].bsdf_pdf);
679 }
680
681 // ------------------------------------------------------------------------------
682 // generate the second RIS candidate using a sample from the guiding distribution
683 // ------------------------------------------------------------------------------
684 float unguided_bsdf_pdfs[MAX_CLOSURE];
685 bsdf_eval_init(&ris_samples[1].bsdf_eval, eval);
686 ris_samples[1].guide_pdf = guiding_bsdf_sample(
687 kg, make_float2(ris_samples[1].rand), &ris_samples[1].wo);
688 ris_samples[1].guide_pdf *= (1.0f - bssrdf_sampling_prob);
690 kg, ris_samples[1].wo);
692 kg, sd, ris_samples[1].wo, &ris_samples[1].bsdf_eval, unguided_bsdf_pdfs, 0);
693 ris_samples[1].label = ris_samples[0].label;
694 ris_samples[1].avg_bsdf_eval = average(ris_samples[1].bsdf_eval.sum);
695 ris_samples[1].bsdf_pdf = max(0.0f, ris_samples[1].bsdf_pdf);
696
697 // ------------------------------------------------------------------------------
698 // calculate the RIS target functions for each RIS candidate
699 // ------------------------------------------------------------------------------
700 int num_ris_candidates = 0;
701 float sum_ris_weights = 0.0f;
702 if (calculate_ris_target(&ris_samples[0], guiding_sampling_prob)) {
703 sum_ris_weights += ris_samples[0].ris_weight;
704 num_ris_candidates++;
705 }
706 kernel_assert(ris_samples[0].ris_weight >= 0.0f);
707 kernel_assert(sum_ris_weights >= 0.0f);
708
709 if (calculate_ris_target(&ris_samples[1], guiding_sampling_prob)) {
710 sum_ris_weights += ris_samples[1].ris_weight;
711 num_ris_candidates++;
712 }
713 kernel_assert(ris_samples[1].ris_weight >= 0.0f);
714 kernel_assert(sum_ris_weights >= 0.0f);
715
716 // ------------------------------------------------------------------------------
717 // Sample/Select a sample from the RIS candidates proportional to the target
718 // ------------------------------------------------------------------------------
719 if (num_ris_candidates == 0 || !(sum_ris_weights > 1e-10f)) {
720 *bsdf_pdf = 0.0f;
721 *mis_pdf = 0.0f;
722 return label;
723 }
724
725 const float rand_ris_select = rand_bsdf_guiding * sum_ris_weights;
726
727 float sum_ris = 0.0f;
728 for (int i = 0; i < 2; i++) {
729 sum_ris += ris_samples[i].ris_weight;
730 if (rand_ris_select <= sum_ris) {
731 ris_idx = i;
732 break;
733 }
734 }
735
736 kernel_assert(sum_ris >= 0.0f);
737 kernel_assert(ris_idx < 2);
738
739 // ------------------------------------------------------------------------------
740 // Fill in the sample data for the selected RIS candidate
741 // ------------------------------------------------------------------------------
742 guide_pdf = ris_samples[ris_idx].ris_target * (2.0f / sum_ris_weights);
743 *unguided_bsdf_pdf = ris_samples[ris_idx].bsdf_pdf;
744 *mis_pdf = 0.5f * (ris_samples[ris_idx].bsdf_pdf + ris_samples[ris_idx].guide_pdf);
745 *bsdf_pdf = guide_pdf;
746
747 *wo = ris_samples[ris_idx].wo;
748 label = ris_samples[ris_idx].label;
749
750 *sampled_roughness = ris_samples[ris_idx].sampled_roughness;
751 *eta = ris_samples[ris_idx].eta;
752 *bsdf_eval = ris_samples[ris_idx].bsdf_eval;
753
754 kernel_assert(isfinite_safe(guide_pdf));
755 kernel_assert(isfinite_safe(*bsdf_pdf));
756
757 if (!(*bsdf_pdf > 1e-10f)) {
758 *bsdf_pdf = 0.0f;
759 *mis_pdf = 0.0f;
760 return label;
761 }
762
763 kernel_assert(*bsdf_pdf > 0.0f);
764 kernel_assert(*bsdf_pdf >= 1e-20f);
765 kernel_assert(guide_pdf >= 0.0f);
766
768 if (ris_idx == 1 && ris_samples[1].bsdf_pdf > 0.0f) {
769
770 const float rnd = path_state_rng_1D(kg, rng_state, PRNG_SURFACE_RIS_GUIDING_1);
771
772 float sum_pdfs = 0.0f;
773 int idx = -1;
774 for (int i = 0; i < sd->num_closure; i++) {
775 sum_pdfs += unguided_bsdf_pdfs[i];
776 if (rnd <= sum_pdfs) {
777 idx = i;
778 break;
779 }
780 }
781 // kernel_assert(idx >= 0);
782 /* Set the default idx to the last in the list.
783 * in case of numerical problems and rand_bsdf_guiding is just >=1.0f and
784 * the sum of all unguided_bsdf_pdfs is just < 1.0f. */
785 idx = (rnd > sum_pdfs) ? sd->num_closure - 1 : idx;
786
787 label = bsdf_label(kg, &sd->closure[idx], *wo);
788 bsdf_roughness_eta(&sd->closure[idx], *wo, sampled_roughness, eta);
789 }
790
791 kernel_assert(isfinite_safe(*bsdf_pdf));
792 kernel_assert(*bsdf_pdf >= 0.0f);
794 }
795 else {
796 /* Sample BSDF. */
797 *bsdf_pdf = 0.0f;
798 label = bsdf_sample(
799 kg, sd, sc, rand_bsdf, &eval, wo, unguided_bsdf_pdf, sampled_roughness, eta);
800# ifdef WITH_CYCLES_DEBUG
801 // Code path to validate the estimation of the label, sampled roughness and eta
802 // This should be activated from time to time when the BSDFs change to check if everything
803 // is still working correctly.
804 if (*unguided_bsdf_pdf > 0.0f) {
805 surface_shader_validate_bsdf_sample(kg, sc, *wo, label, *sampled_roughness, *eta);
806 }
807# endif
808
809 if (*unguided_bsdf_pdf != 0.0f) {
810 bsdf_eval_init(bsdf_eval, sc, *wo, eval * sc->weight);
811
813
814 if (sd->num_closure > 1) {
815 const float sweight = sc->sample_weight;
816 *unguided_bsdf_pdf = _surface_shader_bsdf_eval_mis(
817 kg, sd, *wo, sc, bsdf_eval, (*unguided_bsdf_pdf) * sweight, sweight, 0);
819 }
820 *bsdf_pdf = *unguided_bsdf_pdf;
821 *mis_pdf = *bsdf_pdf;
822 }
823
825 }
826
827 return label;
828}
829
830ccl_device int surface_shader_bsdf_guided_sample_closure(KernelGlobals kg,
832 ccl_private ShaderData *sd,
833 const ccl_private ShaderClosure *sc,
834 const float3 rand_bsdf,
837 ccl_private float *bsdf_pdf,
838 ccl_private float *mis_pdf,
839 ccl_private float *unguided_bsdf_pdf,
840 ccl_private float2 *sampled_roughness,
841 ccl_private float *eta,
842 const ccl_private RNGState *rng_state)
843{
844 int label = LABEL_NONE;
845 if (kernel_data.integrator.guiding_directional_sampling_type ==
847 kernel_data.integrator.guiding_directional_sampling_type ==
849 {
850 label = surface_shader_bsdf_guided_sample_closure_mis(kg,
851 state,
852 sd,
853 sc,
854 rand_bsdf,
855 bsdf_eval,
856 wo,
857 bsdf_pdf,
858 unguided_bsdf_pdf,
859 sampled_roughness,
860 eta);
861 *mis_pdf = (*unguided_bsdf_pdf > 0.0f) ? *bsdf_pdf : 0.0f;
862 }
863 else if (kernel_data.integrator.guiding_directional_sampling_type ==
865 {
866 label = surface_shader_bsdf_guided_sample_closure_ris(kg,
867 state,
868 sd,
869 sc,
870 rand_bsdf,
871 rng_state,
872 bsdf_eval,
873 wo,
874 bsdf_pdf,
875 mis_pdf,
876 unguided_bsdf_pdf,
877 sampled_roughness,
878 eta);
879 }
880 if (!(*unguided_bsdf_pdf > 0.0f)) {
881 *bsdf_pdf = 0.0f;
882 *mis_pdf = 0.0f;
883 }
884 return label;
885}
886
887#endif
888
889/* Sample direction for picked BSDF, and return evaluation and pdf for all
890 * BSDFs combined using MIS. */
892 ccl_private ShaderData *sd,
893 const ccl_private ShaderClosure *sc,
894 const float3 rand_bsdf,
897 ccl_private float *pdf,
898 ccl_private float2 *sampled_roughness,
899 ccl_private float *eta)
900{
901 /* BSSRDF should already have been handled elsewhere. */
903
904 int label;
905 Spectrum eval = zero_spectrum();
906
907 *pdf = 0.0f;
908 label = bsdf_sample(kg, sd, sc, rand_bsdf, &eval, wo, pdf, sampled_roughness, eta);
909
910 if (*pdf != 0.0f) {
911 bsdf_eval_init(bsdf_eval, sc, *wo, eval * sc->weight);
912
913 if (sd->num_closure > 1) {
914 const float sweight = sc->sample_weight;
915 *pdf = _surface_shader_bsdf_eval_mis(kg, sd, *wo, sc, bsdf_eval, *pdf * sweight, sweight, 0);
916 }
917 }
918 else {
920 }
921
922 return label;
923}
924
926{
927 float roughness = 0.0f;
928 float sum_weight = 0.0f;
929
930 for (int i = 0; i < sd->num_closure; i++) {
931 const ccl_private ShaderClosure *sc = &sd->closure[i];
932
933 if (CLOSURE_IS_BSDF(sc->type)) {
934 /* `sqrt()` once to undo the squaring from multiplying roughness on the
935 * two axes, and once for the squared roughness convention. */
936 const float value = bsdf_get_roughness_pass_squared(sc);
937 if (value >= 0.0f) {
938 const float weight = fabsf(average(sc->weight));
939 roughness += weight * sqrtf(sqrtf(value));
940 sum_weight += weight;
941 }
942 }
943 }
944
945 return (sum_weight > 0.0f) ? roughness / sum_weight : 1.0f;
946}
947
949{
950 if (sd->flag & SD_HAS_ONLY_VOLUME) {
951 return one_spectrum();
952 }
953 if (sd->flag & (SD_TRANSPARENT | SD_RAY_PORTAL)) {
954 return sd->closure_transparent_extinction;
955 }
956 return zero_spectrum();
957}
958
960{
962
963 alpha = saturate(alpha);
964
965 return alpha;
966}
967
969{
970 Spectrum eval = zero_spectrum();
971
972 for (int i = 0; i < sd->num_closure; i++) {
973 const ccl_private ShaderClosure *sc = &sd->closure[i];
974
975 if (CLOSURE_IS_BSDF_DIFFUSE(sc->type) || CLOSURE_IS_BSSRDF(sc->type)) {
976 eval += bsdf_albedo(kg, sd, sc, true, true);
977 }
978 }
979
980 return eval;
981}
982
984{
985 Spectrum eval = zero_spectrum();
986
987 for (int i = 0; i < sd->num_closure; i++) {
988 const ccl_private ShaderClosure *sc = &sd->closure[i];
989
990 if (CLOSURE_IS_BSDF_GLOSSY(sc->type) || CLOSURE_IS_GLASS(sc->type)) {
991 eval += bsdf_albedo(kg, sd, sc, true, false);
992 }
993 }
994
995 return eval;
996}
997
999{
1000 Spectrum eval = zero_spectrum();
1001
1002 for (int i = 0; i < sd->num_closure; i++) {
1003 const ccl_private ShaderClosure *sc = &sd->closure[i];
1004
1005 if (CLOSURE_IS_BSDF_TRANSMISSION(sc->type) || CLOSURE_IS_GLASS(sc->type)) {
1006 eval += bsdf_albedo(kg, sd, sc, false, true);
1007 }
1008 }
1009
1010 return eval;
1011}
1012
1014{
1015 float3 N = zero_float3();
1016
1017 for (int i = 0; i < sd->num_closure; i++) {
1018 const ccl_private ShaderClosure *sc = &sd->closure[i];
1019 if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
1020 N += sc->N * fabsf(average(sc->weight));
1021 }
1022 }
1023
1024 return (is_zero(N)) ? sd->N : normalize(N);
1025}
1026
1028 const float ao_factor,
1030{
1031 Spectrum eval = zero_spectrum();
1032 float3 N = zero_float3();
1033
1034 for (int i = 0; i < sd->num_closure; i++) {
1035 const ccl_private ShaderClosure *sc = &sd->closure[i];
1036
1037 if (CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
1038 const ccl_private DiffuseBsdf *bsdf = (const ccl_private DiffuseBsdf *)sc;
1039 eval += sc->weight * ao_factor;
1040 N += bsdf->N * fabsf(average(sc->weight));
1041 }
1042 }
1043
1044 *N_ = (is_zero(N)) ? sd->N : normalize(N);
1045 return eval;
1046}
1047
1048#ifdef __SUBSURFACE__
1049ccl_device float3 surface_shader_bssrdf_normal(const ccl_private ShaderData *sd)
1050{
1051 float3 N = zero_float3();
1052
1053 for (int i = 0; i < sd->num_closure; i++) {
1054 const ccl_private ShaderClosure *sc = &sd->closure[i];
1055
1056 if (CLOSURE_IS_BSSRDF(sc->type)) {
1057 const ccl_private Bssrdf *bssrdf = (const ccl_private Bssrdf *)sc;
1058 const float avg_weight = fabsf(average(sc->weight));
1059
1060 N += bssrdf->N * avg_weight;
1061 }
1062 }
1063
1064 return (is_zero(N)) ? sd->N : normalize(N);
1065}
1066#endif /* __SUBSURFACE__ */
1067
1068/* Constant emission optimization */
1069
1071 const int shader,
1072 ccl_private Spectrum *eval)
1073{
1074 const int shader_index = shader & SHADER_MASK;
1075 const int shader_flag = kernel_data_fetch(shaders, shader_index).flags;
1076
1077 if (shader_flag & SD_HAS_CONSTANT_EMISSION) {
1078 const float3 emission_rgb = make_float3(
1079 kernel_data_fetch(shaders, shader_index).constant_emission[0],
1080 kernel_data_fetch(shaders, shader_index).constant_emission[1],
1081 kernel_data_fetch(shaders, shader_index).constant_emission[2]);
1082 *eval = rgb_to_spectrum(emission_rgb);
1083
1084 return true;
1085 }
1086
1087 return false;
1088}
1089
1090/* Background */
1091
1093{
1094 if (sd->flag & SD_EMISSION) {
1095 return sd->closure_emission_background;
1096 }
1097 return zero_spectrum();
1098}
1099
1100/* Emission */
1101
1103{
1104 if (sd->flag & SD_EMISSION) {
1105 return emissive_simple_eval(sd->Ng, sd->wi) * sd->closure_emission_background;
1106 }
1107 return zero_spectrum();
1108}
1109
1110/* Holdout */
1111
1113{
1114 Spectrum weight = zero_spectrum();
1115
1116 /* For objects marked as holdout, preserve transparency and remove all other
1117 * closures, replacing them with a holdout weight. */
1118 if (sd->object_flag & SD_OBJECT_HOLDOUT_MASK) {
1119 if ((sd->flag & SD_TRANSPARENT) && !(sd->flag & SD_HAS_ONLY_VOLUME)) {
1120 weight = one_spectrum() - sd->closure_transparent_extinction;
1121
1122 for (int i = 0; i < sd->num_closure; i++) {
1123 ccl_private ShaderClosure *sc = &sd->closure[i];
1124 if (!CLOSURE_IS_BSDF_TRANSPARENT(sc->type)) {
1125 sc->type = NBUILTIN_CLOSURES;
1126 }
1127 }
1128
1129 sd->flag &= ~(SD_CLOSURE_FLAGS - (SD_TRANSPARENT | SD_BSDF));
1130 }
1131 else {
1132 weight = one_spectrum();
1133 }
1134 }
1135 else {
1136 for (int i = 0; i < sd->num_closure; i++) {
1137 const ccl_private ShaderClosure *sc = &sd->closure[i];
1138 if (CLOSURE_IS_HOLDOUT(sc->type)) {
1139 weight += sc->weight;
1140 }
1141 }
1142 }
1143
1144 return weight;
1145}
1146
1147/* Surface Evaluation */
1148
1149template<uint node_feature_mask, typename ConstIntegratorGenericState>
1151 ConstIntegratorGenericState state,
1152 ccl_private ShaderData *ccl_restrict sd,
1153 ccl_global float *ccl_restrict buffer,
1154 const uint32_t path_flag,
1155 bool use_caustics_storage = false)
1156{
1157 /* If path is being terminated, we are tracing a shadow ray or evaluating
1158 * emission, then we don't need to store closures. The emission and shadow
1159 * shader data also do not have a closure array to save GPU memory. */
1160 int max_closures;
1162 max_closures = 0;
1163 }
1164 else {
1165 max_closures = use_caustics_storage ? CAUSTICS_MAX_CLOSURE : kernel_data.max_closures;
1166 }
1167
1168 sd->num_closure = 0;
1169 sd->num_closure_left = max_closures;
1170 sd->closure_transparent_extinction = zero_spectrum();
1171
1172#ifdef __OSL__
1173 if (kernel_data.kernel_features & KERNEL_FEATURE_OSL_SHADING) {
1174 osl_eval_nodes<SHADER_TYPE_SURFACE>(kg, state, sd, path_flag);
1175 }
1176 else
1177#endif
1178 {
1179#ifdef __SVM__
1181#else
1182 if (sd->object == OBJECT_NONE) {
1183 sd->closure_emission_background = make_spectrum(0.8f);
1184 sd->flag |= SD_EMISSION;
1185 }
1186 else {
1188 sd, sizeof(DiffuseBsdf), make_spectrum(0.8f));
1189 if (bsdf != nullptr) {
1190 bsdf->N = sd->N;
1191 sd->flag |= bsdf_diffuse_setup(bsdf);
1192 }
1193 }
1194#endif
1195 }
1196}
1197
MINLINE float safe_sqrtf(float a)
unsigned int uint
ccl_device_inline ccl_private ShaderClosure * bsdf_alloc(ccl_private ShaderData *sd, const int size, Spectrum weight)
Definition alloc.h:55
CCL_NAMESPACE_BEGIN ccl_device_inline float bsdf_get_specular_roughness_squared(const ccl_private ShaderClosure *sc)
Definition bsdf.h:29
ccl_device Spectrum bsdf_eval(KernelGlobals kg, ccl_private ShaderData *sd, const ccl_private ShaderClosure *sc, const float3 wo, ccl_private float *pdf)
Definition bsdf.h:512
ccl_device_inline void bsdf_roughness_eta(const ccl_private ShaderClosure *sc, const float3 wo, ccl_private float2 *roughness, ccl_private float *eta)
Definition bsdf.h:297
ccl_device_inline float bsdf_get_roughness_pass_squared(const ccl_private ShaderClosure *sc)
Definition bsdf.h:43
ccl_device_inline int bsdf_label(const KernelGlobals kg, const ccl_private ShaderClosure *sc, const float3 wo)
Definition bsdf.h:404
ccl_device_inline int bsdf_sample(KernelGlobals kg, ccl_private ShaderData *sd, const ccl_private ShaderClosure *sc, const float3 rand, ccl_private Spectrum *eval, ccl_private float3 *wo, ccl_private float *pdf, ccl_private float2 *sampled_roughness, ccl_private float *eta)
Definition bsdf.h:144
ccl_device_inline Spectrum bsdf_albedo(KernelGlobals kg, const ccl_private ShaderData *sd, const ccl_private ShaderClosure *sc, const bool reflection, const bool transmission)
Definition bsdf.h:648
ccl_device void bsdf_blur(ccl_private ShaderClosure *sc, const float roughness)
Definition bsdf.h:617
ccl_device int bsdf_diffuse_setup(ccl_private DiffuseBsdf *bsdf)
static T sum(const btAlignedObjectArray< T > &items)
void osl_eval_nodes< SHADER_TYPE_SURFACE >(const ThreadKernelGlobalsCPU *kg, const void *state, ShaderData *sd, const uint32_t path_flag)
Definition closures.cpp:82
#define kernel_assert(cond)
#define CLOSURE_IS_GLASS(type)
#define kernel_data
#define ccl_restrict
#define ccl_device_forceinline
#define KERNEL_FEATURE_PATH_GUIDING
#define kernel_data_fetch(name, index)
#define CLOSURE_IS_HOLDOUT(type)
#define one_spectrum
#define CLOSURE_IS_BSDF_TRANSPARENT(type)
#define CLOSURE_IS_BSDF_TRANSMISSION(type)
#define CLOSURE_IS_BSDF(type)
#define zero_spectrum
#define OBJECT_NONE
#define KERNEL_FEATURE_OSL_SHADING
#define make_spectrum(f)
#define CLOSURE_IS_BSDF_GLOSSY(type)
#define ccl_private
const ThreadKernelGlobalsCPU * KernelGlobals
#define ccl_device_inline
#define CLOSURE_IS_BSDF_DIFFUSE(type)
#define MAX_CLOSURE
#define ccl_global
#define CLOSURE_IS_BSDF_OR_BSSRDF(type)
#define __MNEE__
#define CLOSURE_IS_BSSRDF(type)
#define CAUSTICS_MAX_CLOSURE
#define BSDF_ROUGHNESS_SQ_THRESH
#define CCL_NAMESPACE_END
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
ccl_device Spectrum emissive_simple_eval(const float3 Ng, const float3 wi)
Definition emissive.h:58
VecBase< float, D > normalize(VecOp< float, D >) RET
ccl_device_forceinline bool guiding_bsdf_init(KernelGlobals kg, const float3 P, const float3 N, ccl_private float &rand)
ccl_device_forceinline float guiding_surface_incoming_radiance_pdf(KernelGlobals kg, const float3 wo)
ccl_device_forceinline float guiding_bsdf_pdf(KernelGlobals kg, const float3 wo)
ccl_device_forceinline float guiding_bsdf_sample(KernelGlobals kg, const float2 rand_bsdf, ccl_private float3 *wo)
ccl_device_forceinline bool calculate_ris_target(ccl_private GuidingRISSample *ris_sample, const ccl_private float guiding_sampling_prob)
ccl_device void svm_eval_nodes(KernelGlobals kg, ConstIntegratorGenericState state, ccl_private ShaderData *sd, ccl_global float *render_buffer, const uint32_t path_flag)
ClosureType
@ CLOSURE_NONE_ID
@ CLOSURE_HOLDOUT_ID
@ NBUILTIN_CLOSURES
@ CLOSURE_BSDF_TRANSLUCENT_ID
@ PATH_MNEE_VALID
@ FILTER_CLOSURE_EMISSION
@ FILTER_CLOSURE_GLOSSY
@ FILTER_CLOSURE_DIFFUSE
@ FILTER_CLOSURE_TRANSPARENT
@ FILTER_CLOSURE_DIRECT_LIGHT
@ FILTER_CLOSURE_TRANSMISSION
@ SD_CLOSURE_FLAGS
@ SD_BSDF_HAS_EVAL
@ SD_HAS_CONSTANT_EMISSION
@ SD_HAS_ONLY_VOLUME
@ SD_BSDF
@ SD_RAY_PORTAL
@ SD_TRANSPARENT
@ SD_HOLDOUT
@ SD_EMISSION
@ PRNG_SURFACE_BSDF_GUIDING
@ PRNG_SURFACE_RIS_GUIDING_0
@ PRNG_SURFACE_RIS_GUIDING_1
@ PATH_RAY_SHADOW
@ PATH_RAY_TERMINATE
@ PATH_RAY_EMISSION
@ PATH_RAY_CAMERA
@ SHADER_EXCLUDE_DIFFUSE
@ SHADER_USE_MIS
@ SHADER_EXCLUDE_ANY
@ SHADER_EXCLUDE_GLOSSY
@ SHADER_EXCLUDE_TRANSMIT
@ SHADER_MASK
@ GUIDING_DIRECTIONAL_SAMPLING_TYPE_PRODUCT_MIS
@ GUIDING_DIRECTIONAL_SAMPLING_TYPE_RIS
@ GUIDING_DIRECTIONAL_SAMPLING_TYPE_ROUGHNESS
@ SD_OBJECT_HOLDOUT_MASK
@ LABEL_NONE
ccl_device_inline Spectrum rgb_to_spectrum(const float3 rgb)
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 bsdf_eval_accum(ccl_private BsdfEval *eval, const ccl_private ShaderClosure *sc, const float3 wo, Spectrum value)
ccl_device_inline Spectrum bsdf_eval_sum(const ccl_private BsdfEval *eval)
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 reduce_min(const float2 a)
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
Definition math_float3.h:17
static ulong state[N]
#define N
float average(point a)
Definition node_math.h:144
ccl_device_inline float path_state_rng_1D(KernelGlobals kg, const ccl_private RNGState *rng_state, const int dimension)
Definition path_state.h:353
ccl_device_inline float3 path_state_rng_3D(KernelGlobals kg, const ccl_private RNGState *rng_state, const int dimension)
Definition path_state.h:369
#define sqr
#define fabsf
#define sqrtf
#define ccl_device
#define make_float2
#define saturate(a)
Definition smaa.cc:315
#define INTEGRATOR_STATE_WRITE(state, nested_struct, member)
Definition state.h:236
#define INTEGRATOR_STATE(state, nested_struct, member)
Definition state.h:235
IntegratorStateCPU * IntegratorState
Definition state.h:228
const IntegratorStateCPU * ConstIntegratorState
Definition state.h:229
#define FLT_MAX
Definition stdcycles.h:14
closure color bssrdf(string method, normal N, vector radius, color albedo) BUILTIN
float x
float y
const ccl_device_inline ccl_private ShaderClosure * surface_shader_bsdf_bssrdf_pick(const ccl_private ShaderData *ccl_restrict sd, ccl_private float3 *rand_bsdf)
ccl_device float surface_shader_bsdf_eval(KernelGlobals kg, IntegratorState state, ccl_private ShaderData *sd, const float3 wo, ccl_private BsdfEval *bsdf_eval, const uint light_shader_flags)
ccl_device float surface_shader_average_roughness(const ccl_private ShaderData *sd)
ccl_device Spectrum surface_shader_transmission(KernelGlobals kg, const ccl_private ShaderData *sd)
ccl_device int surface_shader_bsdf_sample_closure(KernelGlobals kg, ccl_private ShaderData *sd, const ccl_private ShaderClosure *sc, const float3 rand_bsdf, ccl_private BsdfEval *bsdf_eval, ccl_private float3 *wo, ccl_private float *pdf, ccl_private float2 *sampled_roughness, ccl_private float *eta)
ccl_device_forceinline bool _surface_shader_exclude(ClosureType type, const uint light_shader_flags)
ccl_device float3 surface_shader_average_normal(const ccl_private ShaderData *sd)
ccl_device void surface_shader_eval(KernelGlobals kg, ConstIntegratorGenericState state, ccl_private ShaderData *ccl_restrict sd, ccl_global float *ccl_restrict buffer, const uint32_t path_flag, bool use_caustics_storage=false)
ccl_device_inline float surface_shader_bsdf_eval_pdfs(const KernelGlobals kg, ccl_private ShaderData *sd, const float3 wo, ccl_private BsdfEval *result_eval, ccl_private float *pdfs, const uint light_shader_flags)
CCL_NAMESPACE_BEGIN ccl_device_inline void surface_shader_prepare_closures(KernelGlobals kg, ConstIntegratorState state, ccl_private ShaderData *sd, const uint32_t path_flag)
ccl_device Spectrum surface_shader_ao(const ccl_private ShaderData *sd, const float ao_factor, ccl_private float3 *N_)
ccl_device Spectrum surface_shader_transparency(const ccl_private ShaderData *sd)
ccl_device Spectrum surface_shader_background(const ccl_private ShaderData *sd)
ccl_device Spectrum surface_shader_glossy(KernelGlobals kg, const ccl_private ShaderData *sd)
ccl_device Spectrum surface_shader_alpha(const ccl_private ShaderData *sd)
ccl_device Spectrum surface_shader_apply_holdout(ccl_private ShaderData *sd)
ccl_device Spectrum surface_shader_diffuse(KernelGlobals kg, const ccl_private ShaderData *sd)
ccl_device_inline Spectrum surface_shader_bssrdf_sample_weight(const ccl_private ShaderData *ccl_restrict sd, const ccl_private ShaderClosure *ccl_restrict bssrdf_sc)
ccl_device Spectrum surface_shader_emission(const ccl_private ShaderData *sd)
ccl_device_inline float _surface_shader_bsdf_eval_mis(KernelGlobals kg, ccl_private ShaderData *sd, const float3 wo, const ccl_private ShaderClosure *skip_sc, ccl_private BsdfEval *result_eval, float sum_pdf, float sum_sample_weight, const uint light_shader_flags)
ccl_device bool surface_shader_constant_emission(KernelGlobals kg, const int shader, ccl_private Spectrum *eval)
i
Definition text_draw.cc:230
max
Definition text_draw.cc:251
float3 Spectrum
#define N_(msgid)