Acceleration Algorithms

Spatial Data Structures

空间数据结构是指一个组织了n维空间中的集合体结构。空间数据结构的组织通常是分层的,这意味着,最高层包含一些子层,每个子层定义了自己的空间体积,而这些空间有包含自己的子层,因此,这些结构式嵌套的,具有递归性质。

一些常见的空间数据结构类型是包围体层次结构,二进制空间划分(BSP)树的变体,四叉树和八叉树。BSP树和八叉树是基于空间划分的数据结构。这意味着场景的整个空间被划分并编码在数据结构中。例如,所有叶子节点空间的并集等于场景的整个空间。一般情况下,叶节点的体积不重叠。

包围体层次结构(BVH)

包围体(BVH)是一个包含一组对象的体积,BV的想法是包含的对象更简单的几何形状,因此使用BV的测试可以比使用本身更快地完成。BV的例子有球体,轴向包围盒(AABB),定向包围盒(OBB)和k-DOPs,BV对渲染图像没有直接的贡献,相反,他被用一个代理来代替包围的对象,以加速渲染,选择,查询和其他计算。

对于三维的场景实时渲染,通常使用包围体层次进行分层视锥体剔除。场景组成在一个层次树结构,有一组链接的节点组成。最上面的根节点,它没有父节点。内部节点有指向它的子节点。因此,跟是一个内部节点,除非它是树种唯一的节点叶节点保存要渲染的几何图形包围在它的整个子树中。还可以决定从叶节点排除bv,而将他们包含在每个也节点上方的内部节点中。每个节点的BV包含了其子树中所有叶子节点的几何形状。这意味着跟包含整个场景的BV。

BVH底层结构是树。所以他非常适合执行各种的查询,例如,假设一条射线与场景相交,返回第一个交集,就像阴影射线的情况一样,要为此使用BVH,从根开始测试。如果射线错过了它的BV,那么射线就错过了包含在BVH中所有的几何图形。否则,测试将继续递归下去,即测试根的子节点的BV,射线就会在这个节点的几何体上进行测试。性能提高的部分原因是使用BV测试射线速度很快。这就是为啥像球体和盒子这样的简单物体被用作BV。另一个原因就是BV嵌套,这使得我们可以避免由于在树中提前终止而测试大区域的空间。

往往最接近的相交的点,不是最先发现的,唯一需要额外的数据是遍历树时发现的最近对象的距离和标识。在遍历过程中,当前最近的距离也被用来剔除树。如果一个BV是相交的,但是他的距离超过了目前为止找到的最近距离,那么BV可以被丢弃。这里可以看出BSP树比BVH更有优势,因为它可以保证从前到后的排序,而不是BVH的粗略排序。

BSP树

二进制(Binary)空间划分树,简称BSP树,在计算机图形学以两种明显不同的形式存在,我们称之为轴对齐树和多边形对齐树。树是通过使用平面将空间划分为两部分,然后将几何图形分类到这两个空间中来创建的,这个划分是递归的。一个有价值的特性是,以某种方式遍历BSP树,树的几何内容可以从任何角度从前到后排序。这种排序对于轴对齐的BSP是近似的,对于多边形对齐的BSP是精确的。

以如下方式创建轴向BSP树。首先整个场景被包围在一个轴对齐的包围盒(AABB)中。接下来是递归将这个包围盒划分为更小的包围盒。现在,考虑任意递归的级别的包围盒。选择包围盒的一个轴,生成一个垂直的面,将空间划分为2个包围盒。有些方案确定了这个划分的平面,以便将包围盒精确地分成2半,另一些允许运行时改变位置,称为非均匀划分,节点在内存中的位置由其在树种的位置隐式给出。

可以用多种方法处理与平面相交的物体,例如,它可以存储在书的这一层,或者成为两个子包围盒的成员,或者被平面分割成2个独立的对象。在树的级别存储的好处是书中只有一个对象的副本,这使得删除对象很easy, 然而,与平面相交的小物体会卡在树的上层,这往往是低效的。 将相交的对象放置到两个子对象中可以使较大的对象具有更紧密的边界,因为所有对象都向下渗透到一个或多个叶节点,但只有那些它们重叠的叶节点。 每个子框包含一定数量的对象,这个平面划分过程重复进行,递归地划分每个AABB,直到满足某个条件停止该过程。 下图是轴对齐的BSP树的示例:

