作者:faihiwang | 来源:互联网 | 2023-09-25 16:32
想来,GI的学习也大概有一个月了,不敢说有多深入的理解,至少有了一个感性的了解。记得大二的时候一直很惊叹于3DMAX渲染的图片为什么会有这么真实的效果,当时也没有深究,现在再回过头来看3D
想来,GI的学习也大概有一个月了,不敢说有多深入的理解,至少有了一个感性的了解。记得大二的时候一直很惊叹于3DMAX渲染的图片为什么会有这么真实的效果,当时也没有深究,现在再回过头来看3DMAX的普通天光渲染,感觉很可能是裸的Final Gathering或者直接AO实现。只是遗憾的是当时只忙着学习怎么操作3DMAX,对其中的道理却一点也不想深究。闲话少说,先来说说GI(Global Illumination)究竟是什么吧。
还记得光线跟踪(Raytrace)算法么,在它提出之前的光照算法几乎是完全的局部光照算法,以phong着色为例,在不考虑光源光强衰减的情况下物体表面某点的光亮度直接与该点到光源的向量与该点表面法向量夹角余弦值成正比,这一点也很好理解,比如相同的一个平面,其表面朝向和光源方向越正,亮度越高,相反则越暗。当然phong还有可以带镜面反射效果,若光线射到物体表面经过反射后刚好在视线周围的一个范围内,表面的这个点就可以带有高光。另外在所有光线照射不到的地方用一个环境光统一表示它们的亮度。这样,局部光照模型最主要考虑的三种光照参数就是:diffuse(漫反射),specular(镜面反射),ambient(环境光)。这里要着重讨论一下ambient,因为它是后面GI将要解决的关键问题之一。环境光亦可以理解为背景光,它是指由于场景中各个物体表面反射光集合起来所产生的一种各向同性的背景光,它使并不直接暴露在光源下的表面仍然是可见的。
传统的光线跟踪算法基本上也是使用的这三个参数,但是它是一个递归的过程,当射线击中镜面物体或者透明物体的时候,会产生第二根(甚至很多根)射线,递归求解这些射线击中物体的颜色值,可以轻松模拟镜面或者透明物体的效果,如下图:
可以看出在单光源的条件下,同一个物体上所有光源不能直接照射到的地方都是一个颜色(取决于其环境光的设置),这样显然是不真实的。照成这种原因的根本在于光线跟踪算法的射线只在击中镜面或者透明物体的时候才产生子射线,而在击中漫反射表面的时候其跟踪就停止了。然而现实生活中,光在击中漫反射表面的时候仍然会反弹,由于是朝四面八方反弹,所以这个反弹效果并没有镜面反射的效果那么明显。这样导致的结果就是传统光线跟踪算法不能表现诸如颜色辉映(Color bleeding),焦散(caustic)等效果。
接下来就是全局光照登场了,它要解决的核心问题就是如何很好地表现物体间的相互反射问题,最直接的问题就是如何找到一种更合理的方式来取代局部光照中的ambient(环境光),它实际上是各个物体表面的光的互相反射的结果。全局光照有多种实现方法,例如辐射度、光线追踪、环境光遮蔽(ambient occlusion)、光子贴图、Light Probe等。当光从光源被发射出来后,碰到障碍物就反射和折射,经过无数次的反射和折射,物体表面和角落都会有光感,像真实的自然光。一种简单且无偏的全局光照求解办法是Path-tracing,它可以看做raytrace的扩展,即在射线击中漫反射表面时也产生子射线,但这里就有一个问题了,因为漫反射表面的反射方向是四面八方的,没有一个固定的方向,因而仅仅只产生一条子射线显然是不行的。Path-tracing的做法是在第一次击中表面时产生大量的射线,然后后面每次只产生一条子射线进行递归。在击中光源之前颜色值为0,直到击中光源之后才开始有了非零的颜色值。这样每条射线对于这个点来说都是一个糟糕的采样值(bad sample),但是在大量这样的采样结果平均起来得到的结果却是正确的。注意标准的Path-tracing求解是无偏的(一些其他的经典方法比如photon mapping是有偏的),虽然其方差很大,为了保证其无偏性,在其递归终止条件中,一般使用类似"俄罗斯轮盘赌"的方式,而不是类似之前raytrace中使用的递归次数上限。理论上当采样次数足够大的时候,Path-tracing得到的结果可以看起来相当真实,但是其耗时确实很成问题。下面附一张Path-tracing的结果作为对照,由于还没有时间做GPU的移植,噪点比较严重:
可以看出使用全局照明的算法得到的结果比传统raytrace的结果明显更加真实。
12.1补充:
1.OpenMp优化:介于path-tracing算法天生的并行性,在CPU层面上,还可以对其进行并行优化,提高速度。
2.层次采样:之前的算法中在射线第一次击中漫反射表面时的采样是纯随机采样,这样的采样结果方差有可能非常凌乱,导致算法收敛速度慢,因此噪点比较明显。分层采样是先将总体的单位按照某种特征分为若干层,再从每一层进行纯随机采样。一般情况下分层采样得到的样本的精细度高于纯随机采样,故而可以有效地降低算法的方差(并不是绝对的)。下图解释了二维平面上的分层采样:
在此算法中,可以将目标点正法向量一侧的半球面均分为N*M个区域,然后再在这些区域中各采样一个点。这样,得到的图像噪点减少了: