bvh.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  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. /* BVH
  17. *
  18. * Bounding volume hierarchy for ray tracing. We compile different variations
  19. * of the same BVH traversal function for faster rendering when some types of
  20. * primitives are not needed, using #includes to work around the lack of
  21. * C++ templates in OpenCL.
  22. *
  23. * Originally based on "Understanding the Efficiency of Ray Traversal on GPUs",
  24. * the code has been extended and modified to support more primitives and work
  25. * with CPU/CUDA/OpenCL. */
  26. #ifdef __EMBREE__
  27. # include "kernel/bvh/bvh_embree.h"
  28. #endif
  29. CCL_NAMESPACE_BEGIN
  30. #include "kernel/bvh/bvh_types.h"
  31. /* Common QBVH functions. */
  32. #ifdef __QBVH__
  33. # include "kernel/bvh/qbvh_nodes.h"
  34. # ifdef __KERNEL_AVX2__
  35. # include "kernel/bvh/obvh_nodes.h"
  36. # endif
  37. #endif
  38. /* Regular BVH traversal */
  39. #include "kernel/bvh/bvh_nodes.h"
  40. #define BVH_FUNCTION_NAME bvh_intersect
  41. #define BVH_FUNCTION_FEATURES 0
  42. #include "kernel/bvh/bvh_traversal.h"
  43. #if defined(__INSTANCING__)
  44. # define BVH_FUNCTION_NAME bvh_intersect_instancing
  45. # define BVH_FUNCTION_FEATURES BVH_INSTANCING
  46. # include "kernel/bvh/bvh_traversal.h"
  47. #endif
  48. #if defined(__HAIR__)
  49. # define BVH_FUNCTION_NAME bvh_intersect_hair
  50. # define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_HAIR
  51. # include "kernel/bvh/bvh_traversal.h"
  52. #endif
  53. #if defined(__OBJECT_MOTION__)
  54. # define BVH_FUNCTION_NAME bvh_intersect_motion
  55. # define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_MOTION
  56. # include "kernel/bvh/bvh_traversal.h"
  57. #endif
  58. #if defined(__HAIR__) && defined(__OBJECT_MOTION__)
  59. # define BVH_FUNCTION_NAME bvh_intersect_hair_motion
  60. # define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_HAIR | BVH_MOTION
  61. # include "kernel/bvh/bvh_traversal.h"
  62. #endif
  63. /* Subsurface scattering BVH traversal */
  64. #if defined(__BVH_LOCAL__)
  65. # define BVH_FUNCTION_NAME bvh_intersect_local
  66. # define BVH_FUNCTION_FEATURES BVH_HAIR
  67. # include "kernel/bvh/bvh_local.h"
  68. # if defined(__OBJECT_MOTION__)
  69. # define BVH_FUNCTION_NAME bvh_intersect_local_motion
  70. # define BVH_FUNCTION_FEATURES BVH_MOTION | BVH_HAIR
  71. # include "kernel/bvh/bvh_local.h"
  72. # endif
  73. #endif /* __BVH_LOCAL__ */
  74. /* Volume BVH traversal */
  75. #if defined(__VOLUME__)
  76. # define BVH_FUNCTION_NAME bvh_intersect_volume
  77. # define BVH_FUNCTION_FEATURES BVH_HAIR
  78. # include "kernel/bvh/bvh_volume.h"
  79. # if defined(__INSTANCING__)
  80. # define BVH_FUNCTION_NAME bvh_intersect_volume_instancing
  81. # define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_HAIR
  82. # include "kernel/bvh/bvh_volume.h"
  83. # endif
  84. # if defined(__OBJECT_MOTION__)
  85. # define BVH_FUNCTION_NAME bvh_intersect_volume_motion
  86. # define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_MOTION | BVH_HAIR
  87. # include "kernel/bvh/bvh_volume.h"
  88. # endif
  89. #endif /* __VOLUME__ */
  90. /* Record all intersections - Shadow BVH traversal */
  91. #if defined(__SHADOW_RECORD_ALL__)
  92. # define BVH_FUNCTION_NAME bvh_intersect_shadow_all
  93. # define BVH_FUNCTION_FEATURES 0
  94. # include "kernel/bvh/bvh_shadow_all.h"
  95. # if defined(__INSTANCING__)
  96. # define BVH_FUNCTION_NAME bvh_intersect_shadow_all_instancing
  97. # define BVH_FUNCTION_FEATURES BVH_INSTANCING
  98. # include "kernel/bvh/bvh_shadow_all.h"
  99. # endif
  100. # if defined(__HAIR__)
  101. # define BVH_FUNCTION_NAME bvh_intersect_shadow_all_hair
  102. # define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_HAIR
  103. # include "kernel/bvh/bvh_shadow_all.h"
  104. # endif
  105. # if defined(__OBJECT_MOTION__)
  106. # define BVH_FUNCTION_NAME bvh_intersect_shadow_all_motion
  107. # define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_MOTION
  108. # include "kernel/bvh/bvh_shadow_all.h"
  109. # endif
  110. # if defined(__HAIR__) && defined(__OBJECT_MOTION__)
  111. # define BVH_FUNCTION_NAME bvh_intersect_shadow_all_hair_motion
  112. # define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_HAIR | BVH_MOTION
  113. # include "kernel/bvh/bvh_shadow_all.h"
  114. # endif
  115. #endif /* __SHADOW_RECORD_ALL__ */
  116. /* Record all intersections - Volume BVH traversal */
  117. #if defined(__VOLUME_RECORD_ALL__)
  118. # define BVH_FUNCTION_NAME bvh_intersect_volume_all
  119. # define BVH_FUNCTION_FEATURES BVH_HAIR
  120. # include "kernel/bvh/bvh_volume_all.h"
  121. # if defined(__INSTANCING__)
  122. # define BVH_FUNCTION_NAME bvh_intersect_volume_all_instancing
  123. # define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_HAIR
  124. # include "kernel/bvh/bvh_volume_all.h"
  125. # endif
  126. # if defined(__OBJECT_MOTION__)
  127. # define BVH_FUNCTION_NAME bvh_intersect_volume_all_motion
  128. # define BVH_FUNCTION_FEATURES BVH_INSTANCING | BVH_MOTION | BVH_HAIR
  129. # include "kernel/bvh/bvh_volume_all.h"
  130. # endif
  131. #endif /* __VOLUME_RECORD_ALL__ */
  132. #undef BVH_FEATURE
  133. #undef BVH_NAME_JOIN
  134. #undef BVH_NAME_EVAL
  135. #undef BVH_FUNCTION_FULL_NAME
  136. ccl_device_inline bool scene_intersect_valid(const Ray *ray)
  137. {
  138. /* NOTE: Due to some vectorization code non-finite origin point might
  139. * cause lots of false-positive intersections which will overflow traversal
  140. * stack.
  141. * This code is a quick way to perform early output, to avoid crashes in
  142. * such cases.
  143. * From production scenes so far it seems it's enough to test first element
  144. * only.
  145. */
  146. return isfinite_safe(ray->P.x) && isfinite_safe(ray->D.x);
  147. }
  148. /* Note: ray is passed by value to work around a possible CUDA compiler bug. */
  149. ccl_device_intersect bool scene_intersect(KernelGlobals *kg,
  150. const Ray ray,
  151. const uint visibility,
  152. Intersection *isect)
  153. {
  154. PROFILING_INIT(kg, PROFILING_INTERSECT);
  155. if (!scene_intersect_valid(&ray)) {
  156. return false;
  157. }
  158. #ifdef __EMBREE__
  159. if (kernel_data.bvh.scene) {
  160. isect->t = ray.t;
  161. CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_REGULAR);
  162. IntersectContext rtc_ctx(&ctx);
  163. RTCRayHit ray_hit;
  164. kernel_embree_setup_rayhit(ray, ray_hit, visibility);
  165. rtcIntersect1(kernel_data.bvh.scene, &rtc_ctx.context, &ray_hit);
  166. if (ray_hit.hit.geomID != RTC_INVALID_GEOMETRY_ID &&
  167. ray_hit.hit.primID != RTC_INVALID_GEOMETRY_ID) {
  168. kernel_embree_convert_hit(kg, &ray_hit.ray, &ray_hit.hit, isect);
  169. return true;
  170. }
  171. return false;
  172. }
  173. #endif /* __EMBREE__ */
  174. #ifdef __OBJECT_MOTION__
  175. if (kernel_data.bvh.have_motion) {
  176. # ifdef __HAIR__
  177. if (kernel_data.bvh.have_curves)
  178. return bvh_intersect_hair_motion(kg, &ray, isect, visibility);
  179. # endif /* __HAIR__ */
  180. return bvh_intersect_motion(kg, &ray, isect, visibility);
  181. }
  182. #endif /* __OBJECT_MOTION__ */
  183. #ifdef __HAIR__
  184. if (kernel_data.bvh.have_curves)
  185. return bvh_intersect_hair(kg, &ray, isect, visibility);
  186. #endif /* __HAIR__ */
  187. #ifdef __KERNEL_CPU__
  188. # ifdef __INSTANCING__
  189. if (kernel_data.bvh.have_instancing)
  190. return bvh_intersect_instancing(kg, &ray, isect, visibility);
  191. # endif /* __INSTANCING__ */
  192. return bvh_intersect(kg, &ray, isect, visibility);
  193. #else /* __KERNEL_CPU__ */
  194. # ifdef __INSTANCING__
  195. return bvh_intersect_instancing(kg, &ray, isect, visibility);
  196. # else
  197. return bvh_intersect(kg, &ray, isect, visibility);
  198. # endif /* __INSTANCING__ */
  199. #endif /* __KERNEL_CPU__ */
  200. }
  201. #ifdef __BVH_LOCAL__
  202. /* Note: ray is passed by value to work around a possible CUDA compiler bug. */
  203. ccl_device_intersect bool scene_intersect_local(KernelGlobals *kg,
  204. const Ray ray,
  205. LocalIntersection *local_isect,
  206. int local_object,
  207. uint *lcg_state,
  208. int max_hits)
  209. {
  210. PROFILING_INIT(kg, PROFILING_INTERSECT_LOCAL);
  211. if (!scene_intersect_valid(&ray)) {
  212. local_isect->num_hits = 0;
  213. return false;
  214. }
  215. # ifdef __EMBREE__
  216. if (kernel_data.bvh.scene) {
  217. CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_SSS);
  218. ctx.lcg_state = lcg_state;
  219. ctx.max_hits = max_hits;
  220. ctx.ss_isect = local_isect;
  221. local_isect->num_hits = 0;
  222. ctx.sss_object_id = local_object;
  223. IntersectContext rtc_ctx(&ctx);
  224. RTCRay rtc_ray;
  225. kernel_embree_setup_ray(ray, rtc_ray, PATH_RAY_ALL_VISIBILITY);
  226. /* Get the Embree scene for this intersection. */
  227. RTCGeometry geom = rtcGetGeometry(kernel_data.bvh.scene, local_object * 2);
  228. if (geom) {
  229. float3 P = ray.P;
  230. float3 dir = ray.D;
  231. float3 idir = ray.D;
  232. const int object_flag = kernel_tex_fetch(__object_flag, local_object);
  233. if (!(object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
  234. Transform ob_itfm;
  235. rtc_ray.tfar = bvh_instance_motion_push(
  236. kg, local_object, &ray, &P, &dir, &idir, ray.t, &ob_itfm);
  237. /* bvh_instance_motion_push() returns the inverse transform but
  238. * it's not needed here. */
  239. (void)ob_itfm;
  240. rtc_ray.org_x = P.x;
  241. rtc_ray.org_y = P.y;
  242. rtc_ray.org_z = P.z;
  243. rtc_ray.dir_x = dir.x;
  244. rtc_ray.dir_y = dir.y;
  245. rtc_ray.dir_z = dir.z;
  246. }
  247. RTCScene scene = (RTCScene)rtcGetGeometryUserData(geom);
  248. if (scene) {
  249. rtcOccluded1(scene, &rtc_ctx.context, &rtc_ray);
  250. }
  251. }
  252. return local_isect->num_hits > 0;
  253. }
  254. # endif /* __EMBREE__ */
  255. # ifdef __OBJECT_MOTION__
  256. if (kernel_data.bvh.have_motion) {
  257. return bvh_intersect_local_motion(kg, &ray, local_isect, local_object, lcg_state, max_hits);
  258. }
  259. # endif /* __OBJECT_MOTION__ */
  260. return bvh_intersect_local(kg, &ray, local_isect, local_object, lcg_state, max_hits);
  261. }
  262. #endif
  263. #ifdef __SHADOW_RECORD_ALL__
  264. ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals *kg,
  265. const Ray *ray,
  266. Intersection *isect,
  267. uint visibility,
  268. uint max_hits,
  269. uint *num_hits)
  270. {
  271. PROFILING_INIT(kg, PROFILING_INTERSECT_SHADOW_ALL);
  272. if (!scene_intersect_valid(ray)) {
  273. *num_hits = 0;
  274. return false;
  275. }
  276. # ifdef __EMBREE__
  277. if (kernel_data.bvh.scene) {
  278. CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_SHADOW_ALL);
  279. ctx.isect_s = isect;
  280. ctx.max_hits = max_hits;
  281. ctx.num_hits = 0;
  282. IntersectContext rtc_ctx(&ctx);
  283. RTCRay rtc_ray;
  284. kernel_embree_setup_ray(*ray, rtc_ray, PATH_RAY_SHADOW);
  285. rtcOccluded1(kernel_data.bvh.scene, &rtc_ctx.context, &rtc_ray);
  286. if (ctx.num_hits > max_hits) {
  287. return true;
  288. }
  289. *num_hits = ctx.num_hits;
  290. return rtc_ray.tfar == -INFINITY;
  291. }
  292. # endif
  293. # ifdef __OBJECT_MOTION__
  294. if (kernel_data.bvh.have_motion) {
  295. # ifdef __HAIR__
  296. if (kernel_data.bvh.have_curves) {
  297. return bvh_intersect_shadow_all_hair_motion(kg, ray, isect, visibility, max_hits, num_hits);
  298. }
  299. # endif /* __HAIR__ */
  300. return bvh_intersect_shadow_all_motion(kg, ray, isect, visibility, max_hits, num_hits);
  301. }
  302. # endif /* __OBJECT_MOTION__ */
  303. # ifdef __HAIR__
  304. if (kernel_data.bvh.have_curves) {
  305. return bvh_intersect_shadow_all_hair(kg, ray, isect, visibility, max_hits, num_hits);
  306. }
  307. # endif /* __HAIR__ */
  308. # ifdef __INSTANCING__
  309. if (kernel_data.bvh.have_instancing) {
  310. return bvh_intersect_shadow_all_instancing(kg, ray, isect, visibility, max_hits, num_hits);
  311. }
  312. # endif /* __INSTANCING__ */
  313. return bvh_intersect_shadow_all(kg, ray, isect, visibility, max_hits, num_hits);
  314. }
  315. #endif /* __SHADOW_RECORD_ALL__ */
  316. #ifdef __VOLUME__
  317. ccl_device_intersect bool scene_intersect_volume(KernelGlobals *kg,
  318. const Ray *ray,
  319. Intersection *isect,
  320. const uint visibility)
  321. {
  322. PROFILING_INIT(kg, PROFILING_INTERSECT_VOLUME);
  323. if (!scene_intersect_valid(ray)) {
  324. return false;
  325. }
  326. # ifdef __OBJECT_MOTION__
  327. if (kernel_data.bvh.have_motion) {
  328. return bvh_intersect_volume_motion(kg, ray, isect, visibility);
  329. }
  330. # endif /* __OBJECT_MOTION__ */
  331. # ifdef __KERNEL_CPU__
  332. # ifdef __INSTANCING__
  333. if (kernel_data.bvh.have_instancing)
  334. return bvh_intersect_volume_instancing(kg, ray, isect, visibility);
  335. # endif /* __INSTANCING__ */
  336. return bvh_intersect_volume(kg, ray, isect, visibility);
  337. # else /* __KERNEL_CPU__ */
  338. # ifdef __INSTANCING__
  339. return bvh_intersect_volume_instancing(kg, ray, isect, visibility);
  340. # else
  341. return bvh_intersect_volume(kg, ray, isect, visibility);
  342. # endif /* __INSTANCING__ */
  343. # endif /* __KERNEL_CPU__ */
  344. }
  345. #endif /* __VOLUME__ */
  346. #ifdef __VOLUME_RECORD_ALL__
  347. ccl_device_intersect uint scene_intersect_volume_all(KernelGlobals *kg,
  348. const Ray *ray,
  349. Intersection *isect,
  350. const uint max_hits,
  351. const uint visibility)
  352. {
  353. PROFILING_INIT(kg, PROFILING_INTERSECT_VOLUME_ALL);
  354. if (!scene_intersect_valid(ray)) {
  355. return false;
  356. }
  357. # ifdef __EMBREE__
  358. if (kernel_data.bvh.scene) {
  359. CCLIntersectContext ctx(kg, CCLIntersectContext::RAY_VOLUME_ALL);
  360. ctx.isect_s = isect;
  361. ctx.max_hits = max_hits;
  362. ctx.num_hits = 0;
  363. IntersectContext rtc_ctx(&ctx);
  364. RTCRay rtc_ray;
  365. kernel_embree_setup_ray(*ray, rtc_ray, visibility);
  366. rtcOccluded1(kernel_data.bvh.scene, &rtc_ctx.context, &rtc_ray);
  367. return rtc_ray.tfar == -INFINITY;
  368. }
  369. # endif
  370. # ifdef __OBJECT_MOTION__
  371. if (kernel_data.bvh.have_motion) {
  372. return bvh_intersect_volume_all_motion(kg, ray, isect, max_hits, visibility);
  373. }
  374. # endif /* __OBJECT_MOTION__ */
  375. # ifdef __INSTANCING__
  376. if (kernel_data.bvh.have_instancing)
  377. return bvh_intersect_volume_all_instancing(kg, ray, isect, max_hits, visibility);
  378. # endif /* __INSTANCING__ */
  379. return bvh_intersect_volume_all(kg, ray, isect, max_hits, visibility);
  380. }
  381. #endif /* __VOLUME_RECORD_ALL__ */
  382. /* Ray offset to avoid self intersection.
  383. *
  384. * This function should be used to compute a modified ray start position for
  385. * rays leaving from a surface. */
  386. ccl_device_inline float3 ray_offset(float3 P, float3 Ng)
  387. {
  388. #ifdef __INTERSECTION_REFINE__
  389. const float epsilon_f = 1e-5f;
  390. /* ideally this should match epsilon_f, but instancing and motion blur
  391. * precision makes it problematic */
  392. const float epsilon_test = 1.0f;
  393. const int epsilon_i = 32;
  394. float3 res;
  395. /* x component */
  396. if (fabsf(P.x) < epsilon_test) {
  397. res.x = P.x + Ng.x * epsilon_f;
  398. }
  399. else {
  400. uint ix = __float_as_uint(P.x);
  401. ix += ((ix ^ __float_as_uint(Ng.x)) >> 31) ? -epsilon_i : epsilon_i;
  402. res.x = __uint_as_float(ix);
  403. }
  404. /* y component */
  405. if (fabsf(P.y) < epsilon_test) {
  406. res.y = P.y + Ng.y * epsilon_f;
  407. }
  408. else {
  409. uint iy = __float_as_uint(P.y);
  410. iy += ((iy ^ __float_as_uint(Ng.y)) >> 31) ? -epsilon_i : epsilon_i;
  411. res.y = __uint_as_float(iy);
  412. }
  413. /* z component */
  414. if (fabsf(P.z) < epsilon_test) {
  415. res.z = P.z + Ng.z * epsilon_f;
  416. }
  417. else {
  418. uint iz = __float_as_uint(P.z);
  419. iz += ((iz ^ __float_as_uint(Ng.z)) >> 31) ? -epsilon_i : epsilon_i;
  420. res.z = __uint_as_float(iz);
  421. }
  422. return res;
  423. #else
  424. const float epsilon_f = 1e-4f;
  425. return P + epsilon_f * Ng;
  426. #endif
  427. }
  428. #if defined(__VOLUME_RECORD_ALL__) || (defined(__SHADOW_RECORD_ALL__) && defined(__KERNEL_CPU__))
  429. /* ToDo: Move to another file? */
  430. ccl_device int intersections_compare(const void *a, const void *b)
  431. {
  432. const Intersection *isect_a = (const Intersection *)a;
  433. const Intersection *isect_b = (const Intersection *)b;
  434. if (isect_a->t < isect_b->t)
  435. return -1;
  436. else if (isect_a->t > isect_b->t)
  437. return 1;
  438. else
  439. return 0;
  440. }
  441. #endif
  442. #if defined(__SHADOW_RECORD_ALL__)
  443. ccl_device_inline void sort_intersections(Intersection *hits, uint num_hits)
  444. {
  445. # ifdef __KERNEL_GPU__
  446. /* Use bubble sort which has more friendly memory pattern on GPU. */
  447. bool swapped;
  448. do {
  449. swapped = false;
  450. for (int j = 0; j < num_hits - 1; ++j) {
  451. if (hits[j].t > hits[j + 1].t) {
  452. struct Intersection tmp = hits[j];
  453. hits[j] = hits[j + 1];
  454. hits[j + 1] = tmp;
  455. swapped = true;
  456. }
  457. }
  458. --num_hits;
  459. } while (swapped);
  460. # else
  461. qsort(hits, num_hits, sizeof(Intersection), intersections_compare);
  462. # endif
  463. }
  464. #endif /* __SHADOW_RECORD_ALL__ | __VOLUME_RECORD_ALL__ */
  465. CCL_NAMESPACE_END