粗略的前后排序是如何使用轴对齐BSP书的一个例子。这对于遮挡剔除算法是有用的。以及通过最小化像素overdraw来减少像素着色器的成本。假设当前遍历一个名为N的节点。这里N是遍历开始时的根。检查N的分割平面,然后递归的检查一侧的树, 因此,只有当整个树的一半被遍历时,我们才开始遍历另一边。 由于叶节点的内容没有排序,而且对象可能位于树的许多节点中,因此这种遍历不会给出精确的前后排序。 然而,它给出了一个粗略的排序,这通常是有用的。 与观察者的位置相比,从节点平面的另一侧开始遍历,可以得到粗略的前后排序。 这对于透明排序很有用。 BSP遍历也可以用来测试光线对场景几何的影响,射线的位置只是用来交换观察者的位置。

多边形对齐BSP树

另一种类型是多边形多起的形式,它会选择一个多边形作为分割器,将空间分成2半,也就是说,在根节点中,选择一个多边形。对边形所在的平面用于将场景中的其余多边形划分为2个集合,任何被分割平面相交的多边形沿着相交线被分割成2个独立的部分。现在在剖分平面的每个半空间中,选择另一个多边形作为分割器,只分割其半空间中的多边形。这个过程是递归的,知道所有的多边形都在BSP树中。如下图:

多边形对齐的BSP树有一些有用的属性。 一个是,对于给定的视图,树结构可以严格从后到前(或从前到后)遍历。 这与轴对齐的BSP树相比,后者通常只给出粗略排序的顺序。 确定相机位于根平面的哪一边。 在这个远平面的多边形集合在平表面的集合之外。 对于远平面,采取下一层的划分平面,并确定相机在哪一边。 远平面的子集也是离摄像机最远的子集。 通过继续递归,这个过程建立了严格的前后顺序,可以使用画家的算法来渲染场景。 画家的算法不需要z缓冲区。 如果所有对象都是按照前后顺序绘制的,那么每一个较近的对象就会被画在它后面的对象的前面,这样就不需要z-depth比较了。

例如,考虑观察者V在上图中看到的内容, 不管观察方向和视锥体,V是左边的分裂面形成的,所以C、F和G在B,D,E的后面, 和用分裂面C比较,我们发现G在这个平面的对面,所以显示它。 对B平面的测试可以确定E应该在D之前显示,那么从后到前的顺序是G, C,F, A, E, B, D。注意,这个顺序并不能保证一个物体比另一个物体离观众更近。 相反,它提供了一个严格的顺序,一个微小的区别, 例如,多边形F比多边形E更接近v,尽管它在顺序上更靠后。

八叉树(Octree)

八叉树是通过将整个场景包围在一个最小的轴对齐框中来构建的。该过程的其余部分本质是是递归的,并在未满足停止条件时结束。与轴对齐的BSP树一样,这些标准可以包括达到最大递归深度,或者在一个包围盒中获得一定数量的几何本。 如果满足条件,算法将几何体绑定到包围盒并终止递归。 否则,它将包围盒沿着其主轴使用三个平面细分,从而形成八个大小相同的盒子。 每个新盒子都经过测试,并可能再次细分为2 × 2 × 2个更小的盒子。 这在下图的二维空间中进行了说明,其中的数据结构称为四叉树。 四叉树是二维的八叉树,第三个轴被忽略。 在沿着三个轴对数据进行分类没有什么好处的情况下,它们可能很有用。

