在 3D 图形、碰撞检测和光线追踪领域,BSP(Binary Space Partitioning,二叉空间分割)、BVH(Bounding Volume Hierarchy,包围体层次结构) 和八叉树(Octree) 都是用于空间划分与加速查询的数据结构,核心目的是通过 “分而治之” 的思想减少物体间的碰撞检测、光线相交测试等计算的复杂度,提升渲染或物理模拟的效率。
三者的设计思路和适用场景各有侧重,具体区别如下:
BSP 通过无限平面递归地将 3D 空间 “一分为二”,形成二叉树结构:
- 根节点代表整个空间,每个节点用一个平面将当前空间分割为 “前半空间” 和 “后半空间”(平面两侧);
- 递归分割直到子空间内的物体数量足够少(达到终止条件);
- 树的叶子节点存储该子空间内的物体列表。
- 早期 3D 游戏的碰撞检测与场景渲染排序(如《Quake》系列):
通过 BSP 树可快速判断 “玩家与场景的碰撞”“视线是否被遮挡”,还能按距离相机的远近对多边形排序(解决透明物体渲染顺序问题)。
- 静态场景管理:适合结构固定的场景(如建筑、室内关卡),因为平面分割对动态物体支持较差(动态修改树结构成本高)。
- 优点:对静态场景的查询效率高(如射线检测、可见性判断);
- 缺点:构建过程复杂(需反复选择分割平面),不适合动态场景(物体移动会导致树结构大幅变化),3D 场景中应用逐渐减少。
BVH 通过包围体(如轴对齐 bounding box,AABB;球体; oriented bounding box,OBB)对物体进行层次化包裹,形成树结构:
- 根节点用一个大包围体包裹所有物体;
- 每个非叶节点将自身包围体中的物体分成两组,用两个子包围体分别包裹,递归此过程;
- 叶子节点对应单个物体(或少量物体)的包围体。
- 光线追踪加速(如电影渲染、实时光线追踪游戏):
光线与场景相交时,先判断是否与高层包围体相交,若不相交则直接跳过该分支,大幅减少光线与物体的逐一遍历。
- 碰撞检测:适合动态场景(如角色与场景物体、物体间的碰撞),因为更新包围体的成本较低。
- 优点:构建简单(无需复杂的平面分割),对动态物体支持好(移动物体只需更新相关节点的包围体),是目前光线追踪中最常用的加速结构;
- 缺点:查询效率略低于 BSP(对静态场景),包围体可能存在 “冗余空间”(导致无效检测)。
八叉树通过等轴分割将 3D 空间递归划分为 8 个子立方体(每个维度一分为二),形成树结构:
- 根节点代表整个空间,每个节点将空间沿 X、Y、Z 轴中点切开,得到 8 个大小相等的子空间;
- 递归分割子空间,直到子空间大小达到阈值或包含的物体数量足够少;
- 叶子节点存储该子空间内的物体。
- 3D 空间范围查询(如 “获取某区域内的所有物体”):
常用于物理引擎(如检测爆炸范围内的物体)、地形 LOD(细节层次)管理(如只渲染相机附近的高细节地形)。
- 稀疏场景管理:适合物体分布不均匀的场景(如开放世界中的远处物体稀疏、近处密集)。
- 优点:结构简单直观,适合范围查询和稀疏场景;
- 缺点:等轴分割可能导致子空间内物体分布不均(如细长物体可能横跨多个子空间),对动态场景的更新成本高于 BVH。
简单来说:
- BSP 是 “老派静态场景神器”,但已被更灵活的结构取代;
- BVH 是 “动态场景与光线追踪的首选”,平衡了效率与适应性;
- 八叉树是 “规则空间的万金油”,适合简单的范围查询和稀疏场景。
现代游戏引擎(如 Unity、Unreal)中,BVH 是光线追踪和动态碰撞的核心加速结构,八叉树用于辅助空间查询,BSP 仅在部分 legacy 系统中保留。