第一次写博客,水平有限,错误之处也请指正~
计算机图形学在于通过计算的方式渲染出模拟自然世界的一张拟真图片,一般来讲最直接的方式就是模拟大量光子在空间中的物理传递过程,但是这样做的运算量极大。。。现在的电脑(一般是指个人计算机)还不能通过对光子的逐一模拟进而生成图像。。
但是可以通过近似方式模拟。主要有辐射度方式的渲染(好像是类比热力学里的平衡方程得到的渲染方式。。这里不太清楚),还有就是类似于上述的模拟光子行为的渲染方式。
由于光路可逆原理,模拟光子行为的方式又可分为正向光线跟踪(光子从光源出发向整个场景传递)和逆向的光线跟踪(从摄影机逐像素发出光线)。传统的光线追踪(raytrace)就是指逆向跟踪。计算机渲染中真实感的体现是借助于所谓的全局光照(GI)算法来实现的,而在GI方面,上述的正向光线跟踪的典型模式是光子贴图(photon mapping,典型代表是vray渲染器),逆向的典型模式是类似于路径追踪(path tracing,典型代表为NVIDIA的Iray渲染器),光子贴图在现在的很多三维建模软件的配套渲染器里已经很常见了,像vray这种成熟的产品已经将photon mapping基本上是做到极致了,光子贴图通过从光源发射一个一个光子与场景交互,然后经过反射,折射等等的过程最终消失在场景后留下的多个“印记”,把这些印记保存下来,光子记录比较密的部位自然就是比较亮的地方,然后从摄影机发射光线,利用最邻近查找去找那些离采样点最近的多个光子进而决定相应像素点的颜色,整个图像的精度取决于发射光子的个数与场景的复杂度。而路径追踪看起来就更暴力一点。。每个像素发射一条光线(比如要渲染一个800x600的图,就得发射48万条光线),每条光线与表面求交后,新的光线的方向取决于表面的材质参数(比如要是理想漫反射,新的方向就是在半球内的均匀采样),新的方向继续追踪,下一轮追踪之前保存一个BRDF,并与上一个BRDF相乘,直到击中了一个发光物体(可想而知原始算法可能会效率比较低。。)这时候这条光线才被视为有效,没击中的话或者超过最大递归深度的话。。那这条光线对应的那个像素就对应黑色。一般来讲,遍历一次后整个图像是很脏的(噪点太多,因为采样光线的方向是随机的,同一个像素的采样光线在不同时刻的采样值都可能不同,但是大量光线在同一像素的采样平均值就基本上对应着正确的最终结果),这时候就需要一次又一次的迭代,每次结果都要与上一次混合后做平均,迭代几千次(甚至要上万次。。。)后得到一张收敛的图片,其实这也就是iray的最基本的工作原理(当然远不止这么简单,人家毕竟是专业开发渲染器的,有很多降噪的算法,效率也很快,配上NV自己做的GPU来加速运算的话效率能快上一个数量级)。path tracing的渲染基本上是通过步进式渲染方式来完成的。
个人还是觉得path tracing实现上比较简单一些,而传统path tracing效率实在是。。有点低,所以后面有很多人对这个基础算法做了改进,比如双向路径追踪(bidirectional path tracing)类似的。
最后附上自己初试path tracing的几张效果图,可以看出噪点确实比较多。。日后还需要做好多学习和工作量去改进这个效率和噪点问题,还有现在只能实现简单参数几何体的渲染,后面还要考虑对复杂几何体mesh的支持
(最后三张图是一个场景分别进行10次迭代,1000次迭代和5000次迭代的图像)