BVH
Bounding Volume Hierarchy,正常来说,对于一条 ray,我们需要查询空间中所有存在的几何面,这很贵,于是借助 BVH 对空间中存在的几何面先进行分层,快速地排除一部分不可能击中的面。
其中使用 “Volume” 是因为它是一个更大的概念,而 AABB 是一个非常常见的包围体的实现,因为其求交操作非常的便宜
假设我们有若干几何面被一个 Volume 包裹住,那么如果当前的 Ray 与这个更大的包围盒没有交那么必定和其中所有的物体都没有交,由此快速过滤一些不可能击中的面
简单思路
它的思路实际上是不断的对物体进行分层划分 —— 首先所有的物体都属于一个最大的可以抱住它们的 Bounding Volume,然后在把当前的所有物体按照某种模式划分成若干小分,再反复递归这些子集,直到叶子节点只表示一个物体为止。
以 AABB 作为例子
现在假设要实现的就是一个基于 AABB 的二叉树状的 BVH
好,现在接受到传入的一串物体,我们使用一个最大的 AABB 作为 Root,然后需要将它们划分成两个部分 —— 现在先解决第一个问题,以什么基准划分。显然的,我们希望物体越“铺开”越好,那么延续 AABB 最好的地方 —— 所有面都和坐标轴平行,我们不妨选取 x, y, z 轴作为划分
由于现在的依据都是包围盒,所以以包围盒的中心作为物体的替代,得到这些物体包围盒中心当中,轴方向跨度最大的那根轴作为划分依据,接着按选定轴排序,然后取中位数得到切的位置(实际上并不需要排序,只需要找到中位数即可),依照中位数把物体划分成“大的“/”小的“两个子集
接着我们分别对其做 AABB 记录,再递归建树即可
查询的时候在击中 Root 的时候进入树,判断是和左子树还是右子树的 AABB 碰撞(根据使用情况可能都要触发递归),如果碰撞则进入子树继续递归进行,直到跑到叶子节点进行最终的几何面碰撞计算