何时使用二进制空间分区、四叉树、八叉树?

Posted

技术标签:

【中文标题】何时使用二进制空间分区、四叉树、八叉树?【英文标题】:When to use Binary Space Partitioning, Quadtree, Octree? 【发布时间】:2008-09-19 05:08:25 【问题描述】:

我最近了解了二进制空间分区树及其在 3D 图形和碰撞检测中的应用。我还简要阅读了有关四叉树和八叉树的材料。你什么时候会在 bsp 树上使用四叉树,反之亦然?它们可以互换吗?如果我有足够的信息来填写这样的表格,我会很满意:

            | BSP | Quadtree | Octree
------------+----------------+-------
Situation A |  X  |          |
Situation B |     |     X    |
Situation C |     |          |   X

什么是 A、B 和 C?

【问题讨论】:

【参考方案1】:

您的问题没有明确的答案。这完全取决于您的数据是如何组织的。

注意事项:

四叉树最适合主要是二维的数据,例如导航系统中的地图渲染。在这种情况下,它比八叉树更快,因为它更好地适应几何形状并保持节点结构较小。

如果数据是三维的,则八叉树和 BVH(边界体积层次结构)会受益。如果您的几何实体聚集在 3D 空间中,它也能很好地工作。 (见Octree vs BVH)(存档自original

Oc- 和 Quadtrees 的好处是您可以随时停止生成树。如果您想使用图形加速器渲染图形,它只允许您在对象级别上生成树,并在单个绘制调用中将每个对象发送到图形 API。这比发送单个三角形(如果您完全使用 BSP-Trees,您必须这样做)执行 很多

BSP-Trees 确实是一个特例。它们在 2D 和 3D 中工作得非常好,但是生成好的 BSP-Trees 本身就是一种艺术形式。 BSP 树的缺点是您可能必须将几何体分割成更小的部分。这可以增加数据集的整体多边形数。它们非常适合渲染,但更适合碰撞检测和光线追踪。

BSP 树的一个很好的特性是,它们将多边形汤分解成一个结构,该结构可以从任何相机位置完美地向后渲染(反之亦然),而无需进行实际排序。每个视点的顺序是数据结构的一部分,并在 BSP-Tree 编译期间完成。

顺便说一句,这就是它们在 10 年前如此受欢迎的原因。 Quake 使用它们是因为它允许图形引擎/软件光栅器不使用昂贵的 z 缓冲区。

所有提到的树都只是树的家族。还有松散的八叉树、kd-trees 混合树以及许多其他相关结构。

【讨论】:

很好的答案,但我不确定你所说的将对象“发送”到 GPU 而不是单个三角形是什么意思。您指的是 VBO 与即时模式吗?因为我认为这两种方法都可以做到…… @DavidJeske 这个答案是六岁了。长期从事计算机科学。现在可能已经改变了。 关于使用 BSP 绘制速度较慢的评论是错误的。 BSP 旨在优化大型静态几何。它们最初用于优化软件光栅化的遮挡,此后也被用于预计算硬件光栅化的绘图批次。当有大量实例化时,BSP 不适合,因为必须将对象实例化并细分到 BSP 中。 BSP 也不适合动态对象,因为它们构建起来太慢了。 BSP 真的,我的意思是 真的,不适合任何现代场景。在您必须对少量三角形进行分类的日子里,它们很棒。如今,一点过度绘制(即使使用核心片段着色器)显然比在场景中单独排序和绘制每个三角形要快方式。绘制 z-prepass 消除了所有过度绘制,并且仍然更快。【参考方案2】:

BSP-Trees 和其他类型的 3d-trees 之间最大的实际区别是 BSP-Trees 可以更优化,但只适用于静态几何。这是因为 BSP 树的构建通常非常缓慢,通常需要数小时或数天才能完成典型的静态城市游戏关卡。

构建 BSP 树需要较长时间的两个主要原因是(a)它们使用非轴对齐的分割平面,这需要更长的时间才能找到最佳位置,以及(b)它们在轴边界上细分几何图形,确保没有对象交叉分割平面。

其他类型的 3d 树(Octrees、Quadtrees、kd-tree、Bounding-Volume-Hierarchy)使用轴对齐的包围体,并且体积(可选)允许重叠,因此包含的对象不需要削减体积边界。这两者都使得树不如 BSP 树优化,但构建速度更快,并且更容易针对动态对象进行更改。

将这些因素外推到情境中……

室外区域通常使用基于高度场的地面表示,可以是简单的高度图,也可以是更复杂的地理 Mip 映射技术,例如 ROAM。地面本身不参与 3D 空间划分,只有放置在地面上的物体。

具有大量简单和相似几何体(房屋、树木、小行星等)实例的世界通常会使用非 BSP 树(例如 BVH),因为将几何体放入 BSP 树意味着复制并为每个实例分割细节几何。

相反,没有实例化的大型自定义静态网格物体(例如城市场景或复杂的室内环境)通常会使用 BSP-Tree 来提高运行时性能。 BSP-Tree 在节点边界上分割几何体这一事实有助于渲染性能,因为 BSP 节点可以用作预先组织的三角形渲染批次。 BSP-Tree 还可以针对遮挡进行优化,避免绘制已知位于其他几何图形后面的 BSP-Tree 部分。

另请参阅:Octree vs BVH(存档自 original)、Bounding Volume Hierarchy Tutorial、BSP Tutorial。

【讨论】:

【参考方案3】:

BSP 最适合城市环境。

四叉树最适合使用地形等高度图。

八叉树最适合在 3D 空间中具有几何体块的情况,例如太阳系。

【讨论】:

【参考方案4】:

BSP 是加速碰撞检测的好选择,具体取决于您使用的风格。它们在点、线或射线测试中速度特别快,但在体积测试中速度稍慢且复杂一些。

至于它们在图形中的使用,BSP 几乎已经过时了。八叉树适用于总能见度剔除之类的事情,AABB 树也是如此。

【讨论】:

【参考方案5】:

我对 BSP 没有太多经验,但我可以说,当你渲染的场景很高时,你应该使用八叉树而不是四叉树。也就是说,高度超过宽度和深度的一半——经验法则很少。一般来说,八叉树不会比四叉树带来巨大的成本,而且它们有可能加快速度。 YMMV。

【讨论】:

【参考方案6】:

除非您知道自己在做什么,否则总是选择八叉树,这样您就可以停止过度优化并开始研究更重要的功能。严重的是,瓶颈总是在其他地方,或者您正在围绕一个优化的系统设计代码,最终防止以后发生某些类型的更改。

【讨论】:

【参考方案7】:

通常这些事情没有明确的答案。我建议 A、B 和 C 是你的空间大小和你区分的东西数量的函数的结果。

【讨论】:

请澄清一下,BSP 适合大空间还是小空间?更多或更少的对象?【参考方案8】:

BSP 更适合您只想进行遮挡的更小、更简单的空间。如果您想要给定光线的所有交点,则需要升级到四叉树/八叉树。

至于四叉树与八叉树 - 您最关心多少维度?二维表示四叉树,四维表示八叉树。如前所述,由于四叉树可以在三个空间中工作,但如果您希望对每个维度进行适当的处​​理,八叉树是可行的方法。

【讨论】:

以上是关于何时使用二进制空间分区、四叉树、八叉树?的主要内容,如果未能解决你的问题,请参考以下文章

Mark四叉树与八叉树

PCL学习八叉树

PCL——八叉树Octree

八叉树分割3d 空间

空间数据结构

PCL:八叉树Octree实现点云K近邻搜索