八叉树可以以与轴对齐的BSP树相同的方式使用,因此可以处理相同类型的查询。 事实上,BSP树可以给出与八叉树相同的空间分区。先x轴的中间,分割,然后两个孩子沿沿y轴中间分割,最后沿z轴中间划分 成8个大小相同的单元, 八叉树的一个效率来源是它不需要存储BSP树结构所需要的信息。 例如,分裂平面的位置是已知的,因此不必明确地描述。 这种更紧凑的存储方案还通过在遍历期间访问更少的内存位置来节省时间。 轴对齐的BSP树仍然更有效,因为获取分裂平面位置所需的额外内存成本和遍历时间可以被更好的平面放置所节省的成本所抵消。 没有全面的最佳效率方案; 它取决于底层几何结构的性质、结构如何被访问的使用模式,以及运行代码的硬件体系结构,等等。

在上面的描述中,对象总是存储在叶节点中。 因此,某些对象必须存储在多个叶节点中。 另一种选择是将对象放置在包含整个对象的最小包围盒中。 例如,图中的星形对象应该放在左边第二个插图的右上方的框中。 这有一个明显的缺点,例如,位于八叉树中心的(小)对象将被放置在最上面(最大)的节点中。 这是不有效的,因为一个微小的物体被包围在包围整个场景的包围盒里。 一种解决方案是拆分对象,但这会引入更多的几何体。 另一种方法是在对象所在的每个叶包围盒中放置一个指向对象的指针,这样会降低效率,并使八叉树编辑更加困难。

场景图 (Scene Graph)

BVHs,BSP树和八叉树都是用基本数据结构,他们的区别在于存储的几何图形。它们也以一种分层的形式存储几何对象,而不是其他任何东西。然而,三维场景远不止几何图形这么简单。动画,可见性和其他元素的控制通常使用场景图来执行,在giTF中称为节点层次结构。这是一个面向用户的树结构,通过纹理,变换,细节层次,渲染状态(例如材质属性),光源和其他任何合适的元素来增强。它由一棵树来表示,这棵树以某种顺序被遍历以渲染场景。例如,一个光源可以放在一个内部节点,这只影响他的子树内容。另一个例子是当一个材质在树中时,材质可以应用到该节点的子树中的所有几何图形,或者可能被子节点的设置覆盖。下图:从某种意义上啊来说,每个图形应用程序都使用某种形式的场景图,即使这个图只是一个带有要显示的子节点的列表的根节点。

动画对象的一种方法是改变树中的内部节点的变换。 场景图实现然后变换该节点的子树的全部内容。 由于变换可以放在任何内部节点中,所以可以进行分层动画。 例如,汽车的轮子可以旋转,汽车作为一个整体可以向前移动。

当多个节点指向同一个子节点时,这种树结构称为有向无环图(DAG)。 无循环的意思是它不能包含任何循环或循环。 有向的意思是,当两个节点由一条边连接时,它们也按照一定的顺序连接,例如从父节点到子节点。 场景图通常是DAG,因为它们允许实例化,例如,当我们想要创建多个对象副本(实例)而不复制其几何形状时。 上图显示了一个示例,其中两个内部节点对它们的子树应用了不同的转换。 使用实例可以节省内存,GPU可以通过API调用快速渲染一个实例的多个副本

当物体在场景中移动时,场景图必须更新。 这可以通过对树结构的递归调用来实现。 变换在从根到叶的过程中被更新。 矩阵在此遍历中相乘并存储在相关节点中。 但是,当变换被更新时,任何附加的BV都是过时的。 因此,BV在从叶向根返回的过程中被更新。 过于松散的树形结构使这些任务变得非常复杂,所以通常会避免使用DAG,或者使用有限形式的DAG,其中只共享叶节点。 有关这个主题的更多信息。

场景图本身可以提供一些计算效率。 场景图中的节点通常有一个边界体,因此与BVH非常相似。 场景图中的叶子存储几何图形。 重要的是要认识到,完全无关的效率方案可以与一个场景图一起使用。 这就是空间化的思想,在这种思想中,用户的场景图被一个单独的数据结构(例如,BSP树或BVH)扩充,为不同的任务创建,如更快的选择对象。 大多数模型所在的叶节点是共享的,因此额外的空间效率结构的成本相对较低。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值