我们说这个光线追踪效果虽然好但是慢,你想如果这个场景有1000万三角形组成,那我每个像素都发射光线和每个三角形都计算一次这个光照,那计算量还得了啊
目录
轴对⻬包围盒 Axis-Aligned Bounding Box (AABB)
Bounding Volume Hierarchy (BVH)
包围盒
对于下面这个壶,我可以用一个框把它框起来,如果光线和这个框没有交点,那是不是就不会和这个壶有任何的交点,那是不是这一块我都不用算了,基本思想就是这个Bounding Volumes,叫包围盒
轴对⻬包围盒 Axis-Aligned Bounding Box (AABB)
实际应用中我们用这个长方体,叫这个Axis-Aligned Bounding Box (AABB),叫轴对⻬包围盒,就是它由三对平行的平面确定的长方体
那具体怎么做呢,我们先从这个二维的出发,我把这长方体三对面拿俩对面出来,我先算这个竖的,可以计算出光线进入平面的时候tmin和出去平面的时间tmax是不是,然后我再算横的,同样可以计算出一个tmin和一个tmax,我这里先不管这个算出的t的正负,然后我要确定这个光线进入这个框起来的范围内的真正的进入时间是不是两个tmin的较大值,然后真正离开时间是这两个tmax的较小值
同理到三维,我去计算每对面的tmin和tmax出来,然后取最大的tmin和最小的tmax就是光线进入和离开的时间对不对
如果离开的时间小于0,那说明这个包围盒在光线的后面
如果离开的时间大于等于0,但是进入的时间小于0,那说明这个光线是在包围盒里面发出来的
我们这里为什么要用上轴对称的面呢,这是因为这样计算量小一些,当这个光线和某些面垂直或者平行的时候,计算这个t只需要用到三维向量中的一个分量进行计算即可
下面就到lecture14讲如何通过这个aabb加速光线追踪
均匀网格 Uniform grids
先用一个大的包围盒将物体包起来,然后生成网格,记录下每个物体覆盖的网格
然后沿着光线的方向去看和光线相加的格子里面有没有物体,如果有的话就计算和物体的交点
基本思路就是这样,但实际中呢这个格子的大小影响比较大,格子太大,那基本上都要和每个物体计算交点,等于没做,格子太小 ,那本身就要计算很多多余的格子,在摸索过程中可能可以找到一个格子的数量可能效果比较好
这个均匀网格适用于场景分布比较均匀的,对于物体差异比较大的场景效果不好
空间划分 Spatial partitions
均匀网格的缺点就是均匀对吧,那不均匀的划分是不是会好一点,这里就讲了三种空间划分
首先是这个八叉树,它在二维里面就相当于四叉树,怎么做呢,就是我每次把场景分成四份,然后递归的继续分下去,那什么时候停下了呢,就是当这次的划分使得一个格子里面三角形数量比较少的时候我就停下来
然后是这个后面要详细讲解的KD树,就是二叉树,每次把场景分成两部分,每次都从不同的维度划分,比如这次沿xy平面,下次沿yz平面,再下次沿zx平面,但是都是这种正交方向的
然后同样二分的是这个BSP树,也是每次分两部分,但是不同的是它这个方向是斜的
KD-Tree
怎么建立这个KD树呢,其实思路也很清晰,就是每次将这个场景沿着一个轴平面分成两部分,这就产生两个子节点,然后继续递归下去划分,然后直到这个节点内的物体数量比较少,并且所有的物体都挂在这个叶子节点上
然后就是和均匀网格一样的做法,看光线路径上和哪些块相交,再继续看块内的物体有没有和光线相交,找出最近的相交点
但是这个KD树同样有问题哈,就是我一个物体可能在多个块上,这就引出下面的BVH
Bounding Volume Hierarchy (BVH)
基本思路和KD树差不多,不同的是我先把物体分成两堆,然后去求两堆物体的包围盒,那这样形成的两个节点就不会包含同一个物体了
那这里涉及到怎么样去将物体分成两堆,可以从某一个维度去划分,还可以选择最长的一条然后把它分开变短,还有就是选择一个位置在中间的物体为界,这里可以用快速选择来找出中间值
然后同样是将物体挂在叶子节点上
做法和之前的一样,如果光线和框没有交点就直接返回,如果是和叶子节点框有交点就计算里面所有物体和光线的交点,返回最近的,不然就继续递归计算和两个子节点框