Blender V4.5
shade_surface.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
13
14#include "kernel/light/sample.h"
15
18
20
25
26#include "kernel/types.h"
27#include "util/math_intersect.h"
28
30
43
45 const ccl_private ShaderData *sd,
46 const float3 ray_P,
47 const float3 ray_D)
48{
49 /* No ray offset needed for other primitive types. */
50 if (!(sd->type & PRIMITIVE_TRIANGLE)) {
51 return ray_P;
52 }
53
54 /* Self intersection tests already account for the case where a ray hits the
55 * same primitive. However precision issues can still cause neighboring
56 * triangles to be hit. Here we test if the ray-triangle intersection with
57 * the same primitive would miss, implying that a neighboring triangle would
58 * be hit instead.
59 *
60 * This relies on triangle intersection to be watertight, and the object inverse
61 * object transform to match the one used by ray intersection exactly.
62 *
63 * Potential improvements:
64 * - It appears this happens when either barycentric coordinates are small,
65 * or dot(sd->Ng, ray_D) is small. Detect such cases and skip test?
66 * - Instead of ray offset, can we tweak P to lie within the triangle?
67 */
68
69 /* TODO: Investigate if there are better ray offsetting algorithms for each BVH.
70 * Cycles and Custom BVH triangle tests aren't numerically identical, meaning
71 * this method isn't ideal for them. */
72
73 float3 verts[3];
74 if (sd->type == PRIMITIVE_TRIANGLE) {
75 triangle_vertices(kg, sd->prim, verts);
76 }
77 else {
79 motion_triangle_vertices(kg, sd->object, sd->prim, sd->time, verts);
80 }
81
82 float3 local_ray_P = ray_P;
83 float3 local_ray_D = ray_D;
84
85 if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
86 const Transform itfm = object_get_inverse_transform(kg, sd);
87 local_ray_P = transform_point(&itfm, local_ray_P);
88 local_ray_D = transform_direction(&itfm, local_ray_D);
89 }
90
91 if (ray_triangle_intersect_self(local_ray_P, local_ray_D, verts)) {
92 return ray_P;
93 }
94 return ray_offset(ray_P, sd->Ng);
95}
96
99 ccl_private ShaderData *sd,
101{
102 /* Write holdout transparency to render buffer and stop if fully holdout. */
103 const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
104
105 if (((sd->flag & SD_HOLDOUT) || (sd->object_flag & SD_OBJECT_HOLDOUT_MASK)) &&
107 {
108 const Spectrum holdout_weight = surface_shader_apply_holdout(kg, sd);
109 const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput);
110 const float transparent = average(holdout_weight * throughput);
111 film_write_holdout(kg, state, path_flag, transparent, render_buffer);
112 if (isequal(holdout_weight, one_spectrum())) {
113 return false;
114 }
115 }
116
117 return true;
118}
119
122 const ccl_private ShaderData *sd,
125{
126 const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
127
128#ifdef __LIGHT_LINKING__
129 if (!light_link_object_match(kg, light_link_receiver_forward(kg, state), sd->object) &&
130 !(path_flag & PATH_RAY_CAMERA))
131 {
132 return;
133 }
134#endif
135
136#ifdef __SHADOW_LINKING__
137 /* Indirect emission of shadow-linked emissive surfaces is done via shadow rays to dedicated
138 * light sources. */
139 if (kernel_data.kernel_features & KERNEL_FEATURE_SHADOW_LINKING) {
140 if (!(path_flag & PATH_RAY_CAMERA) &&
141 kernel_data_fetch(objects, sd->object).shadow_set_membership != LIGHT_LINK_MASK_ALL)
142 {
143 return;
144 }
145 }
146#endif
147
148 /* Evaluate emissive closure. */
150
151 const float mis_weight = light_sample_mis_weight_forward_surface(kg, state, path_flag, sd);
152
153 guiding_record_surface_emission(kg, state, L, mis_weight);
155 kg, state, L, mis_weight, render_buffer, object_lightgroup(kg, sd->object));
156}
157
160 ccl_private ShaderData *sd,
161 const ccl_private ShaderClosure *sc)
162{
164
165 float sum_sample_weight = 0.0f;
166 for (int i = 0; i < sd->num_closure; i++) {
167 const ccl_private ShaderClosure *sc = &sd->closure[i];
168
169 if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
170 sum_sample_weight += sc->sample_weight;
171 }
172 }
173 if (sum_sample_weight <= 0.0f) {
174 return LABEL_NONE;
175 }
176
177 if (len_squared(sd->P - pc->P) > 1e-9f) {
178 /* if the ray origin is changed, unset the current object,
179 * so we can potentially hit the same polygon again */
180 INTEGRATOR_STATE_WRITE(state, isect, object) = OBJECT_NONE;
181 INTEGRATOR_STATE_WRITE(state, ray, P) = pc->P;
182 }
183 else {
184 INTEGRATOR_STATE_WRITE(state, ray, P) = integrate_surface_ray_offset(kg, sd, pc->P, pc->D);
185 }
186 INTEGRATOR_STATE_WRITE(state, ray, D) = pc->D;
187 INTEGRATOR_STATE_WRITE(state, ray, tmin) = 0.0f;
189#ifdef __RAY_DIFFERENTIALS__
191#endif
192
193 const float pick_pdf = pc->sample_weight / sum_sample_weight;
194 INTEGRATOR_STATE_WRITE(state, path, throughput) *= pc->weight / pick_pdf;
195
196 const int label = LABEL_TRANSMIT | LABEL_RAY_PORTAL;
197 path_state_next(kg, state, label, sd->flag);
198
199 return label;
200}
201
202/* Branch off a shadow path and initialize common part of it.
203 * THe common is between the surface shading and configuration of a special shadow ray for the
204 * shadow linking. */
208 const ccl_private Ray *ccl_restrict ray,
209 const Spectrum bsdf_spectrum,
210 const int light_group,
211 const int mnee_vertex_count)
212{
213
214 /* Branch off shadow kernel. */
217
218#ifdef __VOLUME__
219 /* Copy volume stack and enter/exit volume. */
220 integrator_state_copy_volume_stack_to_shadow(kg, shadow_state, state);
221#endif
222
223 /* Write shadow ray and associated state to global memory. */
224 integrator_state_write_shadow_ray(shadow_state, ray);
225 integrator_state_write_shadow_ray_self(kg, shadow_state, ray);
226
227 /* Copy state from main path to shadow path. */
228 const Spectrum unlit_throughput = INTEGRATOR_STATE(state, path, throughput);
229 const Spectrum throughput = unlit_throughput * bsdf_spectrum;
230
231 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, render_pixel_index) = INTEGRATOR_STATE(
232 state, path, render_pixel_index);
233 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, rng_offset) = INTEGRATOR_STATE(
234 state, path, rng_offset);
235 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, rng_pixel) = INTEGRATOR_STATE(
236 state, path, rng_pixel);
237 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, sample) = INTEGRATOR_STATE(
238 state, path, sample);
239
240 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, transparent_bounce) = INTEGRATOR_STATE(
241 state, path, transparent_bounce);
242 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, glossy_bounce) = INTEGRATOR_STATE(
243 state, path, glossy_bounce);
244
245 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, throughput) = throughput;
246
247#ifdef __MNEE__
248 if (mnee_vertex_count > 0) {
249 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, transmission_bounce) =
250 INTEGRATOR_STATE(state, path, transmission_bounce) + mnee_vertex_count - 1;
251 INTEGRATOR_STATE_WRITE(shadow_state,
252 shadow_path,
253 diffuse_bounce) = INTEGRATOR_STATE(state, path, diffuse_bounce) + 1;
254 INTEGRATOR_STATE_WRITE(shadow_state,
255 shadow_path,
256 bounce) = INTEGRATOR_STATE(state, path, bounce) + mnee_vertex_count;
257 }
258 else
259#endif
260 {
261 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, transmission_bounce) = INTEGRATOR_STATE(
262 state, path, transmission_bounce);
263 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, diffuse_bounce) = INTEGRATOR_STATE(
264 state, path, diffuse_bounce);
265 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, bounce) = INTEGRATOR_STATE(
266 state, path, bounce);
267 }
268
269 /* Write Light-group, +1 as light-group is int but we need to encode into a uint8_t. */
270 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, lightgroup) = light_group + 1;
271
272#ifdef __PATH_GUIDING__
273 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, unlit_throughput) = unlit_throughput;
274 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, path_segment) = INTEGRATOR_STATE(
275 state, guiding, path_segment);
276 INTEGRATOR_STATE(shadow_state, shadow_path, guiding_mis_weight) = 0.0f;
277#endif
278
279 return shadow_state;
280}
281
282/* Path tracing: sample point on light and evaluate light shader, then
283 * queue shadow ray to be traced. */
284template<uint node_feature_mask>
285#if defined(__KERNEL_GPU__)
287#else
288/* MSVC has very long compilation time (x20) if we force inline this function */
290#endif
291 void
294 ccl_private ShaderData *sd,
295 const ccl_private RNGState *rng_state)
296{
297 /* Test if there is a light or BSDF that needs direct light. */
298 if (!(kernel_data.integrator.use_direct_light && (sd->flag & SD_BSDF_HAS_EVAL))) {
299 return;
300 }
301
302 /* Sample position on a light. */
304 {
305 const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
306 const uint bounce = INTEGRATOR_STATE(state, path, bounce);
307 const float3 rand_light = path_state_rng_3D(kg, rng_state, PRNG_LIGHT);
308
310 rand_light,
311 sd->time,
312 sd->P,
313 sd->N,
315 sd->flag,
316 bounce,
317 path_flag,
318 &ls))
319 {
320 return;
321 }
322 }
323
324 kernel_assert(ls.pdf != 0.0f);
325
326 const bool is_transmission = dot(ls.D, sd->N) < 0.0f;
327
328 if (ls.prim != PRIM_NONE && ls.prim == sd->prim && ls.object == sd->object) {
329 /* Skip self intersection if light direction lies in the same hemisphere as the geometric
330 * normal. */
331 if (dot(ls.D, is_transmission ? -sd->Ng : sd->Ng) > 0.0f) {
332 return;
333 }
334 }
335
336 /* Evaluate light shader.
337 *
338 * TODO: can we reuse sd memory? In theory we can move this after
339 * integrate_surface_bounce, evaluate the BSDF, and only then evaluate
340 * the light shader. This could also move to its own kernel, for
341 * non-constant light sources. */
342 ShaderDataCausticsStorage emission_sd_storage;
343 ccl_private ShaderData *emission_sd = AS_SHADER_DATA(&emission_sd_storage);
344
347
348 int mnee_vertex_count = 0; // NOLINT
349#ifdef __MNEE__
351 {
352 if (ls.type != LIGHT_TRIANGLE) {
353 /* Is this a caustic light? */
354 const bool use_caustics = kernel_data_fetch(lights, ls.prim).use_caustics;
355 if (use_caustics) {
356 /* Are we on a caustic caster? */
357 if (is_transmission && (sd->object_flag & SD_OBJECT_CAUSTICS_CASTER)) {
358 return;
359 }
360
361 /* Are we on a caustic receiver? */
362 if (!is_transmission && (sd->object_flag & SD_OBJECT_CAUSTICS_RECEIVER)) {
363 mnee_vertex_count = kernel_path_mnee_sample(
364 kg, state, sd, emission_sd, rng_state, &ls, &bsdf_eval);
365 }
366 }
367 }
368 }
369 if (mnee_vertex_count > 0) {
370 /* Create shadow ray after successful manifold walk:
371 * emission_sd contains the last interface intersection and
372 * the light sample ls has been updated */
373 light_sample_to_surface_shadow_ray(kg, emission_sd, &ls, &ray);
374 }
375 else
376#endif /* __MNEE__ */
377 {
378 const Spectrum light_eval = light_sample_shader_eval(kg, state, emission_sd, &ls, sd->time);
379 if (is_zero(light_eval)) {
380 return;
381 }
382
383 /* Evaluate BSDF. */
384 const float bsdf_pdf = surface_shader_bsdf_eval(kg, state, sd, ls.D, &bsdf_eval, ls.shader);
385 const float mis_weight = light_sample_mis_weight_nee(kg, ls.pdf, bsdf_pdf);
386 bsdf_eval_mul(&bsdf_eval, light_eval / ls.pdf * mis_weight);
387
388 /* Path termination. */
389 const float terminate = path_state_rng_light_termination(kg, rng_state);
390 if (light_sample_terminate(kg, &bsdf_eval, terminate)) {
391 return;
392 }
393
394 /* Create shadow ray. */
395 light_sample_to_surface_shadow_ray(kg, sd, &ls, &ray);
396 }
397
398 if (ray.self.object != OBJECT_NONE) {
399 ray.P = integrate_surface_ray_offset(kg, sd, ray.P, ray.D);
400 }
401
402 /* Branch off shadow kernel. */
404 kg, state, &ray, bsdf_eval_sum(&bsdf_eval), ls.group, mnee_vertex_count);
405
406 if (is_transmission) {
407#ifdef __VOLUME__
408 shadow_volume_stack_enter_exit(kg, shadow_state, sd);
409#endif
410 }
411
412 uint32_t shadow_flag = INTEGRATOR_STATE(state, path, flag);
413
414 if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) {
415 PackedSpectrum pass_diffuse_weight;
416 PackedSpectrum pass_glossy_weight;
417
418 if (shadow_flag & PATH_RAY_ANY_PASS) {
419 /* Indirect bounce, use weights from earlier surface or volume bounce. */
420 pass_diffuse_weight = INTEGRATOR_STATE(state, path, pass_diffuse_weight);
421 pass_glossy_weight = INTEGRATOR_STATE(state, path, pass_glossy_weight);
422 }
423 else {
424 /* Direct light, use BSDFs at this bounce. */
425 shadow_flag |= PATH_RAY_SURFACE_PASS;
428 }
429
430 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, pass_diffuse_weight) = pass_diffuse_weight;
431 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, pass_glossy_weight) = pass_glossy_weight;
432 }
433
434 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, flag) = shadow_flag;
435}
436
437/* Path tracing: bounce off or through surface with new direction. */
439 KernelGlobals kg,
441 ccl_private ShaderData *sd,
442 const ccl_private RNGState *rng_state)
443{
444 /* Sample BSDF or BSSRDF. */
445 if (!(sd->flag & (SD_BSDF | SD_BSSRDF))) {
446 return LABEL_NONE;
447 }
448
449 float3 rand_bsdf = path_state_rng_3D(kg, rng_state, PRNG_SURFACE_BSDF);
450 const ccl_private ShaderClosure *sc = surface_shader_bsdf_bssrdf_pick(sd, &rand_bsdf);
451
452#ifdef __SUBSURFACE__
453 /* BSSRDF closure, we schedule subsurface intersection kernel. */
454 if (CLOSURE_IS_BSSRDF(sc->type)) {
455 return subsurface_bounce(kg, state, sd, sc);
456 }
457#endif
458 if (CLOSURE_IS_RAY_PORTAL(sc->type)) {
459 return integrate_surface_ray_portal(kg, state, sd, sc);
460 }
461
462 /* BSDF closure, sample direction. */
463 float bsdf_pdf = 0.0f;
464 float unguided_bsdf_pdf = 0.0f;
467 int label;
468
469 float2 bsdf_sampled_roughness = make_float2(1.0f, 1.0f);
470 float bsdf_eta = 1.0f;
471 float mis_pdf = 1.0f;
472
473#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
474 if (kernel_data.integrator.use_surface_guiding) {
475 label = surface_shader_bsdf_guided_sample_closure(kg,
476 state,
477 sd,
478 sc,
479 rand_bsdf,
480 &bsdf_eval,
481 &bsdf_wo,
482 &bsdf_pdf,
483 &mis_pdf,
484 &unguided_bsdf_pdf,
485 &bsdf_sampled_roughness,
486 &bsdf_eta,
487 rng_state);
488
489 if (bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval)) {
490 return LABEL_NONE;
491 }
492
493 INTEGRATOR_STATE_WRITE(state, path, unguided_throughput) *= bsdf_pdf / unguided_bsdf_pdf;
494 }
495 else
496#endif
497 {
499 sd,
500 sc,
502 rand_bsdf,
503 &bsdf_eval,
504 &bsdf_wo,
505 &bsdf_pdf,
506 &bsdf_sampled_roughness,
507 &bsdf_eta);
508
509 if (bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval)) {
510 return LABEL_NONE;
511 }
512 mis_pdf = bsdf_pdf;
513 unguided_bsdf_pdf = bsdf_pdf;
514 }
515
516 if (label & LABEL_TRANSPARENT) {
517 /* Only need to modify start distance for transparent. */
518 INTEGRATOR_STATE_WRITE(state, ray, tmin) = intersection_t_offset(sd->ray_length);
519 }
520 else {
521 /* Setup ray with changed origin and direction. */
522 const float3 D = normalize(bsdf_wo);
525 INTEGRATOR_STATE_WRITE(state, ray, tmin) = 0.0f;
527#ifdef __RAY_DIFFERENTIALS__
529#endif
530 }
531
532 /* Update throughput. */
533 const Spectrum bsdf_weight = bsdf_eval_sum(&bsdf_eval) / bsdf_pdf;
534 INTEGRATOR_STATE_WRITE(state, path, throughput) *= bsdf_weight;
535
536 if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) {
537 if (INTEGRATOR_STATE(state, path, bounce) == 0) {
538 INTEGRATOR_STATE_WRITE(state, path, pass_diffuse_weight) = bsdf_eval_pass_diffuse_weight(
539 &bsdf_eval);
540 INTEGRATOR_STATE_WRITE(state, path, pass_glossy_weight) = bsdf_eval_pass_glossy_weight(
541 &bsdf_eval);
542 }
543 }
544
545 /* Update path state */
546 if (!(label & LABEL_TRANSPARENT)) {
547 INTEGRATOR_STATE_WRITE(state, path, mis_ray_pdf) = mis_pdf;
548 INTEGRATOR_STATE_WRITE(state, path, mis_origin_n) = sd->N;
549 INTEGRATOR_STATE_WRITE(state, path, min_ray_pdf) = fminf(
550 unguided_bsdf_pdf, INTEGRATOR_STATE(state, path, min_ray_pdf));
551
552#ifdef __LIGHT_LINKING__
553 if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_LINKING) {
554 INTEGRATOR_STATE_WRITE(state, path, mis_ray_object) = sd->object;
555 }
556#endif
557 }
558
559 path_state_next(kg, state, label, sd->flag);
560
562 state,
563 sd,
564 bsdf_weight,
565 bsdf_pdf,
566 sd->N,
567 normalize(bsdf_wo),
568 bsdf_sampled_roughness,
569 bsdf_eta);
570
571 return label;
572}
573
574#ifdef __VOLUME__
575ccl_device_forceinline int integrate_surface_volume_only_bounce(IntegratorState state,
576 ccl_private ShaderData *sd)
577{
578 if (!path_state_volume_next(state)) {
579 return LABEL_NONE;
580 }
581
582 /* Only modify start distance. */
583 INTEGRATOR_STATE_WRITE(state, ray, tmin) = intersection_t_offset(sd->ray_length);
584
586}
587#endif
588
590 const uint32_t path_flag)
591{
592 const float continuation_probability = (path_flag & PATH_RAY_TERMINATE_ON_NEXT_SURFACE) ?
593 0.0f :
595 state, path, continuation_probability);
596 if (continuation_probability == 0.0f) {
597 return true;
598 }
599 if (continuation_probability != 1.0f) {
600 INTEGRATOR_STATE_WRITE(state, path, throughput) /= continuation_probability;
601 }
602
603 return false;
604}
605
606#if defined(__AO__)
607ccl_device_forceinline void integrate_surface_ao(KernelGlobals kg,
609 const ccl_private ShaderData *ccl_restrict sd,
611 rng_state)
612{
613 const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
614
615 if (!(kernel_data.kernel_features & KERNEL_FEATURE_AO_ADDITIVE) &&
616 !(path_flag & PATH_RAY_CAMERA))
617 {
618 return;
619 }
620
621 /* Skip AO for paths that were split off for shadow catchers to avoid double-counting. */
622 if (path_flag & PATH_RAY_SHADOW_CATCHER_PASS) {
623 return;
624 }
625
626 const float2 rand_bsdf = path_state_rng_2D(kg, rng_state, PRNG_SURFACE_BSDF);
627
628 float3 ao_N;
629 const Spectrum ao_weight = surface_shader_ao(
630 kg, sd, kernel_data.integrator.ao_additive_factor, &ao_N);
631
632 float3 ao_D;
633 float ao_pdf;
634 sample_cos_hemisphere(ao_N, rand_bsdf, &ao_D, &ao_pdf);
635
636 bool skip_self = true;
637
639 ray.P = shadow_ray_offset(kg, sd, ao_D, &skip_self);
640 ray.D = ao_D;
641 if (skip_self) {
642 ray.P = integrate_surface_ray_offset(kg, sd, ray.P, ray.D);
643 }
644 ray.tmin = 0.0f;
645 ray.tmax = kernel_data.integrator.ao_bounces_distance;
646 ray.time = sd->time;
647 ray.self.object = (skip_self) ? sd->object : OBJECT_NONE;
648 ray.self.prim = (skip_self) ? sd->prim : PRIM_NONE;
649 ray.self.light_object = OBJECT_NONE;
650 ray.self.light_prim = PRIM_NONE;
651 ray.dP = differential_zero_compact();
652 ray.dD = differential_zero_compact();
653
654 /* Branch off shadow kernel. */
657
658# ifdef __VOLUME__
659 /* Copy volume stack and enter/exit volume. */
660 integrator_state_copy_volume_stack_to_shadow(kg, shadow_state, state);
661# endif
662
663 /* Write shadow ray and associated state to global memory. */
664 integrator_state_write_shadow_ray(shadow_state, &ray);
665 integrator_state_write_shadow_ray_self(kg, shadow_state, &ray);
666
667 /* Copy state from main path to shadow path. */
668 const uint16_t bounce = INTEGRATOR_STATE(state, path, bounce);
669 const uint16_t transparent_bounce = INTEGRATOR_STATE(state, path, transparent_bounce);
670 const uint32_t shadow_flag = INTEGRATOR_STATE(state, path, flag) | PATH_RAY_SHADOW_FOR_AO;
671 const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput) *
672 surface_shader_alpha(kg, sd);
673
674 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, render_pixel_index) = INTEGRATOR_STATE(
675 state, path, render_pixel_index);
676 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, rng_offset) = INTEGRATOR_STATE(
677 state, path, rng_offset);
678 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, rng_pixel) = INTEGRATOR_STATE(
679 state, path, rng_pixel);
680 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, sample) = INTEGRATOR_STATE(
681 state, path, sample);
682 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, flag) = shadow_flag;
683 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, bounce) = bounce;
684 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, transparent_bounce) = transparent_bounce;
685 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, throughput) = throughput;
686
687 if (kernel_data.kernel_features & KERNEL_FEATURE_AO_ADDITIVE) {
688 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, unshadowed_throughput) = ao_weight;
689 }
690}
691#endif /* defined(__AO__) */
692
693template<uint node_feature_mask>
697
698{
700
701 /* Setup shader data. */
702 ShaderData sd;
704 PROFILING_SHADER(sd.object, sd.shader);
705
706 int continue_path_label = 0;
707
708 const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
709
710 /* Skip most work for volume bounding surface. */
711#ifdef __VOLUME__
712 if (!(sd.flag & SD_HAS_ONLY_VOLUME)) {
713#endif
715
716#ifdef __SUBSURFACE__
717 /* Can skip shader evaluation for BSSRDF exit point without bump mapping. */
718 if (!(path_flag & PATH_RAY_SUBSURFACE) || ((sd.flag & SD_HAS_BSSRDF_BUMP)))
719#endif
720 {
721 /* Evaluate shader. */
724
725 /* Initialize additional RNG for BSDFs. */
726 if (sd.flag & SD_BSDF_NEEDS_LCG) {
727 sd.lcg_state = lcg_state_init(INTEGRATOR_STATE(state, path, rng_pixel),
728 INTEGRATOR_STATE(state, path, rng_offset),
730 0xb4bc3953);
731 }
732 }
733
734#ifdef __SUBSURFACE__
735 if (path_flag & PATH_RAY_SUBSURFACE) {
736 /* When coming from inside subsurface scattering, setup a diffuse
737 * closure to perform lighting at the exit point. */
738 subsurface_shader_data_setup(kg, state, &sd, path_flag);
740 }
741 else
742#endif
743 {
744 /* Filter closures. */
745 surface_shader_prepare_closures(kg, state, &sd, path_flag);
746
747 /* Evaluate holdout. */
749 return LABEL_NONE;
750 }
751
752 /* Write emission. */
753 if (sd.flag & SD_EMISSION) {
755 }
756
757 /* Perform path termination. Most paths have already been terminated in
758 * the intersect_closest kernel, this is just for emission and for dividing
759 * throughput by the probability at the right moment.
760 *
761 * Also ensure we don't do it twice for SSS at both the entry and exit point. */
762 if (integrate_surface_terminate(state, path_flag)) {
763 return LABEL_NONE;
764 }
765
766 /* Write render passes. */
767#ifdef __PASSES__
770#endif
771
772#ifdef __DENOISING_FEATURES__
773 film_write_denoising_features_surface(kg, state, &sd, render_buffer);
774#endif
775 }
776
777 /* Load random number state. */
778 RNGState rng_state;
779 path_state_rng_load(state, &rng_state);
780
781#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
782 surface_shader_prepare_guiding(kg, state, &sd, &rng_state);
784#endif
785 /* Direct light. */
788
789#if defined(__AO__)
790 /* Ambient occlusion pass. */
791 if (kernel_data.kernel_features & KERNEL_FEATURE_AO) {
793 integrate_surface_ao(kg, state, &sd, &rng_state);
794 }
795#endif
796
798 continue_path_label = integrate_surface_bsdf_bssrdf_bounce(kg, state, &sd, &rng_state);
799#ifdef __VOLUME__
800 }
801 else {
802 if (integrate_surface_terminate(state, path_flag)) {
803 return LABEL_NONE;
804 }
805
807 continue_path_label = integrate_surface_volume_only_bounce(state, &sd);
808 }
809
810 if (continue_path_label & LABEL_TRANSMIT) {
811 /* Enter/Exit volume. */
812 volume_stack_enter_exit(kg, state, &sd);
813 }
814#endif
815
816 return continue_path_label;
817}
818
819template<DeviceKernel current_kernel>
831
837{
838 const int continue_path_label = integrate_surface<node_feature_mask>(kg, state, render_buffer);
839 if (continue_path_label == LABEL_NONE) {
840 integrator_path_terminate(kg, state, current_kernel);
841 return;
842 }
843
844#ifdef __SHADOW_LINKING__
845 /* No need to cast shadow linking rays at a transparent bounce: the lights will be accumulated
846 * via the main path in this case. */
847 if ((continue_path_label & LABEL_TRANSPARENT) == 0) {
848 if (shadow_linking_schedule_intersection_kernel<current_kernel>(kg, state)) {
849 return;
850 }
851 }
852#endif
853
855}
856
864
874
#define D
unsigned int uint
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
dot(value.rgb, luminance_coefficients)") DEFINE_VALUE("REDUCE(lhs
ccl_device_forceinline float intersection_t_offset(const float t)
ccl_device_inline float3 ray_offset(const float3 P, const float3 Ng)
ccl_device_inline bool light_sample_terminate(KernelGlobals kg, ccl_private BsdfEval *ccl_restrict eval, const float rand_terminate)
ccl_device_inline void light_sample_to_surface_shadow_ray(KernelGlobals kg, const ccl_private ShaderData *ccl_restrict sd, const ccl_private LightSample *ccl_restrict ls, ccl_private Ray *ray)
CCL_NAMESPACE_BEGIN ccl_device_noinline_cpu Spectrum light_sample_shader_eval(KernelGlobals kg, IntegratorState state, ccl_private ShaderData *ccl_restrict emission_sd, ccl_private LightSample *ccl_restrict ls, const float time)
ccl_device bool light_sample_from_position(KernelGlobals kg, const float3 rand, const float time, const float3 P, const float3 N, const int object_receiver, const int shader_flags, const int bounce, const uint32_t path_flag, ccl_private LightSample *ls)
ccl_device_inline float light_sample_mis_weight_nee(KernelGlobals kg, const float nee_pdf, const float forward_pdf)
ccl_device_inline float3 shadow_ray_offset(KernelGlobals kg, const ccl_private ShaderData *ccl_restrict sd, const float3 L, ccl_private bool *r_skip_self)
ccl_device_inline float light_sample_mis_weight_forward_surface(KernelGlobals kg, IntegratorState state, const uint32_t path_flag, const ccl_private ShaderData *sd)
ccl_device_inline void film_write_data_passes(KernelGlobals kg, IntegratorState state, const ccl_private ShaderData *sd, ccl_global float *ccl_restrict render_buffer)
Definition data_passes.h:27
#define kernel_assert(cond)
#define kernel_data
#define KERNEL_FEATURE_AO
#define ccl_restrict
#define ccl_device_forceinline
#define ccl_optional_struct_init
#define kernel_data_fetch(name, index)
#define AS_SHADER_DATA(shader_data_tiny_storage)
#define one_spectrum
#define PRIM_NONE
#define ccl_device
#define OBJECT_NONE
#define ccl_private
const ThreadKernelGlobalsCPU * KernelGlobals
#define ccl_device_inline
#define KERNEL_FEATURE_LIGHT_PASSES
#define KERNEL_FEATURE_SHADOW_LINKING
#define KERNEL_FEATURE_NODE_MASK_SURFACE
#define LIGHT_LINK_MASK_ALL
#define KERNEL_FEATURE_LIGHT_LINKING
#define ccl_global
#define CLOSURE_IS_BSDF_OR_BSSRDF(type)
#define KERNEL_FEATURE_AO_ADDITIVE
#define CLOSURE_IS_RAY_PORTAL(type)
#define CLOSURE_IS_BSSRDF(type)
#define KERNEL_FEATURE_NODE_RAYTRACE
#define KERNEL_FEATURE_MNEE
#define IF_KERNEL_FEATURE(feature)
#define CCL_NAMESPACE_END
#define fminf(x, y)
ccl_device_forceinline float2 make_float2(const float x, const float y)
ccl_device_forceinline float differential_make_compact(const float dD)
ccl_device_forceinline float differential_zero_compact()
ccl_device_inline void triangle_vertices(KernelGlobals kg, const int prim, float3 P[3])
static float verts[][3]
VecBase< float, D > normalize(VecOp< float, D >) RET
ccl_gpu_kernel_postfix ccl_global KernelWorkTile const int ccl_global float * render_buffer
ccl_device_inline Transform object_get_inverse_transform(KernelGlobals kg, const ccl_private ShaderData *sd)
ccl_device_inline int object_lightgroup(KernelGlobals kg, const int object)
ccl_device_forceinline void guiding_write_debug_passes(KernelGlobals kg, IntegratorState state, const ccl_private ShaderData *sd, ccl_global float *ccl_restrict render_buffer)
ccl_device_forceinline void guiding_record_surface_emission(KernelGlobals kg, IntegratorState state, const Spectrum Le, const float mis_weight)
ccl_device_forceinline void guiding_record_surface_bounce(KernelGlobals kg, IntegratorState state, const ccl_private ShaderData *sd, const Spectrum weight, const float pdf, const float3 N, const float3 wo, const float2 roughness, const float eta)
ccl_device_forceinline void guiding_record_surface_segment(KernelGlobals kg, IntegratorState state, const ccl_private ShaderData *sd)
ccl_device_inline bool light_link_object_match(KernelGlobals kg, const int object_receiver, const int object_emitter)
ccl_device_inline int light_link_receiver_nee(KernelGlobals kg, const ccl_private ShaderData *sd)
ccl_device_inline int light_link_receiver_forward(KernelGlobals kg, IntegratorState state)
@ SD_BSDF_HAS_EVAL
@ SD_BSSRDF
@ SD_BSDF_NEEDS_LCG
@ SD_HAS_BSSRDF_BUMP
@ SD_HAS_ONLY_VOLUME
@ SD_BSDF
@ SD_HOLDOUT
@ SD_EMISSION
@ PRIMITIVE_MOTION_TRIANGLE
@ PRIMITIVE_TRIANGLE
@ PRNG_LIGHT
@ PRNG_SURFACE_BSDF
@ PATH_RAY_SHADOW_FOR_AO
@ PATH_RAY_SHADOW_CATCHER_PASS
@ PATH_RAY_SUBSURFACE
@ PATH_RAY_SURFACE_PASS
@ PATH_RAY_TRANSPARENT_BACKGROUND
@ PATH_RAY_CAMERA
@ PATH_RAY_ANY_PASS
@ PATH_RAY_TERMINATE_ON_NEXT_SURFACE
@ SD_OBJECT_HOLDOUT_MASK
@ SD_OBJECT_CAUSTICS_RECEIVER
@ SD_OBJECT_TRANSFORM_APPLIED
@ SD_OBJECT_CAUSTICS_CASTER
@ LABEL_TRANSMIT
@ LABEL_RAY_PORTAL
@ LABEL_NONE
@ LABEL_TRANSPARENT
ShaderData ShaderDataCausticsStorage
@ LIGHT_TRIANGLE
DeviceKernel
@ DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE
@ DEVICE_KERNEL_INTEGRATOR_INTERSECT_SUBSURFACE
@ DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_RAYTRACE
@ DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_MNEE
@ DEVICE_KERNEL_INTEGRATOR_INTERSECT_SHADOW
@ DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST
ccl_device_inline uint lcg_state_init(const uint rng_hash, const uint rng_offset, const uint sample, const uint scramble)
Definition lcg.h:36
ccl_device_inline void film_write_surface_emission(KernelGlobals kg, ConstIntegratorState state, const Spectrum L, const float mis_weight, ccl_global float *ccl_restrict render_buffer, const int lightgroup=LIGHTGROUP_NONE)
ccl_device_inline void film_write_holdout(KernelGlobals kg, ConstIntegratorState state, const uint32_t path_flag, const float transparent, ccl_global float *ccl_restrict render_buffer)
ccl_device_inline bool bsdf_eval_is_zero(ccl_private BsdfEval *eval)
ccl_device_inline Spectrum bsdf_eval_pass_glossy_weight(const ccl_private BsdfEval *eval)
ccl_device_inline void bsdf_eval_mul(ccl_private BsdfEval *eval, const float value)
ccl_device_inline Spectrum bsdf_eval_sum(const ccl_private BsdfEval *eval)
ccl_device_inline Spectrum bsdf_eval_pass_diffuse_weight(const ccl_private BsdfEval *eval)
ccl_device_inline float len_squared(const float2 a)
ccl_device_inline bool is_zero(const float2 a)
ccl_device_inline float average(const float2 a)
ccl_device_inline bool isequal(const float2 a, const float2 b)
ccl_device_forceinline bool ray_triangle_intersect_self(const float3 ray_P, const float3 ray_D, const float3 verts[3])
static ulong state[N]
#define L
ccl_device_forceinline int kernel_path_mnee_sample(KernelGlobals kg, IntegratorState state, ccl_private ShaderData *sd, ccl_private ShaderData *sd_mnee, const ccl_private RNGState *rng_state, ccl_private LightSample *ls, ccl_private BsdfEval *throughput)
Definition mnee.h:948
ccl_device_inline void motion_triangle_vertices(KernelGlobals kg, const int object, const uint3 tri_vindex, const int numsteps, const int numverts, const int step, const float t, float3 verts[3])
ccl_device_inline float path_state_rng_light_termination(KernelGlobals kg, const ccl_private RNGState *state)
Definition path_state.h:401
ccl_device_inline void path_state_rng_load(ConstIntegratorState state, ccl_private RNGState *rng_state)
Definition path_state.h:314
ccl_device_inline void path_state_next(KernelGlobals kg, IntegratorState state, const int label, const int shader_flag)
Definition path_state.h:105
ccl_device_inline float2 path_state_rng_2D(KernelGlobals kg, const ccl_private RNGState *rng_state, const int dimension)
Definition path_state.h:346
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 PROFILING_INIT_FOR_SHADER(kg, event)
Definition profiler.h:17
#define PROFILING_EVENT(event)
Definition profiler.h:16
#define PROFILING_SHADER(object, shader)
Definition profiler.h:19
@ PROFILING_SHADE_SURFACE_SETUP
Definition profiling.h:25
@ PROFILING_SHADE_SURFACE_EVAL
Definition profiling.h:26
@ PROFILING_SHADE_SURFACE_INDIRECT_LIGHT
Definition profiling.h:28
@ PROFILING_SHADE_SURFACE_AO
Definition profiling.h:29
@ PROFILING_SHADE_SURFACE_DIRECT_LIGHT
Definition profiling.h:27
@ PROFILING_SHADE_SURFACE_PASSES
Definition profiling.h:30
ccl_device_inline void sample_cos_hemisphere(const float3 N, const float2 rand_in, ccl_private float3 *wo, ccl_private float *pdf)
ccl_device_forceinline float3 integrate_surface_ray_offset(KernelGlobals kg, const ccl_private ShaderData *sd, const float3 ray_P, const float3 ray_D)
ccl_device_inline IntegratorShadowState integrate_direct_light_shadow_init_common(KernelGlobals kg, IntegratorState state, const ccl_private Ray *ccl_restrict ray, const Spectrum bsdf_spectrum, const int light_group, const int mnee_vertex_count)
ccl_device_forceinline void integrator_shade_surface(KernelGlobals kg, IntegratorState state, ccl_global float *ccl_restrict render_buffer)
ccl_device_forceinline bool integrate_surface_holdout(KernelGlobals kg, ConstIntegratorState state, ccl_private ShaderData *sd, ccl_global float *ccl_restrict render_buffer)
ccl_device int integrate_surface_ray_portal(KernelGlobals kg, IntegratorState state, ccl_private ShaderData *sd, const ccl_private ShaderClosure *sc)
ccl_device int integrate_surface(KernelGlobals kg, IntegratorState state, ccl_global float *ccl_restrict render_buffer)
ccl_device_forceinline void integrator_shade_surface_mnee(KernelGlobals kg, IntegratorState state, ccl_global float *ccl_restrict render_buffer)
ccl_device_forceinline bool integrate_surface_terminate(IntegratorState state, const uint32_t path_flag)
ccl_device void integrate_surface_direct_light(KernelGlobals kg, IntegratorState state, ccl_private ShaderData *sd, const ccl_private RNGState *rng_state)
ccl_device_forceinline void integrate_surface_emission(KernelGlobals kg, IntegratorState state, const ccl_private ShaderData *sd, ccl_global float *ccl_restrict render_buffer)
ccl_device_forceinline void integrator_shade_surface_next_kernel(KernelGlobals kg, IntegratorState state)
ccl_device_forceinline void integrator_shade_surface_raytrace(KernelGlobals kg, IntegratorState state, ccl_global float *ccl_restrict render_buffer)
ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce(KernelGlobals kg, IntegratorState state, ccl_private ShaderData *sd, const ccl_private RNGState *rng_state)
CCL_NAMESPACE_BEGIN ccl_device_forceinline void integrate_surface_shader_setup(KernelGlobals kg, ConstIntegratorState state, ccl_private ShaderData *sd)
ccl_device_inline void shader_setup_from_ray(KernelGlobals kg, ccl_private ShaderData *ccl_restrict sd, const ccl_private Ray *ccl_restrict ray, const ccl_private Intersection *ccl_restrict isect)
Definition shader_data.h:39
IntegratorShadowStateCPU * IntegratorShadowState
Definition state.h:230
#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
ccl_device_forceinline void integrator_path_terminate(KernelGlobals kg, IntegratorState state, const DeviceKernel current_kernel)
Definition state_flow.h:182
ccl_device_forceinline void integrator_path_next(KernelGlobals kg, IntegratorState state, const DeviceKernel current_kernel, const DeviceKernel next_kernel)
Definition state_flow.h:173
ccl_device_forceinline IntegratorShadowState integrator_shadow_path_init(KernelGlobals kg, IntegratorState state, const DeviceKernel next_kernel, const bool is_ao)
Definition state_flow.h:201
ccl_device_forceinline void integrator_state_write_shadow_ray_self(KernelGlobals kg, IntegratorShadowState state, const ccl_private Ray *ccl_restrict ray)
Definition state_util.h:98
ccl_device_forceinline void integrator_state_read_ray(ConstIntegratorState state, ccl_private Ray *ccl_restrict ray)
Definition state_util.h:55
ccl_device_forceinline void integrator_state_write_shadow_ray(IntegratorShadowState state, const ccl_private Ray *ccl_restrict ray)
Definition state_util.h:75
ccl_device_forceinline void integrator_state_read_isect(ConstIntegratorState state, ccl_private Intersection *ccl_restrict isect)
Definition state_util.h:179
#define FLT_MAX
Definition stdcycles.h:14
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 Spectrum surface_shader_ao(KernelGlobals kg, const ccl_private ShaderData *sd, const float ao_factor, ccl_private float3 *N_)
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_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 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_apply_holdout(KernelGlobals kg, ccl_private ShaderData *sd)
ccl_device Spectrum surface_shader_alpha(KernelGlobals kg, const ccl_private ShaderData *sd)
ccl_device Spectrum surface_shader_emission(const ccl_private ShaderData *sd)
i
Definition text_draw.cc:230
ccl_device_inline float3 transform_direction(const ccl_private Transform *t, const float3 a)
Definition transform.h:87
ccl_device_inline float3 transform_point(const ccl_private Transform *t, const float3 a)
Definition transform.h:56
float3 Spectrum
packed_float3 PackedSpectrum
uint8_t flag
Definition wm_window.cc:139