观察发现,只需要3个重心坐标的两个,由于在三角形内部,它们相加的和老是1。这就使得在一个单独的RGBA纹理中存储交点记实是可行的,并且它的维度同其它两个光线纹理的维度相同。
Moller和Trumbore提出了一个高效的光线一三角形求交算法,使用这个算法,并利用CPU在向量计算上的上风来入行求交计算。下面列出了求交的代码,这个代码也铺示了如何利用向量指令来入步效率。
当所有的原始光线都已经计算出了相交的状态的时候,就能够查询着色过程所需要的表面法线和材质的信息。每一个击中记实都存储了一个指向材质纹理的索引,这个材质纹理包含了三角形的法线,材质颜色以及类型。三个顶点的法线根据击中记实的中央坐标入行了插值。终极的颜色能够按(N-L)C入行计算,此处Ⅳ是法线,L是光源的方向,G是三角形的颜色。
现在根据击中的三角形所具有的材质的类型(漫反射材质,或者镜面反射材质),需要产生二次光线,以此来计算暗影和反射。
1)假如一条光线射出场景之外,像素就被赋予全局的背景颜色。
2)假如一条光线击中了一个漫反射材质表面,就发射一条暗暗射线( shdow ray)。这些光线的起始点在击中点,方向为从击中点指向光源。
3)假如一条光线击中了一个镜面反射材质表面。就发射一条镜面反射光线。镜面发射光线的起始点也在击中点,但是它的方向是在击中点处关于进射光线和插值后的法线对称的方向。一个真正的Whitted类型的光线跟踪器也支持透明材质,从而能够产生折射光线。但因为主要是研究加速结构,所以在本文的实现中,没有考虑折射光线。
4)假如暗影光线击中了某个几何体,这就说明在光源和击中点之间,存在某个几何体,所以这个像素就应该是玄色(处于暗影中)。当跟踪暗影光线的时候,不关心最近的那个击中点,更加关心的是是否存在这样的击中点。因此,当有一个交点被发现,就可以休止整个求交过程,从而加速算法的处理过程。在本文的实现中,以相同的方式跟踪暗影光线和反射光线,因此,就没有使用到这个优化策略。
已经对每一个像素产生了准确二次光线,假如需要,就能够执行另外一趟遍历/求交过程,对上述的二次光线入行跟踪。每一次调用着色程序就能够对每一个像素返归一个颜色值和一条新的光线。着色内核也可以将前一次着色程序的输出当作本次着色程序的输进。这就使得能够在跟踪连续的光线的时候合并这些连续的镜面反射的颜色。
同Carr等人的程序不同,本文所采用的程序不存在浮点精度太低的题目,由于Ceforce 7300在整个管线中支持真正的32位浮点操纵。
3.加速结构的实现和比较
3.1平均栅格
平均栅格是第一个在GPU上实现的加速结构。Purcell给出了良多选择平均栅格作为加速结构的理由,但是Purcell没有具体的说明为什么平均网格对于硬件实现而言比其它的加速结构要更加的简朴。当在探讨了平均栅格的一些主要特性的时候,更加清楚的知道了平均栅格为什么会成为一个好的GPU机速结构。
首先,只用使用简朴的算术运算,就能够对于每个体素的遍历在常量时间能被定位和存取。这就消除了对树的遍历的需要,以及重复的纹理查找工作,而纹理查找是相称耗时的。
其次,体素的遍历是通过递增算术运算来完成的。这就消除了对堆栈的需要,使得我们能够从光线的起始点开始,以间隔递增的顺序访问体素成为可能。
再其次,因为对于体素的访问是沿着光线,以间隔递增的方式遍历的,所以,一旦在一个被访问的体素中报道发现有一个交点,就可以休止这条光线对体素的遍历过程,从而入步整个遍历过程的速度。
最后,用于遍历的代码非常适适用向量编写,而向量形式的编码风格又非常适合GPU的指令集。
然而,平均栅格的缺点就是因为它是空间细分结构的一种特殊情况,多个体素可能包含相同三角形的多个引用。因为无法使用mailbox技术,这就意味着需要对于相同的光线和三角形之间入行不止一次的相交测试。