ClangFormat: apply to source, most of intern
[blender.git] / intern / cycles / kernel / kernel_shadow.h
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 CCL_NAMESPACE_BEGIN
18
19 #ifdef __VOLUME__
20 typedef struct VolumeState {
21 #  ifdef __SPLIT_KERNEL__
22 #  else
23   PathState ps;
24 #  endif
25 } VolumeState;
26
27 /* Get PathState ready for use for volume stack evaluation. */
28 #  ifdef __SPLIT_KERNEL__
29 ccl_addr_space
30 #  endif
31     ccl_device_inline PathState *
32     shadow_blocked_volume_path_state(KernelGlobals *kg,
33                                      VolumeState *volume_state,
34                                      ccl_addr_space PathState *state,
35                                      ShaderData *sd,
36                                      Ray *ray)
37 {
38 #  ifdef __SPLIT_KERNEL__
39   ccl_addr_space PathState *ps =
40       &kernel_split_state.state_shadow[ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0)];
41 #  else
42   PathState *ps = &volume_state->ps;
43 #  endif
44   *ps = *state;
45   /* We are checking for shadow on the "other" side of the surface, so need
46    * to discard volume we are currently at.
47    */
48   if (dot(sd->Ng, ray->D) < 0.0f) {
49     kernel_volume_stack_enter_exit(kg, sd, ps->volume_stack);
50   }
51   return ps;
52 }
53 #endif /* __VOLUME__ */
54
55 /* Attenuate throughput accordingly to the given intersection event.
56  * Returns true if the throughput is zero and traversal can be aborted.
57  */
58 ccl_device_forceinline bool shadow_handle_transparent_isect(
59     KernelGlobals *kg,
60     ShaderData *shadow_sd,
61     ccl_addr_space PathState *state,
62 #ifdef __VOLUME__
63     ccl_addr_space struct PathState *volume_state,
64 #endif
65     Intersection *isect,
66     Ray *ray,
67     float3 *throughput)
68 {
69 #ifdef __VOLUME__
70   /* Attenuation between last surface and next surface. */
71   if (volume_state->volume_stack[0].shader != SHADER_NONE) {
72     Ray segment_ray = *ray;
73     segment_ray.t = isect->t;
74     kernel_volume_shadow(kg, shadow_sd, volume_state, &segment_ray, throughput);
75   }
76 #endif
77   /* Setup shader data at surface. */
78   shader_setup_from_ray(kg, shadow_sd, isect, ray);
79   /* Attenuation from transparent surface. */
80   if (!(shadow_sd->flag & SD_HAS_ONLY_VOLUME)) {
81     path_state_modify_bounce(state, true);
82     shader_eval_surface(kg, shadow_sd, state, PATH_RAY_SHADOW);
83     path_state_modify_bounce(state, false);
84     *throughput *= shader_bsdf_transparency(kg, shadow_sd);
85   }
86   /* Stop if all light is blocked. */
87   if (is_zero(*throughput)) {
88     return true;
89   }
90 #ifdef __VOLUME__
91   /* Exit/enter volume. */
92   kernel_volume_stack_enter_exit(kg, shadow_sd, volume_state->volume_stack);
93 #endif
94   return false;
95 }
96
97 /* Special version which only handles opaque shadows. */
98 ccl_device bool shadow_blocked_opaque(KernelGlobals *kg,
99                                       ShaderData *shadow_sd,
100                                       ccl_addr_space PathState *state,
101                                       const uint visibility,
102                                       Ray *ray,
103                                       Intersection *isect,
104                                       float3 *shadow)
105 {
106   const bool blocked = scene_intersect(
107       kg, *ray, visibility & PATH_RAY_SHADOW_OPAQUE, isect, NULL, 0.0f, 0.0f);
108 #ifdef __VOLUME__
109   if (!blocked && state->volume_stack[0].shader != SHADER_NONE) {
110     /* Apply attenuation from current volume shader. */
111     kernel_volume_shadow(kg, shadow_sd, state, ray, shadow);
112   }
113 #endif
114   return blocked;
115 }
116
117 #ifdef __TRANSPARENT_SHADOWS__
118 #  ifdef __SHADOW_RECORD_ALL__
119 /* Shadow function to compute how much light is blocked,
120  *
121  * We trace a single ray. If it hits any opaque surface, or more than a given
122  * number of transparent surfaces is hit, then we consider the geometry to be
123  * entirely blocked. If not, all transparent surfaces will be recorded and we
124  * will shade them one by one to determine how much light is blocked. This all
125  * happens in one scene intersection function.
126  *
127  * Recording all hits works well in some cases but may be slower in others. If
128  * we have many semi-transparent hairs, one intersection may be faster because
129  * you'd be reinteresecting the same hairs a lot with each step otherwise. If
130  * however there is mostly binary transparency then we may be recording many
131  * unnecessary intersections when one of the first surfaces blocks all light.
132  *
133  * From tests in real scenes it seems the performance loss is either minimal,
134  * or there is a performance increase anyway due to avoiding the need to send
135  * two rays with transparent shadows.
136  *
137  * On CPU it'll handle all transparent bounces (by allocating storage for
138  * intersections when they don't fit into the stack storage).
139  *
140  * On GPU it'll only handle SHADOW_STACK_MAX_HITS-1 intersections, so this
141  * is something to be kept an eye on.
142  */
143
144 #    define SHADOW_STACK_MAX_HITS 64
145
146 /* Actual logic with traversal loop implementation which is free from device
147  * specific tweaks.
148  *
149  * Note that hits array should be as big as max_hits+1.
150  */
151 ccl_device bool shadow_blocked_transparent_all_loop(KernelGlobals *kg,
152                                                     ShaderData *sd,
153                                                     ShaderData *shadow_sd,
154                                                     ccl_addr_space PathState *state,
155                                                     const uint visibility,
156                                                     Ray *ray,
157                                                     Intersection *hits,
158                                                     uint max_hits,
159                                                     float3 *shadow)
160 {
161   /* Intersect to find an opaque surface, or record all transparent
162    * surface hits.
163    */
164   uint num_hits;
165   const bool blocked = scene_intersect_shadow_all(kg, ray, hits, visibility, max_hits, &num_hits);
166 #    ifdef __VOLUME__
167   VolumeState volume_state;
168 #    endif
169   /* If no opaque surface found but we did find transparent hits,
170    * shade them.
171    */
172   if (!blocked && num_hits > 0) {
173     float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
174     float3 Pend = ray->P + ray->D * ray->t;
175     float last_t = 0.0f;
176     int bounce = state->transparent_bounce;
177     Intersection *isect = hits;
178 #    ifdef __VOLUME__
179 #      ifdef __SPLIT_KERNEL__
180     ccl_addr_space
181 #      endif
182         PathState *ps = shadow_blocked_volume_path_state(kg, &volume_state, state, sd, ray);
183 #    endif
184     sort_intersections(hits, num_hits);
185     for (int hit = 0; hit < num_hits; hit++, isect++) {
186       /* Adjust intersection distance for moving ray forward. */
187       float new_t = isect->t;
188       isect->t -= last_t;
189       /* Skip hit if we did not move forward, step by step raytracing
190        * would have skipped it as well then.
191        */
192       if (last_t == new_t) {
193         continue;
194       }
195       last_t = new_t;
196       /* Attenuate the throughput. */
197       if (shadow_handle_transparent_isect(kg,
198                                           shadow_sd,
199                                           state,
200 #    ifdef __VOLUME__
201                                           ps,
202 #    endif
203                                           isect,
204                                           ray,
205                                           &throughput)) {
206         return true;
207       }
208       /* Move ray forward. */
209       ray->P = shadow_sd->P;
210       if (ray->t != FLT_MAX) {
211         ray->D = normalize_len(Pend - ray->P, &ray->t);
212       }
213       bounce++;
214     }
215 #    ifdef __VOLUME__
216     /* Attenuation for last line segment towards light. */
217     if (ps->volume_stack[0].shader != SHADER_NONE) {
218       kernel_volume_shadow(kg, shadow_sd, ps, ray, &throughput);
219     }
220 #    endif
221     *shadow = throughput;
222     return is_zero(throughput);
223   }
224 #    ifdef __VOLUME__
225   if (!blocked && state->volume_stack[0].shader != SHADER_NONE) {
226     /* Apply attenuation from current volume shader. */
227 #      ifdef __SPLIT_KERNEL__
228     ccl_addr_space
229 #      endif
230         PathState *ps = shadow_blocked_volume_path_state(kg, &volume_state, state, sd, ray);
231     kernel_volume_shadow(kg, shadow_sd, ps, ray, shadow);
232   }
233 #    endif
234   return blocked;
235 }
236
237 /* Here we do all device specific trickery before invoking actual traversal
238  * loop to help readability of the actual logic.
239  */
240 ccl_device bool shadow_blocked_transparent_all(KernelGlobals *kg,
241                                                ShaderData *sd,
242                                                ShaderData *shadow_sd,
243                                                ccl_addr_space PathState *state,
244                                                const uint visibility,
245                                                Ray *ray,
246                                                uint max_hits,
247                                                float3 *shadow)
248 {
249 #    ifdef __SPLIT_KERNEL__
250   Intersection hits_[SHADOW_STACK_MAX_HITS];
251   Intersection *hits = &hits_[0];
252 #    elif defined(__KERNEL_CUDA__)
253   Intersection *hits = kg->hits_stack;
254 #    else
255   Intersection hits_stack[SHADOW_STACK_MAX_HITS];
256   Intersection *hits = hits_stack;
257 #    endif
258 #    ifndef __KERNEL_GPU__
259   /* Prefer to use stack but use dynamic allocation if too deep max hits
260    * we need max_hits + 1 storage space due to the logic in
261    * scene_intersect_shadow_all which will first store and then check if
262    * the limit is exceeded.
263    *
264    * Ignore this on GPU because of slow/unavailable malloc().
265    */
266   if (max_hits + 1 > SHADOW_STACK_MAX_HITS) {
267     if (kg->transparent_shadow_intersections == NULL) {
268       const int transparent_max_bounce = kernel_data.integrator.transparent_max_bounce;
269       kg->transparent_shadow_intersections = (Intersection *)malloc(sizeof(Intersection) *
270                                                                     (transparent_max_bounce + 1));
271     }
272     hits = kg->transparent_shadow_intersections;
273   }
274 #    endif /* __KERNEL_GPU__ */
275   /* Invoke actual traversal. */
276   return shadow_blocked_transparent_all_loop(
277       kg, sd, shadow_sd, state, visibility, ray, hits, max_hits, shadow);
278 }
279 #  endif /* __SHADOW_RECORD_ALL__ */
280
281 #  if defined(__KERNEL_GPU__) || !defined(__SHADOW_RECORD_ALL__)
282 /* Shadow function to compute how much light is blocked,
283  *
284  * Here we raytrace from one transparent surface to the next step by step.
285  * To minimize overhead in cases where we don't need transparent shadows, we
286  * first trace a regular shadow ray. We check if the hit primitive was
287  * potentially transparent, and only in that case start marching. this gives
288  * one extra ray cast for the cases were we do want transparency.
289  */
290
291 /* This function is only implementing device-independent traversal logic
292  * which requires some precalculation done.
293  */
294 ccl_device bool shadow_blocked_transparent_stepped_loop(KernelGlobals *kg,
295                                                         ShaderData *sd,
296                                                         ShaderData *shadow_sd,
297                                                         ccl_addr_space PathState *state,
298                                                         const uint visibility,
299                                                         Ray *ray,
300                                                         Intersection *isect,
301                                                         const bool blocked,
302                                                         const bool is_transparent_isect,
303                                                         float3 *shadow)
304 {
305 #    ifdef __VOLUME__
306   VolumeState volume_state;
307 #    endif
308   if (blocked && is_transparent_isect) {
309     float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
310     float3 Pend = ray->P + ray->D * ray->t;
311     int bounce = state->transparent_bounce;
312 #    ifdef __VOLUME__
313 #      ifdef __SPLIT_KERNEL__
314     ccl_addr_space
315 #      endif
316         PathState *ps = shadow_blocked_volume_path_state(kg, &volume_state, state, sd, ray);
317 #    endif
318     for (;;) {
319       if (bounce >= kernel_data.integrator.transparent_max_bounce) {
320         return true;
321       }
322       if (!scene_intersect(
323               kg, *ray, visibility & PATH_RAY_SHADOW_TRANSPARENT, isect, NULL, 0.0f, 0.0f)) {
324         break;
325       }
326       if (!shader_transparent_shadow(kg, isect)) {
327         return true;
328       }
329       /* Attenuate the throughput. */
330       if (shadow_handle_transparent_isect(kg,
331                                           shadow_sd,
332                                           state,
333 #    ifdef __VOLUME__
334                                           ps,
335 #    endif
336                                           isect,
337                                           ray,
338                                           &throughput)) {
339         return true;
340       }
341       /* Move ray forward. */
342       ray->P = ray_offset(shadow_sd->P, -shadow_sd->Ng);
343       if (ray->t != FLT_MAX) {
344         ray->D = normalize_len(Pend - ray->P, &ray->t);
345       }
346       bounce++;
347     }
348 #    ifdef __VOLUME__
349     /* Attenuation for last line segment towards light. */
350     if (ps->volume_stack[0].shader != SHADER_NONE) {
351       kernel_volume_shadow(kg, shadow_sd, ps, ray, &throughput);
352     }
353 #    endif
354     *shadow *= throughput;
355     return is_zero(throughput);
356   }
357 #    ifdef __VOLUME__
358   if (!blocked && state->volume_stack[0].shader != SHADER_NONE) {
359     /* Apply attenuation from current volume shader. */
360 #      ifdef __SPLIT_KERNEL__
361     ccl_addr_space
362 #      endif
363         PathState *ps = shadow_blocked_volume_path_state(kg, &volume_state, state, sd, ray);
364     kernel_volume_shadow(kg, shadow_sd, ps, ray, shadow);
365   }
366 #    endif
367   return blocked;
368 }
369
370 ccl_device bool shadow_blocked_transparent_stepped(KernelGlobals *kg,
371                                                    ShaderData *sd,
372                                                    ShaderData *shadow_sd,
373                                                    ccl_addr_space PathState *state,
374                                                    const uint visibility,
375                                                    Ray *ray,
376                                                    Intersection *isect,
377                                                    float3 *shadow)
378 {
379   bool blocked = scene_intersect(
380       kg, *ray, visibility & PATH_RAY_SHADOW_OPAQUE, isect, NULL, 0.0f, 0.0f);
381   bool is_transparent_isect = blocked ? shader_transparent_shadow(kg, isect) : false;
382   return shadow_blocked_transparent_stepped_loop(
383       kg, sd, shadow_sd, state, visibility, ray, isect, blocked, is_transparent_isect, shadow);
384 }
385
386 #  endif /* __KERNEL_GPU__ || !__SHADOW_RECORD_ALL__ */
387 #endif   /* __TRANSPARENT_SHADOWS__ */
388
389 ccl_device_inline bool shadow_blocked(KernelGlobals *kg,
390                                       ShaderData *sd,
391                                       ShaderData *shadow_sd,
392                                       ccl_addr_space PathState *state,
393                                       Ray *ray_input,
394                                       float3 *shadow)
395 {
396   Ray *ray = ray_input;
397   Intersection isect;
398   /* Some common early checks. */
399   *shadow = make_float3(1.0f, 1.0f, 1.0f);
400   if (ray->t == 0.0f) {
401     return false;
402   }
403 #ifdef __SHADOW_TRICKS__
404   const uint visibility = (state->flag & PATH_RAY_SHADOW_CATCHER) ? PATH_RAY_SHADOW_NON_CATCHER :
405                                                                     PATH_RAY_SHADOW;
406 #else
407   const uint visibility = PATH_RAY_SHADOW;
408 #endif
409   /* Do actual shadow shading. */
410   /* First of all, we check if integrator requires transparent shadows.
411    * if not, we use simplest and fastest ever way to calculate occlusion.
412    */
413 #ifdef __TRANSPARENT_SHADOWS__
414   if (!kernel_data.integrator.transparent_shadows)
415 #endif
416   {
417     return shadow_blocked_opaque(kg, shadow_sd, state, visibility, ray, &isect, shadow);
418   }
419 #ifdef __TRANSPARENT_SHADOWS__
420 #  ifdef __SHADOW_RECORD_ALL__
421   /* For the transparent shadows we try to use record-all logic on the
422    * devices which supports this.
423    */
424   const int transparent_max_bounce = kernel_data.integrator.transparent_max_bounce;
425   /* Check transparent bounces here, for volume scatter which can do
426    * lighting before surface path termination is checked.
427    */
428   if (state->transparent_bounce >= transparent_max_bounce) {
429     return true;
430   }
431   const uint max_hits = transparent_max_bounce - state->transparent_bounce - 1;
432 #    ifdef __KERNEL_GPU__
433   /* On GPU we do trickey with tracing opaque ray first, this avoids speed
434    * regressions in some files.
435    *
436    * TODO(sergey): Check why using record-all behavior causes slowdown in such
437    * cases. Could that be caused by a higher spill pressure?
438    */
439   const bool blocked = scene_intersect(
440       kg, *ray, visibility & PATH_RAY_SHADOW_OPAQUE, &isect, NULL, 0.0f, 0.0f);
441   const bool is_transparent_isect = blocked ? shader_transparent_shadow(kg, &isect) : false;
442   if (!blocked || !is_transparent_isect || max_hits + 1 >= SHADOW_STACK_MAX_HITS) {
443     return shadow_blocked_transparent_stepped_loop(
444         kg, sd, shadow_sd, state, visibility, ray, &isect, blocked, is_transparent_isect, shadow);
445   }
446 #    endif /* __KERNEL_GPU__ */
447   return shadow_blocked_transparent_all(
448       kg, sd, shadow_sd, state, visibility, ray, max_hits, shadow);
449 #  else  /* __SHADOW_RECORD_ALL__ */
450   /* Fallback to a slowest version which works on all devices. */
451   return shadow_blocked_transparent_stepped(
452       kg, sd, shadow_sd, state, visibility, ray, &isect, shadow);
453 #  endif /* __SHADOW_RECORD_ALL__ */
454 #endif   /* __TRANSPARENT_SHADOWS__ */
455 }
456
457 #undef SHADOW_STACK_MAX_HITS
458
459 CCL_NAMESPACE_END