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