【转载】Uniform Grid , KD-Tree , BVH 性能比较

584 阅读4分钟

转自:Uniform Grid , KD-Tree , BVH 性能比较

Ray Tracing 中,每条光线都需要和场景中所有的图元求交(这里我们假设所有的图元都是三角形)。Brute force 的方法就是一点一点的遍历每个图元,然后找出 与光线交点到光线起始点距离最近 的图元,当然这种方法的算法复杂度是 O(N) 的,对于少量的图元还可以,如果图元数量很多,光线跟踪的过程将非常慢。

事实上,大部分的图元距离光线都是非常远的,只有一小部分的图元有可能与光线相交,所以 没有必要 遍历所有图元。利用空间划分结构,可以快速的把无关三角形去除掉,从而只遍历很小的一部分子集,就可以找到最近的交点。其中比较常用的有 Uniform GridKD-TreeBounding Volume Hierarchy (BVH)。

Uniform Grid

即均匀网格,就是把空间均匀划分,每个图元被分配到与其相交的所有节点中注意 这里一个图元可以被分配到 多个 格子中,而每个格子可能有 多个 图元在其中。这种分割方式的 优势 在于,实现起来非常简单,而且 创建速度是最快的,把图元分配到格子中可以在 O(1) 的时间内搞定。然而,由于在创建过程中,对于空间中图元的分布没有任何的考虑,所以这种分割 算法的遍历效率并不高。对于比较实际的场景而言,效率很可能会不好。比如,如果场景中的 1% 的空间中包含了 90% 的图元,这些图元很可能被分配到很少的几个格子里面。换个角度思考,每个格子会有很多的图元,从而当光线遍历过的时候,需要遍历 90% 的图元,效率是非常低下的。即如果场景中的图元分布不够均匀,均匀网格的遍历效率会有很大的问题。

KD-Tree

K-Dimensional Tree,可以更好的适应空间中的 不均匀分布 的图元。在图元多的地方,KD-Tree 会相对分割细致一些,而图元少的地方,就会分割的粗糙一些。一般来说,KD-Tree 都是基于一种叫做 sah 的模型来分割的。有很多种不同的分割策略,其中在单线程的环境下,创建 KD-Tree 的理论复杂度下限为 O(N*log(N))。由于考虑的场景中的图元分布,KD-Tree 在遍历的过程中,有着很大的性能提升。然而,创建一棵质量较优的 KD-Tree 一般要 很长时间(基于 GPU 的实时 KD-Tree 创建算法已经被提出)。

BVH

层次包围盒。 Uniform GridKD-Tree 都是相对于空间进行划分,然后把图元分配到不同的节点中。而 BVH 换了一种角度,它会划分图元,而不是空间。一个图元在 BVH只可能出现一次,而节点在空间中是可能有 重叠 的。BVHKD-Tree 有很多的相似,但是也有一些特性,BVH 的内存是有上限的,由于图元的数量不会因为划分而增长,所以需要开辟的空间是可以预先计算的,而节点的数量也不会超过 2*N-1(N为图元的数量)。相对于 KD-Tree 而言,BVH创建过程会更廉价一些,但是遍历效率会低一些

最近实现了下三种算法,算法的实现基本是学习 pbrt 的,不过 pbrt 的 KD-Tree 的创建复杂度是 O(N*log(N)) 的,而本文的算法实现是 O(N*log(N)) 的(On building fast kd-Trees for Ray Tracing, and on doing that in O(N log N)

modeluniform-gridkd-treebvh
killeroo78/7551390/8221203/12620
bunny640/63631154/4665733/6428)
dragon608/816661545/602321170/115191

构造时间/射线追踪时间(单位:毫秒)

上面的数据每个只测了一次,并不具有代表性,而且这里 rt 的绝对时间是 没什么实际意义 的,因为角度,光照,材质等都不相同。而空间划分结构的创建时间还是有意义的,可以看到,Uniform-Grid 的创建时间很少,而 KD-Tree 的创建代价是最大的,而效率相对来说高一些。这里需要说明的是,从上面的数据来看,似乎 Uniform-GridBVH 更有优势,但是上面的场景都只有一个模型,空间分布还算均匀,如果场景分布不均匀,Uniform-Grid 的效率会 下降的非常快,而 BVH 不会有太大的影响。

本文简单介绍了下三种空间划分结构的基本特点,列出了一些简单的测试数据。需要实现的朋友,可以去 sourceforge 上下载