Blender V5.0
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(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);
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, volume_bounds_bounce) = INTEGRATOR_STATE(
243 state, path, volume_bounds_bounce);
244 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, glossy_bounce) = INTEGRATOR_STATE(
245 state, path, glossy_bounce);
246 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, throughput) = throughput;
247
248 if ((kernel_data.kernel_features & KERNEL_FEATURE_NODE_PORTAL)) {
249 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, portal_bounce) = INTEGRATOR_STATE(
250 state, path, portal_bounce);
251 }
252
253#ifdef __MNEE__
254 if (mnee_vertex_count > 0) {
255 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, transmission_bounce) =
256 INTEGRATOR_STATE(state, path, transmission_bounce) + mnee_vertex_count - 1;
257 INTEGRATOR_STATE_WRITE(shadow_state,
258 shadow_path,
259 diffuse_bounce) = INTEGRATOR_STATE(state, path, diffuse_bounce) + 1;
260 INTEGRATOR_STATE_WRITE(shadow_state,
261 shadow_path,
262 bounce) = INTEGRATOR_STATE(state, path, bounce) + mnee_vertex_count;
263 }
264 else
265#endif
266 {
267 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, transmission_bounce) = INTEGRATOR_STATE(
268 state, path, transmission_bounce);
269 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, diffuse_bounce) = INTEGRATOR_STATE(
270 state, path, diffuse_bounce);
271 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, bounce) = INTEGRATOR_STATE(
272 state, path, bounce);
273 }
274
275 /* Write Light-group, +1 as light-group is int but we need to encode into a uint8_t. */
276 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, lightgroup) = light_group + 1;
277
278#if defined(__PATH_GUIDING__)
279 if ((kernel_data.kernel_features & KERNEL_FEATURE_PATH_GUIDING)) {
280 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, unlit_throughput) = unlit_throughput;
281 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, path_segment) = INTEGRATOR_STATE(
282 state, guiding, path_segment);
283 INTEGRATOR_STATE(shadow_state, shadow_path, guiding_mis_weight) = 0.0f;
284 }
285#endif
286
287 return shadow_state;
288}
289
290/* Path tracing: sample point on light and evaluate light shader, then
291 * queue shadow ray to be traced. */
292template<uint node_feature_mask>
293#if defined(__KERNEL_GPU__)
295#else
296/* MSVC has very long compilation time (x20) if we force inline this function */
298#endif
299 void
302 ccl_private ShaderData *sd,
303 const ccl_private RNGState *rng_state)
304{
305 /* Test if there is a light or BSDF that needs direct light. */
306 if (!(kernel_data.integrator.use_direct_light && (sd->flag & SD_BSDF_HAS_EVAL))) {
307 return;
308 }
309
310 /* Sample position on a light. */
312 {
313 const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
314 const uint bounce = INTEGRATOR_STATE(state, path, bounce);
315 const float3 rand_light = path_state_rng_3D(kg, rng_state, PRNG_LIGHT);
316
318 rand_light,
319 sd->time,
320 sd->P,
321 sd->N,
323 sd->flag,
324 bounce,
325 path_flag,
326 &ls))
327 {
328 return;
329 }
330 }
331
332 kernel_assert(ls.pdf != 0.0f);
333
334 const bool is_transmission = dot(ls.D, sd->N) < 0.0f;
335
336 if (ls.prim != PRIM_NONE && ls.prim == sd->prim && ls.object == sd->object) {
337 /* Skip self intersection if light direction lies in the same hemisphere as the geometric
338 * normal. */
339 if (dot(ls.D, is_transmission ? -sd->Ng : sd->Ng) > 0.0f) {
340 return;
341 }
342 }
343
344 /* Evaluate light shader.
345 *
346 * TODO: can we reuse sd memory? In theory we can move this after
347 * integrate_surface_bounce, evaluate the BSDF, and only then evaluate
348 * the light shader. This could also move to its own kernel, for
349 * non-constant light sources. */
350 ShaderDataCausticsStorage emission_sd_storage;
351 ccl_private ShaderData *emission_sd = AS_SHADER_DATA(&emission_sd_storage);
352
355
356 int mnee_vertex_count = 0; // NOLINT
357#ifdef __MNEE__
359 {
360 if (ls.type != LIGHT_TRIANGLE) {
361 /* Is this a caustic light? */
362 const bool use_caustics = kernel_data_fetch(lights, ls.prim).use_caustics;
363 if (use_caustics) {
364 /* Are we on a caustic caster? */
365 if (is_transmission && (sd->object_flag & SD_OBJECT_CAUSTICS_CASTER)) {
366 return;
367 }
368
369 /* Are we on a caustic receiver? */
370 if (!is_transmission && (sd->object_flag & SD_OBJECT_CAUSTICS_RECEIVER)) {
371 mnee_vertex_count = kernel_path_mnee_sample(
372 kg, state, sd, emission_sd, rng_state, &ls, &bsdf_eval);
373 }
374 }
375 }
376 }
377 if (mnee_vertex_count > 0) {
378 /* Create shadow ray after successful manifold walk:
379 * emission_sd contains the last interface intersection and
380 * the light sample ls has been updated */
381 light_sample_to_surface_shadow_ray(kg, emission_sd, &ls, &ray);
382 }
383 else
384#endif /* __MNEE__ */
385 {
386 const Spectrum light_eval = light_sample_shader_eval(kg, state, emission_sd, &ls, sd->time);
387 if (is_zero(light_eval)) {
388 return;
389 }
390
391 /* Evaluate BSDF. */
392 const float bsdf_pdf = surface_shader_bsdf_eval(kg, state, sd, ls.D, &bsdf_eval, ls.shader);
393 const float mis_weight = light_sample_mis_weight_nee(kg, ls.pdf, bsdf_pdf);
394 bsdf_eval_mul(&bsdf_eval, light_eval / ls.pdf * mis_weight);
395
396 /* Path termination. */
397 const float terminate = path_state_rng_light_termination(kg, rng_state);
398 if (light_sample_terminate(kg, &bsdf_eval, terminate)) {
399 return;
400 }
401
402 /* Create shadow ray. */
403 light_sample_to_surface_shadow_ray(kg, sd, &ls, &ray);
404 }
405
406 if (ray.self.object != OBJECT_NONE) {
407 ray.P = integrate_surface_ray_offset(kg, sd, ray.P, ray.D);
408 }
409
410 /* Branch off shadow kernel. */
412 kg, state, &ray, bsdf_eval_sum(&bsdf_eval), ls.group, mnee_vertex_count);
413
414 if (is_transmission) {
415#ifdef __VOLUME__
416 volume_stack_enter_exit<true>(kg, shadow_state, sd);
417#endif
418 }
419
420 uint32_t shadow_flag = INTEGRATOR_STATE(state, path, flag);
421
422 if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) {
423 PackedSpectrum pass_diffuse_weight;
424 PackedSpectrum pass_glossy_weight;
425
426 if (shadow_flag & PATH_RAY_ANY_PASS) {
427 /* Indirect bounce, use weights from earlier surface or volume bounce. */
428 pass_diffuse_weight = INTEGRATOR_STATE(state, path, pass_diffuse_weight);
429 pass_glossy_weight = INTEGRATOR_STATE(state, path, pass_glossy_weight);
430 }
431 else {
432 /* Direct light, use BSDFs at this bounce. */
433 shadow_flag |= PATH_RAY_SURFACE_PASS;
436 }
437
438 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, pass_diffuse_weight) = pass_diffuse_weight;
439 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, pass_glossy_weight) = pass_glossy_weight;
440 }
441
442 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, flag) = shadow_flag;
443}
444
445/* Path tracing: bounce off or through surface with new direction. */
447 KernelGlobals kg,
449 ccl_private ShaderData *sd,
450 const ccl_private RNGState *rng_state)
451{
452 /* Sample BSDF or BSSRDF. */
453 if (!(sd->flag & (SD_BSDF | SD_BSSRDF))) {
454 return LABEL_NONE;
455 }
456
457 float3 rand_bsdf = path_state_rng_3D(kg, rng_state, PRNG_SURFACE_BSDF);
458 const ccl_private ShaderClosure *sc = surface_shader_bsdf_bssrdf_pick(sd, &rand_bsdf);
459
460#ifdef __SUBSURFACE__
461 /* BSSRDF closure, we schedule subsurface intersection kernel. */
462 if (CLOSURE_IS_BSSRDF(sc->type)) {
463 return subsurface_bounce(kg, state, sd, sc);
464 }
465#endif
466 if (CLOSURE_IS_RAY_PORTAL(sc->type)) {
467 return integrate_surface_ray_portal(kg, state, sd, sc);
468 }
469
470 /* BSDF closure, sample direction. */
471 float bsdf_pdf = 0.0f;
472 float unguided_bsdf_pdf = 0.0f;
475 int label;
476
477 float2 bsdf_sampled_roughness = make_float2(1.0f, 1.0f);
478 float bsdf_eta = 1.0f;
479 float mis_pdf = 1.0f;
480
481#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
482 if (kernel_data.integrator.use_surface_guiding &&
483 (kernel_data.kernel_features & KERNEL_FEATURE_PATH_GUIDING))
484 {
485 label = surface_shader_bsdf_guided_sample_closure(kg,
486 state,
487 sd,
488 sc,
489 rand_bsdf,
490 &bsdf_eval,
491 &bsdf_wo,
492 &bsdf_pdf,
493 &mis_pdf,
494 &unguided_bsdf_pdf,
495 &bsdf_sampled_roughness,
496 &bsdf_eta,
497 rng_state);
498
499 if (bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval)) {
500 return LABEL_NONE;
501 }
502
503 INTEGRATOR_STATE_WRITE(state, path, unguided_throughput) *= bsdf_pdf / unguided_bsdf_pdf;
504 }
505 else
506#endif
507 {
509 sd,
510 sc,
511 rand_bsdf,
512 &bsdf_eval,
513 &bsdf_wo,
514 &bsdf_pdf,
515 &bsdf_sampled_roughness,
516 &bsdf_eta);
517
518 if (bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval)) {
519 return LABEL_NONE;
520 }
521 mis_pdf = bsdf_pdf;
522 unguided_bsdf_pdf = bsdf_pdf;
523 }
524
525 if (label & LABEL_TRANSPARENT) {
526 /* Only need to modify start distance for transparent. */
527 INTEGRATOR_STATE_WRITE(state, ray, tmin) = intersection_t_offset(sd->ray_length);
528 }
529 else {
530 /* Setup ray with changed origin and direction. */
531 const float3 D = normalize(bsdf_wo);
534 INTEGRATOR_STATE_WRITE(state, ray, tmin) = 0.0f;
536#ifdef __RAY_DIFFERENTIALS__
538#endif
539 }
540
541 /* Update throughput. */
542 const Spectrum bsdf_weight = bsdf_eval_sum(&bsdf_eval) / bsdf_pdf;
543 INTEGRATOR_STATE_WRITE(state, path, throughput) *= bsdf_weight;
544
545 if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) {
546 if (INTEGRATOR_STATE(state, path, bounce) == 0) {
547 INTEGRATOR_STATE_WRITE(state, path, pass_diffuse_weight) = bsdf_eval_pass_diffuse_weight(
548 &bsdf_eval);
549 INTEGRATOR_STATE_WRITE(state, path, pass_glossy_weight) = bsdf_eval_pass_glossy_weight(
550 &bsdf_eval);
551 }
552 }
553
554 /* Update path state */
555 if (!(label & LABEL_TRANSPARENT)) {
556 const float min_ray_pdf = INTEGRATOR_STATE(state, path, min_ray_pdf);
557 INTEGRATOR_STATE_WRITE(state, path, mis_ray_pdf) = mis_pdf;
558 INTEGRATOR_STATE_WRITE(state, path, mis_origin_n) = sd->N;
559 INTEGRATOR_STATE_WRITE(state, path, min_ray_pdf) = fminf(unguided_bsdf_pdf, min_ray_pdf);
560
561#ifdef __LIGHT_LINKING__
562 if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_LINKING) {
563 INTEGRATOR_STATE_WRITE(state, path, mis_ray_object) = sd->object;
564 }
565#endif
566 }
567
568 path_state_next(kg, state, label, sd->flag);
569
571 state,
572 bsdf_weight,
573 bsdf_pdf,
574 sd->N,
575 normalize(bsdf_wo),
576 bsdf_sampled_roughness,
577 bsdf_eta);
578
579 return label;
580}
581
582#ifdef __VOLUME__
583ccl_device_forceinline int integrate_surface_volume_only_bounce(IntegratorState state,
584 ccl_private ShaderData *sd)
585{
586 if (!path_state_volume_next(state)) {
587 return LABEL_NONE;
588 }
589
590 /* Only modify start distance. */
591 INTEGRATOR_STATE_WRITE(state, ray, tmin) = intersection_t_offset(sd->ray_length);
592
594}
595#endif
596
598 const uint32_t path_flag)
599{
600 const float continuation_probability = (path_flag & PATH_RAY_TERMINATE_ON_NEXT_SURFACE) ?
601 0.0f :
603 state, path, continuation_probability);
604 if (continuation_probability == 0.0f) {
605 return true;
606 }
607 if (continuation_probability != 1.0f) {
608 INTEGRATOR_STATE_WRITE(state, path, throughput) /= continuation_probability;
609 }
610
611 return false;
612}
613
614#if defined(__AO__)
615ccl_device_forceinline void integrate_surface_ao(KernelGlobals kg,
617 const ccl_private ShaderData *ccl_restrict sd,
619 rng_state)
620{
621 const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
622
623 if (!(kernel_data.kernel_features & KERNEL_FEATURE_AO_ADDITIVE) &&
624 !(path_flag & PATH_RAY_CAMERA))
625 {
626 return;
627 }
628
629 /* Skip AO for paths that were split off for shadow catchers to avoid double-counting. */
630 if (path_flag & PATH_RAY_SHADOW_CATCHER_PASS) {
631 return;
632 }
633
634 const float2 rand_bsdf = path_state_rng_2D(kg, rng_state, PRNG_SURFACE_BSDF);
635
636 float3 ao_N;
637 const Spectrum ao_weight = surface_shader_ao(
638 sd, kernel_data.integrator.ao_additive_factor, &ao_N);
639
640 float3 ao_D;
641 float ao_pdf;
642 sample_cos_hemisphere(ao_N, rand_bsdf, &ao_D, &ao_pdf);
643
644 bool skip_self = true;
645
647 ray.P = shadow_ray_offset(kg, sd, ao_D, &skip_self);
648 ray.D = ao_D;
649 if (skip_self) {
650 ray.P = integrate_surface_ray_offset(kg, sd, ray.P, ray.D);
651 }
652 ray.tmin = 0.0f;
653 ray.tmax = kernel_data.integrator.ao_bounces_distance;
654 ray.time = sd->time;
655 ray.self.object = (skip_self) ? sd->object : OBJECT_NONE;
656 ray.self.prim = (skip_self) ? sd->prim : PRIM_NONE;
657 ray.self.light_object = OBJECT_NONE;
658 ray.self.light_prim = PRIM_NONE;
659 ray.dP = differential_zero_compact();
660 ray.dD = differential_zero_compact();
661
662 /* Branch off shadow kernel. */
665
666# ifdef __VOLUME__
667 /* Copy volume stack and enter/exit volume. */
668 integrator_state_copy_volume_stack_to_shadow(kg, shadow_state, state);
669# endif
670
671 /* Write shadow ray and associated state to global memory. */
672 integrator_state_write_shadow_ray(shadow_state, &ray);
673 integrator_state_write_shadow_ray_self(shadow_state, &ray);
674
675 /* Copy state from main path to shadow path. */
676 const uint16_t bounce = INTEGRATOR_STATE(state, path, bounce);
677 const uint16_t transparent_bounce = INTEGRATOR_STATE(state, path, transparent_bounce);
678 const uint32_t shadow_flag = INTEGRATOR_STATE(state, path, flag) | PATH_RAY_SHADOW_FOR_AO;
679 const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput) * surface_shader_alpha(sd);
680
681 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, render_pixel_index) = INTEGRATOR_STATE(
682 state, path, render_pixel_index);
683 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, rng_offset) = INTEGRATOR_STATE(
684 state, path, rng_offset);
685 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, rng_pixel) = INTEGRATOR_STATE(
686 state, path, rng_pixel);
687 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, sample) = INTEGRATOR_STATE(
688 state, path, sample);
689 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, flag) = shadow_flag;
690 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, bounce) = bounce;
691 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, transparent_bounce) = transparent_bounce;
692 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, volume_bounds_bounce) = INTEGRATOR_STATE(
693 state, path, volume_bounds_bounce);
694 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, throughput) = throughput;
695
696 if (kernel_data.kernel_features & KERNEL_FEATURE_AO_ADDITIVE) {
697 INTEGRATOR_STATE_WRITE(shadow_state, shadow_path, unshadowed_throughput) = ao_weight;
698 }
699}
700#endif /* defined(__AO__) */
701
702template<uint node_feature_mask>
706
707{
709
710 /* Setup shader data. */
711 ShaderData sd;
713 PROFILING_SHADER(sd.object, sd.shader);
714
715 int continue_path_label = 0;
716
717 const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
718
719 /* Skip most work for volume bounding surface. */
720#ifdef __VOLUME__
721 if (!(sd.flag & SD_HAS_ONLY_VOLUME)) {
722#endif
724
725#ifdef __SUBSURFACE__
726 /* Can skip shader evaluation for BSSRDF exit point without bump mapping. */
727 if (!(path_flag & PATH_RAY_SUBSURFACE) || ((sd.flag & SD_HAS_BSSRDF_BUMP)))
728#endif
729 {
730 /* Evaluate shader. */
733
734 /* Initialize additional RNG for BSDFs. */
735 if (sd.flag & SD_BSDF_NEEDS_LCG) {
736 sd.lcg_state = lcg_state_init(INTEGRATOR_STATE(state, path, rng_pixel),
737 INTEGRATOR_STATE(state, path, rng_offset),
739 0xb4bc3953);
740 }
741 }
742
743#ifdef __SUBSURFACE__
744 if (path_flag & PATH_RAY_SUBSURFACE) {
745 /* When coming from inside subsurface scattering, setup a diffuse
746 * closure to perform lighting at the exit point. */
747 subsurface_shader_data_setup(kg, &sd);
749 }
750 else
751#endif
752 {
753 /* Filter closures. */
754 surface_shader_prepare_closures(kg, state, &sd, path_flag);
755
756 /* Evaluate holdout. */
758 return LABEL_NONE;
759 }
760
761 /* Write emission. */
762 if (sd.flag & SD_EMISSION) {
764 }
765
766 /* Perform path termination. Most paths have already been terminated in
767 * the intersect_closest kernel, this is just for emission and for dividing
768 * throughput by the probability at the right moment.
769 *
770 * Also ensure we don't do it twice for SSS at both the entry and exit point. */
771 if (integrate_surface_terminate(state, path_flag)) {
772 return LABEL_NONE;
773 }
774
775 /* Write render passes. */
776#ifdef __PASSES__
779#endif
780
781#ifdef __DENOISING_FEATURES__
782 film_write_denoising_features_surface(kg, state, &sd, render_buffer);
783#endif
784 }
785
786 /* Load random number state. */
787 RNGState rng_state;
788 path_state_rng_load(state, &rng_state);
789
790#if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4
791 if (kernel_data.kernel_features & KERNEL_FEATURE_PATH_GUIDING) {
792 surface_shader_prepare_guiding(kg, state, &sd, &rng_state);
794 }
795#endif
796 /* Direct light. */
799
800#if defined(__AO__)
801 /* Ambient occlusion pass. */
802 if (kernel_data.kernel_features & KERNEL_FEATURE_AO) {
804 integrate_surface_ao(kg, state, &sd, &rng_state);
805 }
806#endif
807
809 continue_path_label = integrate_surface_bsdf_bssrdf_bounce(kg, state, &sd, &rng_state);
810#ifdef __VOLUME__
811 }
812 else {
813 if (integrate_surface_terminate(state, path_flag)) {
814 return LABEL_NONE;
815 }
816
818 continue_path_label = integrate_surface_volume_only_bounce(state, &sd);
819 }
820
821 if (continue_path_label & LABEL_TRANSMIT) {
822 /* Enter/Exit volume. */
823 volume_stack_enter_exit<false>(kg, state, &sd);
824 }
825#endif
826
827 return continue_path_label;
828}
829
830template<DeviceKernel current_kernel>
841
847{
848 const int continue_path_label = integrate_surface<node_feature_mask>(kg, state, render_buffer);
849 if (continue_path_label == LABEL_NONE) {
850 integrator_path_terminate(kg, state, render_buffer, current_kernel);
851 return;
852 }
853
854#ifdef __SHADOW_LINKING__
855 /* No need to cast shadow linking rays at a transparent bounce: the lights will be accumulated
856 * via the main path in this case. BSSRDF bounces continue with intersect_subsurface. */
857 if ((continue_path_label & (LABEL_TRANSPARENT | LABEL_SUBSURFACE_SCATTER)) == 0) {
858 if (shadow_linking_schedule_intersection_kernel<current_kernel>(kg, state)) {
859 return;
860 }
861 }
862#endif
863
865}
866
874
884
#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:512
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_FEATURE_NODE_PORTAL
#define kernel_data
#define KERNEL_FEATURE_AO
#define ccl_restrict
#define ccl_device_forceinline
#define KERNEL_FEATURE_PATH_GUIDING
#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 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
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 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
@ LABEL_SUBSURFACE_SCATTER
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:45
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 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
#define PROFILING_INIT_FOR_SHADER(kg, event)
#define PROFILING_EVENT(event)
#define PROFILING_SHADER(object, shader)
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])
float average(point a)
Definition node_math.h:144
ccl_device_inline float path_state_rng_light_termination(KernelGlobals kg, const ccl_private RNGState *state)
Definition path_state.h:416
ccl_device_inline void path_state_rng_load(ConstIntegratorState state, ccl_private RNGState *rng_state)
Definition path_state.h:329
ccl_device_inline void path_state_next(KernelGlobals kg, IntegratorState state, const int label, const int shader_flag)
Definition path_state.h:110
ccl_device_inline float2 path_state_rng_2D(KernelGlobals kg, const ccl_private RNGState *rng_state, const int dimension)
Definition path_state.h:361
ccl_device_inline float3 path_state_rng_3D(KernelGlobals kg, const ccl_private RNGState *rng_state, const int dimension)
Definition path_state.h:369
@ 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
#define ccl_device
#define make_float2
#define fminf
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_forceinline void integrator_shade_surface_next_kernel(IntegratorState state)
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_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_next(IntegratorState state, const DeviceKernel current_kernel, const DeviceKernel next_kernel)
Definition state_flow.h:195
ccl_device_forceinline void integrator_path_terminate(KernelGlobals kg, IntegratorState state, ccl_global float *ccl_restrict render_buffer, const DeviceKernel current_kernel)
Definition state_flow.h:203
ccl_device_forceinline IntegratorShadowState integrator_shadow_path_init(KernelGlobals kg, IntegratorState state, const DeviceKernel next_kernel, const bool is_ao)
Definition state_flow.h:225
ccl_device_forceinline void integrator_state_write_shadow_ray_self(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 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 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 Spectrum surface_shader_ao(const ccl_private ShaderData *sd, const float ao_factor, ccl_private float3 *N_)
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_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:127
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:145