1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifdef __OSL__
18 #  include "kernel/osl/osl_shader.h"
19 #endif
20 
21 // clang-format off
22 #include "kernel/kernel_random.h"
23 #include "kernel/kernel_projection.h"
24 #include "kernel/kernel_montecarlo.h"
25 #include "kernel/kernel_differential.h"
26 #include "kernel/kernel_camera.h"
27 
28 #include "kernel/geom/geom.h"
29 #include "kernel/bvh/bvh.h"
30 
31 #include "kernel/kernel_write_passes.h"
32 #include "kernel/kernel_accumulate.h"
33 #include "kernel/kernel_shader.h"
34 #include "kernel/kernel_light.h"
35 #include "kernel/kernel_adaptive_sampling.h"
36 #include "kernel/kernel_passes.h"
37 
38 #if defined(__VOLUME__) || defined(__SUBSURFACE__)
39 #  include "kernel/kernel_volume.h"
40 #endif
41 
42 #ifdef __SUBSURFACE__
43 #  include "kernel/kernel_subsurface.h"
44 #endif
45 
46 #include "kernel/kernel_path_state.h"
47 #include "kernel/kernel_shadow.h"
48 #include "kernel/kernel_emission.h"
49 #include "kernel/kernel_path_common.h"
50 #include "kernel/kernel_path_surface.h"
51 #include "kernel/kernel_path_volume.h"
52 #include "kernel/kernel_path_subsurface.h"
53 // clang-format on
54 
55 CCL_NAMESPACE_BEGIN
56 
kernel_path_scene_intersect(KernelGlobals * kg,ccl_addr_space PathState * state,Ray * ray,Intersection * isect,PathRadiance * L)57 ccl_device_forceinline bool kernel_path_scene_intersect(KernelGlobals *kg,
58                                                         ccl_addr_space PathState *state,
59                                                         Ray *ray,
60                                                         Intersection *isect,
61                                                         PathRadiance *L)
62 {
63   PROFILING_INIT(kg, PROFILING_SCENE_INTERSECT);
64 
65   uint visibility = path_state_ray_visibility(kg, state);
66 
67   if (path_state_ao_bounce(kg, state)) {
68     visibility = PATH_RAY_SHADOW;
69     ray->t = kernel_data.background.ao_distance;
70   }
71 
72   bool hit = scene_intersect(kg, ray, visibility, isect);
73 
74 #ifdef __KERNEL_DEBUG__
75   if (state->flag & PATH_RAY_CAMERA) {
76     L->debug_data.num_bvh_traversed_nodes += isect->num_traversed_nodes;
77     L->debug_data.num_bvh_traversed_instances += isect->num_traversed_instances;
78     L->debug_data.num_bvh_intersections += isect->num_intersections;
79   }
80   L->debug_data.num_ray_bounces++;
81 #endif /* __KERNEL_DEBUG__ */
82 
83   return hit;
84 }
85 
kernel_path_lamp_emission(KernelGlobals * kg,ccl_addr_space PathState * state,Ray * ray,float3 throughput,ccl_addr_space Intersection * isect,ShaderData * emission_sd,PathRadiance * L)86 ccl_device_forceinline void kernel_path_lamp_emission(KernelGlobals *kg,
87                                                       ccl_addr_space PathState *state,
88                                                       Ray *ray,
89                                                       float3 throughput,
90                                                       ccl_addr_space Intersection *isect,
91                                                       ShaderData *emission_sd,
92                                                       PathRadiance *L)
93 {
94   PROFILING_INIT(kg, PROFILING_INDIRECT_EMISSION);
95 
96 #ifdef __LAMP_MIS__
97   if (kernel_data.integrator.use_lamp_mis && !(state->flag & PATH_RAY_CAMERA)) {
98     /* ray starting from previous non-transparent bounce */
99     Ray light_ray ccl_optional_struct_init;
100 
101     light_ray.P = ray->P - state->ray_t * ray->D;
102     state->ray_t += isect->t;
103     light_ray.D = ray->D;
104     light_ray.t = state->ray_t;
105     light_ray.time = ray->time;
106     light_ray.dD = ray->dD;
107     light_ray.dP = ray->dP;
108 
109     /* intersect with lamp */
110     indirect_lamp_emission(kg, emission_sd, state, L, &light_ray, throughput);
111   }
112 #endif /* __LAMP_MIS__ */
113 }
114 
kernel_path_background(KernelGlobals * kg,ccl_addr_space PathState * state,ccl_addr_space Ray * ray,float3 throughput,ShaderData * sd,ccl_global float * buffer,PathRadiance * L)115 ccl_device_forceinline void kernel_path_background(KernelGlobals *kg,
116                                                    ccl_addr_space PathState *state,
117                                                    ccl_addr_space Ray *ray,
118                                                    float3 throughput,
119                                                    ShaderData *sd,
120                                                    ccl_global float *buffer,
121                                                    PathRadiance *L)
122 {
123   /* eval background shader if nothing hit */
124   if (kernel_data.background.transparent && (state->flag & PATH_RAY_TRANSPARENT_BACKGROUND)) {
125     L->transparent += average(throughput);
126 
127 #ifdef __PASSES__
128     if (!(kernel_data.film.light_pass_flag & PASSMASK(BACKGROUND)))
129 #endif /* __PASSES__ */
130       return;
131   }
132 
133   /* When using the ao bounces approximation, adjust background
134    * shader intensity with ao factor. */
135   if (path_state_ao_bounce(kg, state)) {
136     throughput *= kernel_data.background.ao_bounces_factor;
137   }
138 
139 #ifdef __BACKGROUND__
140   /* sample background shader */
141   float3 L_background = indirect_background(kg, sd, state, buffer, ray);
142   path_radiance_accum_background(kg, L, state, throughput, L_background);
143 #endif /* __BACKGROUND__ */
144 }
145 
146 #ifndef __SPLIT_KERNEL__
147 
148 #  ifdef __VOLUME__
kernel_path_volume(KernelGlobals * kg,ShaderData * sd,PathState * state,Ray * ray,float3 * throughput,ccl_addr_space Intersection * isect,bool hit,ShaderData * emission_sd,PathRadiance * L)149 ccl_device_forceinline VolumeIntegrateResult kernel_path_volume(KernelGlobals *kg,
150                                                                 ShaderData *sd,
151                                                                 PathState *state,
152                                                                 Ray *ray,
153                                                                 float3 *throughput,
154                                                                 ccl_addr_space Intersection *isect,
155                                                                 bool hit,
156                                                                 ShaderData *emission_sd,
157                                                                 PathRadiance *L)
158 {
159   PROFILING_INIT(kg, PROFILING_VOLUME);
160 
161   /* Sanitize volume stack. */
162   if (!hit) {
163     kernel_volume_clean_stack(kg, state->volume_stack);
164   }
165 
166   if (state->volume_stack[0].shader == SHADER_NONE) {
167     return VOLUME_PATH_ATTENUATED;
168   }
169 
170   /* volume attenuation, emission, scatter */
171   Ray volume_ray = *ray;
172   volume_ray.t = (hit) ? isect->t : FLT_MAX;
173 
174   float step_size = volume_stack_step_size(kg, state->volume_stack);
175 
176 #    ifdef __VOLUME_DECOUPLED__
177   int sampling_method = volume_stack_sampling_method(kg, state->volume_stack);
178   bool direct = (state->flag & PATH_RAY_CAMERA) != 0;
179   bool decoupled = kernel_volume_use_decoupled(kg, step_size, direct, sampling_method);
180 
181   if (decoupled) {
182     /* cache steps along volume for repeated sampling */
183     VolumeSegment volume_segment;
184 
185     shader_setup_from_volume(kg, sd, &volume_ray);
186     kernel_volume_decoupled_record(kg, state, &volume_ray, sd, &volume_segment, step_size);
187 
188     volume_segment.sampling_method = sampling_method;
189 
190     /* emission */
191     if (volume_segment.closure_flag & SD_EMISSION)
192       path_radiance_accum_emission(kg, L, state, *throughput, volume_segment.accum_emission);
193 
194     /* scattering */
195     VolumeIntegrateResult result = VOLUME_PATH_ATTENUATED;
196 
197     if (volume_segment.closure_flag & SD_SCATTER) {
198       int all = kernel_data.integrator.sample_all_lights_indirect;
199 
200       /* direct light sampling */
201       kernel_branched_path_volume_connect_light(
202           kg, sd, emission_sd, *throughput, state, L, all, &volume_ray, &volume_segment);
203 
204       /* indirect sample. if we use distance sampling and take just
205        * one sample for direct and indirect light, we could share
206        * this computation, but makes code a bit complex */
207       float rphase = path_state_rng_1D(kg, state, PRNG_PHASE_CHANNEL);
208       float rscatter = path_state_rng_1D(kg, state, PRNG_SCATTER_DISTANCE);
209 
210       result = kernel_volume_decoupled_scatter(
211           kg, state, &volume_ray, sd, throughput, rphase, rscatter, &volume_segment, NULL, true);
212     }
213 
214     /* free cached steps */
215     kernel_volume_decoupled_free(kg, &volume_segment);
216 
217     if (result == VOLUME_PATH_SCATTERED) {
218       if (kernel_path_volume_bounce(kg, sd, throughput, state, &L->state, ray))
219         return VOLUME_PATH_SCATTERED;
220       else
221         return VOLUME_PATH_MISSED;
222     }
223     else {
224       *throughput *= volume_segment.accum_transmittance;
225     }
226   }
227   else
228 #    endif /* __VOLUME_DECOUPLED__ */
229   {
230     /* integrate along volume segment with distance sampling */
231     VolumeIntegrateResult result = kernel_volume_integrate(
232         kg, state, sd, &volume_ray, L, throughput, step_size);
233 
234 #    ifdef __VOLUME_SCATTER__
235     if (result == VOLUME_PATH_SCATTERED) {
236       /* direct lighting */
237       kernel_path_volume_connect_light(kg, sd, emission_sd, *throughput, state, L);
238 
239       /* indirect light bounce */
240       if (kernel_path_volume_bounce(kg, sd, throughput, state, &L->state, ray))
241         return VOLUME_PATH_SCATTERED;
242       else
243         return VOLUME_PATH_MISSED;
244     }
245 #    endif /* __VOLUME_SCATTER__ */
246   }
247 
248   return VOLUME_PATH_ATTENUATED;
249 }
250 #  endif /* __VOLUME__ */
251 
252 #endif /* __SPLIT_KERNEL__ */
253 
kernel_path_shader_apply(KernelGlobals * kg,ShaderData * sd,ccl_addr_space PathState * state,ccl_addr_space Ray * ray,float3 throughput,ShaderData * emission_sd,PathRadiance * L,ccl_global float * buffer)254 ccl_device_forceinline bool kernel_path_shader_apply(KernelGlobals *kg,
255                                                      ShaderData *sd,
256                                                      ccl_addr_space PathState *state,
257                                                      ccl_addr_space Ray *ray,
258                                                      float3 throughput,
259                                                      ShaderData *emission_sd,
260                                                      PathRadiance *L,
261                                                      ccl_global float *buffer)
262 {
263   PROFILING_INIT(kg, PROFILING_SHADER_APPLY);
264 
265 #ifdef __SHADOW_TRICKS__
266   if ((sd->object_flag & SD_OBJECT_SHADOW_CATCHER)) {
267     if (state->flag & PATH_RAY_TRANSPARENT_BACKGROUND) {
268       state->flag |= (PATH_RAY_SHADOW_CATCHER | PATH_RAY_STORE_SHADOW_INFO);
269 
270       float3 bg = make_float3(0.0f, 0.0f, 0.0f);
271       if (!kernel_data.background.transparent) {
272         bg = indirect_background(kg, emission_sd, state, NULL, ray);
273       }
274       path_radiance_accum_shadowcatcher(L, throughput, bg);
275     }
276   }
277   else if (state->flag & PATH_RAY_SHADOW_CATCHER) {
278     /* Only update transparency after shadow catcher bounce. */
279     L->shadow_transparency *= average(shader_bsdf_transparency(kg, sd));
280   }
281 #endif /* __SHADOW_TRICKS__ */
282 
283   /* holdout */
284 #ifdef __HOLDOUT__
285   if (((sd->flag & SD_HOLDOUT) || (sd->object_flag & SD_OBJECT_HOLDOUT_MASK)) &&
286       (state->flag & PATH_RAY_TRANSPARENT_BACKGROUND)) {
287     const float3 holdout_weight = shader_holdout_apply(kg, sd);
288     if (kernel_data.background.transparent) {
289       L->transparent += average(holdout_weight * throughput);
290     }
291     if (isequal_float3(holdout_weight, make_float3(1.0f, 1.0f, 1.0f))) {
292       return false;
293     }
294   }
295 #endif /* __HOLDOUT__ */
296 
297   /* holdout mask objects do not write data passes */
298   kernel_write_data_passes(kg, buffer, L, sd, state, throughput);
299 
300   /* blurring of bsdf after bounces, for rays that have a small likelihood
301    * of following this particular path (diffuse, rough glossy) */
302   if (kernel_data.integrator.filter_glossy != FLT_MAX) {
303     float blur_pdf = kernel_data.integrator.filter_glossy * state->min_ray_pdf;
304 
305     if (blur_pdf < 1.0f) {
306       float blur_roughness = sqrtf(1.0f - blur_pdf) * 0.5f;
307       shader_bsdf_blur(kg, sd, blur_roughness);
308     }
309   }
310 
311 #ifdef __EMISSION__
312   /* emission */
313   if (sd->flag & SD_EMISSION) {
314     float3 emission = indirect_primitive_emission(
315         kg, sd, sd->ray_length, state->flag, state->ray_pdf);
316     path_radiance_accum_emission(kg, L, state, throughput, emission);
317   }
318 #endif /* __EMISSION__ */
319 
320   return true;
321 }
322 
323 #ifdef __KERNEL_OPTIX__
324 ccl_device_inline /* inline trace calls */
325 #else
326 ccl_device_noinline
327 #endif
328     void
kernel_path_ao(KernelGlobals * kg,ShaderData * sd,ShaderData * emission_sd,PathRadiance * L,ccl_addr_space PathState * state,float3 throughput,float3 ao_alpha)329     kernel_path_ao(KernelGlobals *kg,
330                    ShaderData *sd,
331                    ShaderData *emission_sd,
332                    PathRadiance *L,
333                    ccl_addr_space PathState *state,
334                    float3 throughput,
335                    float3 ao_alpha)
336 {
337   PROFILING_INIT(kg, PROFILING_AO);
338 
339   /* todo: solve correlation */
340   float bsdf_u, bsdf_v;
341 
342   path_state_rng_2D(kg, state, PRNG_BSDF_U, &bsdf_u, &bsdf_v);
343 
344   float ao_factor = kernel_data.background.ao_factor;
345   float3 ao_N;
346   float3 ao_bsdf = shader_bsdf_ao(kg, sd, ao_factor, &ao_N);
347   float3 ao_D;
348   float ao_pdf;
349 
350   sample_cos_hemisphere(ao_N, bsdf_u, bsdf_v, &ao_D, &ao_pdf);
351 
352   if (dot(sd->Ng, ao_D) > 0.0f && ao_pdf != 0.0f) {
353     Ray light_ray;
354     float3 ao_shadow;
355 
356     light_ray.P = ray_offset(sd->P, sd->Ng);
357     light_ray.D = ao_D;
358     light_ray.t = kernel_data.background.ao_distance;
359     light_ray.time = sd->time;
360     light_ray.dP = sd->dP;
361     light_ray.dD = differential3_zero();
362 
363     if (!shadow_blocked(kg, sd, emission_sd, state, &light_ray, &ao_shadow)) {
364       path_radiance_accum_ao(kg, L, state, throughput, ao_alpha, ao_bsdf, ao_shadow);
365     }
366     else {
367       path_radiance_accum_total_ao(L, state, throughput, ao_bsdf);
368     }
369   }
370 }
371 
372 #ifndef __SPLIT_KERNEL__
373 
374 #  if defined(__BRANCHED_PATH__) || defined(__BAKING__)
375 
kernel_path_indirect(KernelGlobals * kg,ShaderData * sd,ShaderData * emission_sd,Ray * ray,float3 throughput,PathState * state,PathRadiance * L)376 ccl_device void kernel_path_indirect(KernelGlobals *kg,
377                                      ShaderData *sd,
378                                      ShaderData *emission_sd,
379                                      Ray *ray,
380                                      float3 throughput,
381                                      PathState *state,
382                                      PathRadiance *L)
383 {
384 #    ifdef __SUBSURFACE__
385   SubsurfaceIndirectRays ss_indirect;
386   kernel_path_subsurface_init_indirect(&ss_indirect);
387 
388   for (;;) {
389 #    endif /* __SUBSURFACE__ */
390 
391     /* path iteration */
392     for (;;) {
393       /* Find intersection with objects in scene. */
394       Intersection isect;
395       bool hit = kernel_path_scene_intersect(kg, state, ray, &isect, L);
396 
397       /* Find intersection with lamps and compute emission for MIS. */
398       kernel_path_lamp_emission(kg, state, ray, throughput, &isect, sd, L);
399 
400 #    ifdef __VOLUME__
401       /* Volume integration. */
402       VolumeIntegrateResult result = kernel_path_volume(
403           kg, sd, state, ray, &throughput, &isect, hit, emission_sd, L);
404 
405       if (result == VOLUME_PATH_SCATTERED) {
406         continue;
407       }
408       else if (result == VOLUME_PATH_MISSED) {
409         break;
410       }
411 #    endif /* __VOLUME__*/
412 
413       /* Shade background. */
414       if (!hit) {
415         kernel_path_background(kg, state, ray, throughput, sd, NULL, L);
416         break;
417       }
418       else if (path_state_ao_bounce(kg, state)) {
419         break;
420       }
421 
422       /* Setup shader data. */
423       shader_setup_from_ray(kg, sd, &isect, ray);
424 
425       /* Skip most work for volume bounding surface. */
426 #    ifdef __VOLUME__
427       if (!(sd->flag & SD_HAS_ONLY_VOLUME)) {
428 #    endif
429 
430         /* Evaluate shader. */
431         shader_eval_surface(kg, sd, state, NULL, state->flag);
432         shader_prepare_closures(sd, state);
433 
434         /* Apply shadow catcher, holdout, emission. */
435         if (!kernel_path_shader_apply(kg, sd, state, ray, throughput, emission_sd, L, NULL)) {
436           break;
437         }
438 
439         /* path termination. this is a strange place to put the termination, it's
440          * mainly due to the mixed in MIS that we use. gives too many unneeded
441          * shader evaluations, only need emission if we are going to terminate */
442         float probability = path_state_continuation_probability(kg, state, throughput);
443 
444         if (probability == 0.0f) {
445           break;
446         }
447         else if (probability != 1.0f) {
448           float terminate = path_state_rng_1D(kg, state, PRNG_TERMINATE);
449 
450           if (terminate >= probability)
451             break;
452 
453           throughput /= probability;
454         }
455 
456 #    ifdef __DENOISING_FEATURES__
457         kernel_update_denoising_features(kg, sd, state, L);
458 #    endif
459 
460 #    ifdef __AO__
461         /* ambient occlusion */
462         if (kernel_data.integrator.use_ambient_occlusion) {
463           kernel_path_ao(kg, sd, emission_sd, L, state, throughput, make_float3(0.0f, 0.0f, 0.0f));
464         }
465 #    endif /* __AO__ */
466 
467 #    ifdef __SUBSURFACE__
468         /* bssrdf scatter to a different location on the same object, replacing
469          * the closures with a diffuse BSDF */
470         if (sd->flag & SD_BSSRDF) {
471           if (kernel_path_subsurface_scatter(
472                   kg, sd, emission_sd, L, state, ray, &throughput, &ss_indirect)) {
473             break;
474           }
475         }
476 #    endif /* __SUBSURFACE__ */
477 
478 #    if defined(__EMISSION__)
479         int all = (kernel_data.integrator.sample_all_lights_indirect) ||
480                   (state->flag & PATH_RAY_SHADOW_CATCHER);
481         kernel_branched_path_surface_connect_light(
482             kg, sd, emission_sd, state, throughput, 1.0f, L, all);
483 #    endif /* defined(__EMISSION__) */
484 
485 #    ifdef __VOLUME__
486       }
487 #    endif
488 
489       if (!kernel_path_surface_bounce(kg, sd, &throughput, state, &L->state, ray))
490         break;
491     }
492 
493 #    ifdef __SUBSURFACE__
494     /* Trace indirect subsurface rays by restarting the loop. this uses less
495      * stack memory than invoking kernel_path_indirect.
496      */
497     if (ss_indirect.num_rays) {
498       kernel_path_subsurface_setup_indirect(kg, &ss_indirect, state, ray, L, &throughput);
499     }
500     else {
501       break;
502     }
503   }
504 #    endif /* __SUBSURFACE__ */
505 }
506 
507 #  endif /* defined(__BRANCHED_PATH__) || defined(__BAKING__) */
508 
kernel_path_integrate(KernelGlobals * kg,PathState * state,float3 throughput,Ray * ray,PathRadiance * L,ccl_global float * buffer,ShaderData * emission_sd)509 ccl_device_forceinline void kernel_path_integrate(KernelGlobals *kg,
510                                                   PathState *state,
511                                                   float3 throughput,
512                                                   Ray *ray,
513                                                   PathRadiance *L,
514                                                   ccl_global float *buffer,
515                                                   ShaderData *emission_sd)
516 {
517   PROFILING_INIT(kg, PROFILING_PATH_INTEGRATE);
518 
519   /* Shader data memory used for both volumes and surfaces, saves stack space. */
520   ShaderData sd;
521 
522 #  ifdef __SUBSURFACE__
523   SubsurfaceIndirectRays ss_indirect;
524   kernel_path_subsurface_init_indirect(&ss_indirect);
525 
526   for (;;) {
527 #  endif /* __SUBSURFACE__ */
528 
529     /* path iteration */
530     for (;;) {
531       /* Find intersection with objects in scene. */
532       Intersection isect;
533       bool hit = kernel_path_scene_intersect(kg, state, ray, &isect, L);
534 
535       /* Find intersection with lamps and compute emission for MIS. */
536       kernel_path_lamp_emission(kg, state, ray, throughput, &isect, &sd, L);
537 
538 #  ifdef __VOLUME__
539       /* Volume integration. */
540       VolumeIntegrateResult result = kernel_path_volume(
541           kg, &sd, state, ray, &throughput, &isect, hit, emission_sd, L);
542 
543       if (result == VOLUME_PATH_SCATTERED) {
544         continue;
545       }
546       else if (result == VOLUME_PATH_MISSED) {
547         break;
548       }
549 #  endif /* __VOLUME__*/
550 
551       /* Shade background. */
552       if (!hit) {
553         kernel_path_background(kg, state, ray, throughput, &sd, buffer, L);
554         break;
555       }
556       else if (path_state_ao_bounce(kg, state)) {
557         break;
558       }
559 
560       /* Setup shader data. */
561       shader_setup_from_ray(kg, &sd, &isect, ray);
562 
563       /* Skip most work for volume bounding surface. */
564 #  ifdef __VOLUME__
565       if (!(sd.flag & SD_HAS_ONLY_VOLUME)) {
566 #  endif
567 
568         /* Evaluate shader. */
569         shader_eval_surface(kg, &sd, state, buffer, state->flag);
570         shader_prepare_closures(&sd, state);
571 
572         /* Apply shadow catcher, holdout, emission. */
573         if (!kernel_path_shader_apply(kg, &sd, state, ray, throughput, emission_sd, L, buffer)) {
574           break;
575         }
576 
577         /* path termination. this is a strange place to put the termination, it's
578          * mainly due to the mixed in MIS that we use. gives too many unneeded
579          * shader evaluations, only need emission if we are going to terminate */
580         float probability = path_state_continuation_probability(kg, state, throughput);
581 
582         if (probability == 0.0f) {
583           break;
584         }
585         else if (probability != 1.0f) {
586           float terminate = path_state_rng_1D(kg, state, PRNG_TERMINATE);
587           if (terminate >= probability)
588             break;
589 
590           throughput /= probability;
591         }
592 
593 #  ifdef __DENOISING_FEATURES__
594         kernel_update_denoising_features(kg, &sd, state, L);
595 #  endif
596 
597 #  ifdef __AO__
598         /* ambient occlusion */
599         if (kernel_data.integrator.use_ambient_occlusion) {
600           kernel_path_ao(kg, &sd, emission_sd, L, state, throughput, shader_bsdf_alpha(kg, &sd));
601         }
602 #  endif /* __AO__ */
603 
604 #  ifdef __SUBSURFACE__
605         /* bssrdf scatter to a different location on the same object, replacing
606          * the closures with a diffuse BSDF */
607         if (sd.flag & SD_BSSRDF) {
608           if (kernel_path_subsurface_scatter(
609                   kg, &sd, emission_sd, L, state, ray, &throughput, &ss_indirect)) {
610             break;
611           }
612         }
613 #  endif /* __SUBSURFACE__ */
614 
615 #  ifdef __EMISSION__
616         /* direct lighting */
617         kernel_path_surface_connect_light(kg, &sd, emission_sd, throughput, state, L);
618 #  endif /* __EMISSION__ */
619 
620 #  ifdef __VOLUME__
621       }
622 #  endif
623 
624       /* compute direct lighting and next bounce */
625       if (!kernel_path_surface_bounce(kg, &sd, &throughput, state, &L->state, ray))
626         break;
627     }
628 
629 #  ifdef __SUBSURFACE__
630     /* Trace indirect subsurface rays by restarting the loop. this uses less
631      * stack memory than invoking kernel_path_indirect.
632      */
633     if (ss_indirect.num_rays) {
634       kernel_path_subsurface_setup_indirect(kg, &ss_indirect, state, ray, L, &throughput);
635     }
636     else {
637       break;
638     }
639   }
640 #  endif /* __SUBSURFACE__ */
641 }
642 
kernel_path_trace(KernelGlobals * kg,ccl_global float * buffer,int sample,int x,int y,int offset,int stride)643 ccl_device void kernel_path_trace(
644     KernelGlobals *kg, ccl_global float *buffer, int sample, int x, int y, int offset, int stride)
645 {
646   PROFILING_INIT(kg, PROFILING_RAY_SETUP);
647 
648   /* buffer offset */
649   int index = offset + x + y * stride;
650   int pass_stride = kernel_data.film.pass_stride;
651 
652   buffer += index * pass_stride;
653 
654   if (kernel_data.film.pass_adaptive_aux_buffer) {
655     ccl_global float4 *aux = (ccl_global float4 *)(buffer +
656                                                    kernel_data.film.pass_adaptive_aux_buffer);
657     if ((*aux).w > 0.0f) {
658       return;
659     }
660   }
661 
662   /* Initialize random numbers and sample ray. */
663   uint rng_hash;
664   Ray ray;
665 
666   kernel_path_trace_setup(kg, sample, x, y, &rng_hash, &ray);
667 
668   if (ray.t == 0.0f) {
669     return;
670   }
671 
672   /* Initialize state. */
673   float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
674 
675   PathRadiance L;
676   path_radiance_init(kg, &L);
677 
678   ShaderDataTinyStorage emission_sd_storage;
679   ShaderData *emission_sd = AS_SHADER_DATA(&emission_sd_storage);
680 
681   PathState state;
682   path_state_init(kg, emission_sd, &state, rng_hash, sample, &ray);
683 
684 #  ifdef __KERNEL_OPTIX__
685   /* Force struct into local memory to avoid costly spilling on trace calls. */
686   if (pass_stride < 0) /* This is never executed and just prevents the compiler from doing SROA. */
687     for (int i = 0; i < sizeof(L); ++i)
688       reinterpret_cast<unsigned char *>(&L)[-pass_stride + i] = 0;
689 #  endif
690 
691   /* Integrate. */
692   kernel_path_integrate(kg, &state, throughput, &ray, &L, buffer, emission_sd);
693 
694   kernel_write_result(kg, buffer, sample, &L);
695 }
696 
697 #endif /* __SPLIT_KERNEL__ */
698 
699 CCL_NAMESPACE_END
700