【遍历阶段】git
4)△x和△y谁大,谁就做为插值的主序方向。意味着每次插值都是朝这个方向行进一步。好比△x大,那么假设当前在格子(xi, yi)处,决定下一个格子时,因为在x方向是主序方向,因此朝x方向行进一步获得xi+1。剩下的就是决定y方向上究竟是yi呢仍是yi+1呢。
web
5)究竟是yi仍是yi+1,要看根据y = m(xi+1) + b计算出真实的y等于多少。这时的y计算出来的是浮点数,根据float2Int的一些规则,转换成对应的整形而后找到对应的格子。float2Int的转换规则要看具体状况,四舍五入仍是直接截取,看效果吧。算法
6)重复4)-5)步架构
DDA算法直接了当,简单易懂。不过它的计算过程当中涉及到许多浮点数运算,这在当今的CPU设计架构中运算成本较大,也可视为其运算复杂度较高。下面的Bresenham line's algorithm就是对其的一种改进。测试
- Bresenham line's algorithm - spa
Bresenham line's algorithm 是DDA的一种改进算法。它与DDA相比有质量和效率的两点改进:设计
1)质量方面的改进。 好比仍是以△x为主序方向行进时,决定下一个点是落在yi仍是yi+1,不只仅考虑真实计算出来的y等于多少,还要考虑这个y值是离yi更近仍是离yi+1更近。谁近就画在谁的格子里。这一点显然比DDA中思考问题的方式更加make sense。
orm
2)效率方面的改进。根据上一点的判断准则,再加上一系列的递归推导,最后简化到只存在整形的加减运算以及比较操做。这在当今CPU的架构中运算成本相对来讲很是便宜,所以效率更高。具体的推导细节,参见这篇 DERIVATION OF THE BRESENHAM’S LINE ALGORITHM递归
- Voxel Traversal used in the Grid-Accelerator in PBRT -ci
我正在看pbrt的第4章。这章主要讲了有关场景管理组织的一些技术,目的是为了提升射线相交测试(ray intersection tests)的效率。主要的手段有三种,Grid-Based, BVH 和 KD-Tree。目前正看到第一种,Grid-Based,基于网格的场景管理技术 。
基于网格的场景管理方法,至关于把整个场景看做是一个大的bouding box,而后对这个box所在的空间分别在三个维度上划分红一格一格的。而后将场景中的primitives与各个发生overlap的格子”关联“起来。接着,从射线的方位出发,遍历(traverse)这个网格系统,对于与射线发生相交的格子,再在里面遍历与之关联的全部primitives,对遍历到的每一个primitive都作一次相交测试。固然这当中的细节还有不少,就不赘述了。总之这种算法的思想能够描述为”分而治之“。经过每一个格子的空间管理与之有关的primitives,测试某个格子的时候就没必要考虑其余格子里的primitives,从而能够有效降解其遍历场景的复杂度。
这里,我想强调下射线是如何遍历这个网格系统的。其方法也是DDA算法的一种改进,书中说很是像Bresenham line's algorithm。但我仔细观察了一下,和Bresenham的算法仍是不同的。这里的关键是利用的是射线的参数(parametric)方程,那个参数t(做为沿着射线方向偏离起点的距离)是很重要的。当决定下一点到底是朝x方向,y方向仍是z方向步进时,要看这条射线”最早打到哪一个方向的下一格子的边界“。哪一个方向的边界先被打到,就朝哪一个方向步进一次。这样一来,这种算法就不是依靠决定”哪一个方向是主序“的思路进行的了,每次判断步进时三个方向皆有可能步进。这点与经典的DDA(包括Bresenham)算法都很是不一样。
我知道我没说清楚,刚才在网上粗略找了找,发现这篇应该才是pbrt中使用的算法:A Fast Voxel Traversal Algorithm for Ray Tracing。(我没细看,大致以为差不了)。欢迎指正校对勘误拍砖头,谢谢。