Blender  V3.3
kernel/bvh/bvh.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright 2011-2022 Blender Foundation */
3 
4 #pragma once
5 
6 #include "kernel/bvh/types.h"
7 #include "kernel/bvh/util.h"
8 
10 
11 /* Device specific acceleration structures for ray tracing. */
12 
13 #if defined(__EMBREE__)
14 # include "kernel/device/cpu/bvh.h"
15 # define __BVH2__
16 #elif defined(__METALRT__)
17 # include "kernel/device/metal/bvh.h"
18 #elif defined(__KERNEL_OPTIX__)
19 # include "kernel/device/optix/bvh.h"
20 #else
21 # define __BVH2__
22 #endif
23 
25 
26 #ifdef __BVH2__
27 
28 /* BVH2
29  *
30  * Bounding volume hierarchy for ray tracing, when no native acceleration
31  * structure is available for the device.
32 
33  * We compile different variations of the same BVH traversal function for
34  * faster rendering when some types of primitives are not needed, using #includes
35  * to work around the lack of C++ templates in OpenCL.
36  *
37  * Originally based on "Understanding the Efficiency of Ray Traversal on GPUs",
38  * the code has been extended and modified to support more primitives and work
39  * with CPU and various GPU kernel languages. */
40 
41 # include "kernel/bvh/nodes.h"
42 
43 /* Regular BVH traversal */
44 
45 # define BVH_FUNCTION_NAME bvh_intersect
46 # define BVH_FUNCTION_FEATURES BVH_POINTCLOUD
47 # include "kernel/bvh/traversal.h"
48 
49 # if defined(__HAIR__)
50 # define BVH_FUNCTION_NAME bvh_intersect_hair
51 # define BVH_FUNCTION_FEATURES BVH_HAIR | BVH_POINTCLOUD
52 # include "kernel/bvh/traversal.h"
53 # endif
54 
55 # if defined(__OBJECT_MOTION__)
56 # define BVH_FUNCTION_NAME bvh_intersect_motion
57 # define BVH_FUNCTION_FEATURES BVH_MOTION | BVH_POINTCLOUD
58 # include "kernel/bvh/traversal.h"
59 # endif
60 
61 # if defined(__HAIR__) && defined(__OBJECT_MOTION__)
62 # define BVH_FUNCTION_NAME bvh_intersect_hair_motion
63 # define BVH_FUNCTION_FEATURES BVH_HAIR | BVH_MOTION | BVH_POINTCLOUD
64 # include "kernel/bvh/traversal.h"
65 # endif
66 
68  ccl_private const Ray *ray,
69  const uint visibility,
71 {
72  if (!intersection_ray_valid(ray)) {
73  return false;
74  }
75 
76 # ifdef __EMBREE__
77  if (kernel_data.device_bvh) {
78  return kernel_embree_intersect(kg, ray, visibility, isect);
79  }
80 # endif
81 
82 # ifdef __OBJECT_MOTION__
83  if (kernel_data.bvh.have_motion) {
84 # ifdef __HAIR__
85  if (kernel_data.bvh.have_curves) {
86  return bvh_intersect_hair_motion(kg, ray, isect, visibility);
87  }
88 # endif /* __HAIR__ */
89 
90  return bvh_intersect_motion(kg, ray, isect, visibility);
91  }
92 # endif /* __OBJECT_MOTION__ */
93 
94 # ifdef __HAIR__
95  if (kernel_data.bvh.have_curves) {
96  return bvh_intersect_hair(kg, ray, isect, visibility);
97  }
98 # endif /* __HAIR__ */
99 
100  return bvh_intersect(kg, ray, isect, visibility);
101 }
102 
103 /* Single object BVH traversal, for SSS/AO/bevel. */
104 
105 # ifdef __BVH_LOCAL__
106 
107 # define BVH_FUNCTION_NAME bvh_intersect_local
108 # define BVH_FUNCTION_FEATURES BVH_HAIR
109 # include "kernel/bvh/local.h"
110 
111 # if defined(__OBJECT_MOTION__)
112 # define BVH_FUNCTION_NAME bvh_intersect_local_motion
113 # define BVH_FUNCTION_FEATURES BVH_MOTION | BVH_HAIR
114 # include "kernel/bvh/local.h"
115 # endif
116 
117 ccl_device_intersect bool scene_intersect_local(KernelGlobals kg,
118  ccl_private const Ray *ray,
119  ccl_private LocalIntersection *local_isect,
120  int local_object,
121  ccl_private uint *lcg_state,
122  int max_hits)
123 {
124  if (!intersection_ray_valid(ray)) {
125  if (local_isect) {
126  local_isect->num_hits = 0;
127  }
128  return false;
129  }
130 
131 # ifdef __EMBREE__
132  if (kernel_data.device_bvh) {
133  return kernel_embree_intersect_local(kg, ray, local_isect, local_object, lcg_state, max_hits);
134  }
135 # endif
136 
137 # ifdef __OBJECT_MOTION__
138  if (kernel_data.bvh.have_motion) {
139  return bvh_intersect_local_motion(kg, ray, local_isect, local_object, lcg_state, max_hits);
140  }
141 # endif /* __OBJECT_MOTION__ */
142  return bvh_intersect_local(kg, ray, local_isect, local_object, lcg_state, max_hits);
143 }
144 # endif
145 
146 /* Transparent shadow BVH traversal, recording multiple intersections. */
147 
148 # ifdef __SHADOW_RECORD_ALL__
149 
150 # define BVH_FUNCTION_NAME bvh_intersect_shadow_all
151 # define BVH_FUNCTION_FEATURES BVH_POINTCLOUD
152 # include "kernel/bvh/shadow_all.h"
153 
154 # if defined(__HAIR__)
155 # define BVH_FUNCTION_NAME bvh_intersect_shadow_all_hair
156 # define BVH_FUNCTION_FEATURES BVH_HAIR | BVH_POINTCLOUD
157 # include "kernel/bvh/shadow_all.h"
158 # endif
159 
160 # if defined(__OBJECT_MOTION__)
161 # define BVH_FUNCTION_NAME bvh_intersect_shadow_all_motion
162 # define BVH_FUNCTION_FEATURES BVH_MOTION | BVH_POINTCLOUD
163 # include "kernel/bvh/shadow_all.h"
164 # endif
165 
166 # if defined(__HAIR__) && defined(__OBJECT_MOTION__)
167 # define BVH_FUNCTION_NAME bvh_intersect_shadow_all_hair_motion
168 # define BVH_FUNCTION_FEATURES BVH_HAIR | BVH_MOTION | BVH_POINTCLOUD
169 # include "kernel/bvh/shadow_all.h"
170 # endif
171 
172 ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals kg,
174  ccl_private const Ray *ray,
175  uint visibility,
176  uint max_hits,
177  ccl_private uint *num_recorded_hits,
178  ccl_private float *throughput)
179 {
180  if (!intersection_ray_valid(ray)) {
181  *num_recorded_hits = 0;
182  *throughput = 1.0f;
183  return false;
184  }
185 
186 # ifdef __EMBREE__
187  if (kernel_data.device_bvh) {
188  return kernel_embree_intersect_shadow_all(
189  kg, state, ray, visibility, max_hits, num_recorded_hits, throughput);
190  }
191 # endif
192 
193 # ifdef __OBJECT_MOTION__
194  if (kernel_data.bvh.have_motion) {
195 # ifdef __HAIR__
196  if (kernel_data.bvh.have_curves) {
197  return bvh_intersect_shadow_all_hair_motion(
198  kg, ray, state, visibility, max_hits, num_recorded_hits, throughput);
199  }
200 # endif /* __HAIR__ */
201 
202  return bvh_intersect_shadow_all_motion(
203  kg, ray, state, visibility, max_hits, num_recorded_hits, throughput);
204  }
205 # endif /* __OBJECT_MOTION__ */
206 
207 # ifdef __HAIR__
208  if (kernel_data.bvh.have_curves) {
209  return bvh_intersect_shadow_all_hair(
210  kg, ray, state, visibility, max_hits, num_recorded_hits, throughput);
211  }
212 # endif /* __HAIR__ */
213 
214  return bvh_intersect_shadow_all(
215  kg, ray, state, visibility, max_hits, num_recorded_hits, throughput);
216 }
217 # endif /* __SHADOW_RECORD_ALL__ */
218 
219 /* Volume BVH traversal, for initializing or updating the volume stack. */
220 
221 # if defined(__VOLUME__) && !defined(__VOLUME_RECORD_ALL__)
222 
223 # define BVH_FUNCTION_NAME bvh_intersect_volume
224 # define BVH_FUNCTION_FEATURES BVH_HAIR
225 # include "kernel/bvh/volume.h"
226 
227 # if defined(__OBJECT_MOTION__)
228 # define BVH_FUNCTION_NAME bvh_intersect_volume_motion
229 # define BVH_FUNCTION_FEATURES BVH_MOTION | BVH_HAIR
230 # include "kernel/bvh/volume.h"
231 # endif
232 
233 ccl_device_intersect bool scene_intersect_volume(KernelGlobals kg,
234  ccl_private const Ray *ray,
235  ccl_private Intersection *isect,
236  const uint visibility)
237 {
238  if (!intersection_ray_valid(ray)) {
239  return false;
240  }
241 
242 # ifdef __OBJECT_MOTION__
243  if (kernel_data.bvh.have_motion) {
244  return bvh_intersect_volume_motion(kg, ray, isect, visibility);
245  }
246 # endif /* __OBJECT_MOTION__ */
247 
248  return bvh_intersect_volume(kg, ray, isect, visibility);
249 }
250 # endif /* defined(__VOLUME__) && !defined(__VOLUME_RECORD_ALL__) */
251 
252 /* Volume BVH traversal, for initializing or updating the volume stack.
253  * Variation that records multiple intersections at once. */
254 
255 # if defined(__VOLUME__) && defined(__VOLUME_RECORD_ALL__)
256 
257 # define BVH_FUNCTION_NAME bvh_intersect_volume_all
258 # define BVH_FUNCTION_FEATURES BVH_HAIR
259 # include "kernel/bvh/volume_all.h"
260 
261 # if defined(__OBJECT_MOTION__)
262 # define BVH_FUNCTION_NAME bvh_intersect_volume_all_motion
263 # define BVH_FUNCTION_FEATURES BVH_MOTION | BVH_HAIR
264 # include "kernel/bvh/volume_all.h"
265 # endif
266 
267 ccl_device_intersect uint scene_intersect_volume(KernelGlobals kg,
268  ccl_private const Ray *ray,
269  ccl_private Intersection *isect,
270  const uint max_hits,
271  const uint visibility)
272 {
273  if (!intersection_ray_valid(ray)) {
274  return false;
275  }
276 
277 # ifdef __EMBREE__
278  if (kernel_data.device_bvh) {
279  return kernel_embree_intersect_volume(kg, ray, isect, max_hits, visibility);
280  }
281 # endif
282 
283 # ifdef __OBJECT_MOTION__
284  if (kernel_data.bvh.have_motion) {
285  return bvh_intersect_volume_all_motion(kg, ray, isect, max_hits, visibility);
286  }
287 # endif /* __OBJECT_MOTION__ */
288 
289  return bvh_intersect_volume_all(kg, ray, isect, max_hits, visibility);
290 }
291 
292 # endif /* defined(__VOLUME__) && defined(__VOLUME_RECORD_ALL__) */
293 
294 # undef BVH_FEATURE
295 # undef BVH_NAME_JOIN
296 # undef BVH_NAME_EVAL
297 # undef BVH_FUNCTION_FULL_NAME
298 
299 #endif /* __BVH2__ */
300 
unsigned int uint
Definition: BLI_sys_types.h:67
#define ccl_private
Definition: cuda/compat.h:48
#define CCL_NAMESPACE_END
Definition: cuda/compat.h:9
CCL_NAMESPACE_BEGIN ccl_device_inline bool intersection_ray_valid(ccl_private const Ray *ray)
#define kernel_data
const KernelGlobalsCPU *ccl_restrict KernelGlobals
ccl_device_intersect bool scene_intersect(KernelGlobals kg, ccl_private const Ray *ray, const uint visibility, ccl_private Intersection *isect)
#define ccl_device_intersect
ccl_device_intersect bool kernel_embree_intersect(KernelGlobals kg, ccl_private const Ray *ray, const uint visibility, ccl_private Intersection *isect)
const int state
IntegratorShadowStateCPU *ccl_restrict IntegratorShadowState
Definition: state.h:149