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