BVH的构建比较耗时间,而且对于动态物体的支持比较麻烦,但是运行效率会更高,因此常用于离线渲染和光线追踪等对性能要求较高的场合。八叉树的构建简洁明了,比较直观。八叉树的结构是固定的,不会受物体位置的影响。
一、游戏场景管理中BVH相比八叉树有什么优劣
BVH的构建比较耗时间,而且对于动态物体的支持比较麻烦,但是运行效率会更高,因此常用于离线渲染和光线追踪等对性能要求较高的场合。
八叉树的构建简洁明了,比较直观。八叉树的结构是固定的,不会受物体位置的影响,这样对动态物体非常友好。
游戏中用的八叉树常常是松散八叉树,就是子节点的范围会比正常的范围略微大一圈,这样如果物体和分割轴相交,也可以放到子节点下。
游戏中物体的大小通常是不变的,物体的移动的处理就很简单,只需要改变物体挂载的子节点位置就行了,而不要调整挂载子节点的深度。
游戏中常常有非常多的动态对象,使用松散八叉树是非常合适的。
BVH在光线追踪上的优势:
曾经写过一个Path Tracing(递归的光线追踪),使用KD树来实现光线相交测试。KD树可以看成一个拓展后的八叉树(八叉树每层要在x,y,z轴上二分,而KD树则是每层选一个轴进行分割)。我最初用的是每层二分的KD树。那么如果要处理下图这种很大的场景中只有数个三角形的情况,则前面几层都是在做一些低效的相交测试(因为和三角形真正占据的面积相差太大)。
但使用BVH进行光线相交测试的话(可以类比为:基于SAH(Surface Area Heuristic)的KD树),则可以进行高效的分割场景,充分考虑三角形本身的面积与形状。同样利用上图场景,基于SAH的KD树可以快速定位到相交的物体,处理的好的话从根往下一层就能找到相交的物体。
BVH相比八叉树:
BVH实现起来比八叉树稍微麻烦一点,八叉树只需要知道场景的大小和模型的精度就能进行分割,然后将模型一个个塞进去即可,而BVH需要了解全部的模型信息才能进行下一步分割。而且游戏场景一般都分布比较均匀(一大片空地的情况少见),上图中物体集中在某一区域的情况比较少,所以利用八叉树和BVH树的层数和效率应该是差不多的。
提到了针对地块进行“2d裁剪”就是八叉树的变种,国内某剑五采用的场景管理方式就是四叉树,做视锥测试什么的很容易而且高效。在NVIDIA实习时还对其引擎做过一个小小的优化,通过确定摄像机在四叉树中的最底层位置,一层层往上由近及远渲染,减少over-draw次数。这个就是利用了四叉树本身的结构性质。优化前后,某帧第6000个DX draw event时的渲染结果
BVH在碰撞检测上:
引擎不会去检测每个三角形之间的碰撞,而是会先检测两者的包围盒(AABB,OBB,DOP等等)是否移动或改变,然后再检测是否相交,然后再检测内部的三角形是否相交。
延伸阅读:
二、八叉树(octree)是什么
八叉树(octree)是三维空间划分的数据结构之一,它用于加速空间查询,例如在游戏中:
加速用于可见性判断的视锥裁剪(view frustum culling)。
加速射线投射(ray casting) ,如用作视线判断或枪击判定。
邻近查询(proximity query),如查询玩家角色某半径范围内的敌方NPC。