很喜欢一首歌的一句歌词“光落在你脸上”,每次听到这一句,我都不自然的觉得下联应该是“有无限种可能”。感叹光线千变万化之余,更神奇的是,所谓的千变万化,其实只有两种可能的无限组合:反射(reflection)和折射(refraction),其中反射又可以分为漫反射(diffuse)和镜面反射(specular)。
上图就是光线示意图,I是射入人眼的光线,L是光源,R和P分别是镜面反射和折射,而漫反射的方向则是一个随机分布的概率。能想象到大家的失望,扯了这么高大上,最后只是一个初中物理的概念。
Phong Model
有了原理,接下来的问题就是如何量化光的强度(intensity)。目前Rasterization中最常用的就是Phong模型,对应的公式如下,其中I(a)是自发光,或者反射周围的环境光;k(d)属于漫反射的部分,强度是物体法线和光源夹角的余弦值;k(s)是镜面反射,强度是上图θ(h)的余弦值:
该模型的具体解释可以参考《Real-Time Rendering》第三版Shading章节。该模型在镜面反射的处理上进行了简化,比如反射来源正好是一处光源,或者正好是一面镜子,这些因素都没有考虑。其次,阴影和折射需要另行计算。
Whitted-Style Ray Tracing
基于Phong模型,Whitted提出了一个新的模型,公式如下:
如下图,该模型对漫反射的处理和Phong一致,但如果物体材质存在镜面反射或折射,也就是S和T的部分,则会创建新的射线来计算对应的强度。
该模型在理论上考虑到反射和折射,自然更能准确的计算光的强度,同时,当射线与物体相交是,也会判断该交点和光源之间是否存在遮盖,用于处理阴影效果。
Distributed ray tracing
在Whitted Ray tracing中都是针对点的采样。这样存在两个问题,第一,可能会遗漏微小物体的特征,第二,无法对面积类的物体进行采样。如下图,我们把光源抽象为一个点,但现实中的光源都是有面积和方向的,如左侧,会出现部分可见部分不可见的情况,所以会有soft shadow的效果。
针对上面这个问题,我们可以增加更多的射线,获取更精确的结果。但有两点,第一,性能上不划算,第二,不知道需要增加多少射线才能满足要求。这就好比很多人认为需要更多的钱才能更幸福是一个意思。
Distributed ray tracing的核心思想就是在等量的射线下,让射线的方向具备一定的随机性,从而高效的模拟渲染结果。本质上就是Monte Carlo integration。比如面积光的可见率,我们并不需要真的计算该点对应光源的可见率,我们只是随机生成一条射线,如果没有遮盖物阻挡,则可见率是100%,再随机生成一条射线,如果这次被阻挡了,可见率下降为50%,因为每次射线都有一定的随机微调,每次更新都会让结果更为准确。这样,我们不断的优化随机分布的概率,只需要尽可能少的射线就能获取比较准确的可见率,进而提高渲染效率,同时,这种精度的提高是叠加的,不需要事先设置采样精度。
在渲染中引入概率,不仅可以提高效率,还能实现一些无法做到的效果。比如我们把像素细化到亚像素级别,这样像素便有了面积,通过随机采样,可以实现反走样的效果;如果把这种随机应用到时间的维度,则可以模拟出Motion Blur的效果;在相机的pinhole中引入随机,可以模拟Depth of field;物体反射方向中采用Cone的随机分布,则可以模拟物体glossy的效果。
Rendering Equation
随着对光照模型的不断优化,最终,我们还是找到了完美的光照模型,我们通常称之为RenderingEquation:
该公式给出了光照强度的完美定义:光的强度取决于自身发光的强度L(E)和其他表面传输到该点并反射到眼睛的强度(积分部分)。
首先,这个公式是可以数学推导,精准无误的,而之前的Phone模型和Whitted Ray Tracing模型都可以认为是该公式的一种约等,比如该公式对应的Phong模型示意如下,考虑了光源抵达x点并反弹到人眼s的光强:
而对应的Whitted模型示意如下,不仅考虑了光源,还考虑了镜面反射S和折射T的积分部分:
有了该理论,我们可以自定义自己的光照模型。采用合理且高效的采样方式,离散化的计算光照强度。
如上图,Ray Tracing中,一条连接光源的射线,还会有反射(漫反射,镜面反射)和折射两条射线,并不断递归,比如限制递归的Depth为8。但很明显,通常第一次的射线贡献的强度最大,依次递减。因此,Ray Tracing会有这样一个问题:越深便会创建越多的射线,而这些射线对最终的强度贡献很小,性价比很低,如左侧。于是,不妨在每次创建新的射线时,我们遵从合理的概率,只随机生成一条新的射线(可能是反射或折射),同时保留和光源连接的射线,如右侧,减少创建射线的次数,形成一条Path,如果场景中存在很多镜面反射和折射材质的物体,这种策略在性能上会有很大的提升,这就是Path Tracing的思想。基于Path Tracing,人们想到了很多variance reduction方式,提高收敛速度。
总结
光线追踪是一种简单且强大的渲染技术,相比Rasterization,性能是该技术的一个瓶颈。采用适合的概率分布,可以更快的模拟渲染效果,因此,从数学的角度,渲染中充满了概率问题。
当然,借助GPU也能极大的提高性能,但Ray Tracing从CPU迁移到GPU,也面临很多的挑战,技术上是否可行,GPU中的性能瓶颈是什么,如何抽象出适合ray tracing的pipeline,这些问题我们有(下)时(一)间(篇)再介绍。