Real-time Environment mapping
环境光照:用一张图记录往任何方向看得到的光照(认为光照距离无限远, 也就是说,场景中的两个物体使用的环境光照是完全相同的,因为光照距离无穷远 )
存储方式:立方体纹理和球形纹理。类似这种处理环境光照的方法被称为IBL(Image-based Lighting),我们需要解决的问题是:给定IBL和一着色点的位置,如何计算该点的着色。方法很简单:解渲染方程。
Split Sum方法
观察渲染方程,由于需要环境光照,自然自发光不需要考虑,同时可见项代表了阴影遮蔽,同样不需要考虑。通过渲染方程可以得知,想要计算着色结果,需要求解光线项和BRDF项。
按照之前路径追踪的做法,要解这个渲染方程需要借助蒙特卡洛积分去进行一个(无偏的)估计,但蒙特卡洛是数值方法,需要大规模的样本数据才能让结果接近真实,因为在实时渲染中,着色器中的采样会很耗时间(但是现在对采样的要求越来越松,但是仍然尽量不采样),所以要避免采样,避免使用蒙特卡洛积分方法。
Split Sum方法的思路是:基于一个观察,如果在积分的过程中,BRDF是glossy的,那么积分限是小区间(覆盖了球面很小部分);如果BRDF是漫反射的,那么意味着积分限是大的,但是非常平滑smooth(值的变化不大)。——>恰好符合积分近似公式的要求,所以可以使用前一节介绍的近似公式进行拆分。
根据积分近似公式,现在的渲染方程变成了:
拆分:因为着色是光照和表面BRDF综合作用得来的,对于每个表面的着色,要逐个考虑光线和表面BRDF比较麻烦,所以把光照项和BRDF拆分考虑。BRDF看作g(x),Li看作f(x),可以把光照项拆出来。发现这时候方程表示的是,平均光照与BRDF共同作用——>可以理解为事先把环境光贴图进行一系列不同大小的平均滤波,以对应不同光泽度的BRDF,对于这些光线,表面BRDF光泽度越低(越漫反射),此BRDF的积分限就有越大,那么就选择更大的滤波核滤波后的环境光贴图(更模糊)对其采样(比如,一个表面的BRDF比较光滑,那么就在清晰的环境光贴图上采样;如果一个表面对应的BRDF比较漫反射,就在模糊的环境光贴图上采样)。
注意:此处的预滤波不是卷积滤波,而是对于球面环境光贴图进行立体角滤波,不同的滤波核就是选不同的立体角。
因为滤波对象是环境贴图,所以这个滤波操作是可以在渲染之前就完成的,即所谓的预滤波。我们可以在渲染前对环境贴图应用不同大小的滤波核进行多级滤波,预生成一些环境光贴图。渲染着色时,依据表面的BRDF确定模糊等级,使用三线性插值取得两个滤波等级之间的结果。这样采样只需查询一次即可得出结果。
深入理解:为什么使用预滤波?
原先的光线着色计算过程是,给定入射光线,根据该表面的BRDF(的光滑与否等等参数)对于此入射光线的出射光的积分限进行积分(加权平均),得出最终着色结果。(采样需要对积分限内的反射查询多次,然后积分)
经过预滤波后的光线着色计算过程:先对环境光贴图进行不同大小核的滤波,选取入射光线的镜面反射光线方向,查询对应滤波核大小的环境光贴图的值。(采样只需要查询一次即可)
注意:因为漫反射每个方向都一样,所以漫反射的查询方向规定为法线方向。
(针对不同种类的BRDF,滤波方法不同,因为BRDF的积分限不同,但大概把BRDF积分限都像高斯分布)
以上,解决了光线项的求解问题,渲染方程还剩BRDF项没有解决,我们希望能求解后项BRDF同时避免计算积分。
求解BRDF项主要思想:依旧是预计算。但考虑到微表面的BRDF涉及菲涅尔项和法线分布等至少五维(观察角度、基础反射率RGB、法线分布粗糙度)的数据处理,直接暴力预计算肯定是不可取的,只好通过一些近似来降低维度,以此来简化预计算。
根据Schlick估计,它认为不同材质的菲涅尔项可以用两个参数构成,基础反射率和入射角
。
法线分布:是一个一维分布:有两个变量,
注意:在实时渲染中,入射角(入射光和法线夹角)、出射角(出射光和法线夹角)以及半角(入射光和反射光夹角的半角,或者说入射光和出射光各自与半程向量的夹角)度数差别不大,可以近似的看成一个角。
到这里,我们只需要三个参数:观察角度、粗糙度、基础反射率(假设为灰度值)
三个参数的预计算依然不方便,继续将参数空间降维。
在渲染方程中,将菲涅尔函数带入,提出
至此,通过Split Sum计算环境光映射结束。注意IBL适用于任何场景,但当光源和你的物体有确定的距离的时候,就不能再这么使用了(因为IBL假设光源无限远)。
环境光照下物体的阴影
前文介绍了不考虑可视项的环境光照下渲染方程的解法。那么现在考虑可视项,考虑遮挡与阴影。
环境光照下物体的阴影:很难得到
因为:1. 环境光照可以认为是很多光源的问题(因为环境光照视为四面八方来的光线):所以阴影图是随光源数量线性增加的。2.环境光的可见性问题可能非常难,导致可见性不一定能简单地从环境光中分离(因为要想把可见性V分离,想要分离V需要满足后面的函数积分限小+光滑,那么后面的函数是L*BRDF,首先L的积分限很大,其次BRDF可能不smooth,所以无法把V分离),由于不知道遮挡情况,所以对环境光贴图做重要性采样很困难。
用环境光遮蔽的话,环境光遮蔽的前提是:把整个环境光假设为了constant environment lighting,也就是说全白或全黑全灰。结合环境光贴图就会造成比较不准确的效果。
工业界的方法:选取最大的光源(如太阳)生成一个或多几个的阴影。
相关工作:imperfect shadow maps(全局光照阴影), Light cuts(离线渲染中,将反射物作为小光源,通过归类近似得到多光源照亮一个着色点的结果), RTRT(Real time ray tracing,最有希望的), Percomputed radiance transfer(PRT,能得到比较好的环境光下的阴影,下文讲)
需要的一些数学知识
傅里叶级数展开
任何一个周期函数,都可以表示为一系列sin和cos函数的线性组合加一个常数项的形式,对应到信号处理就是不同频率的波的叠加,或者是对数据的一种有损压缩,通过这么处理可以将图像从时域(空间域)变换到频域。
基函数
一系列函数,它们的组合可以描述其他函数。如下公式,
滤波
空间域的滤波操作通常使用卷积进行,而在频域的滤波则是两个频率图的乘积,如原图*卷积核频谱=滤波后的频域图,经过逆傅里叶变换后可以得到滤波后的原图。数学公式就是:
在频域上两个信号相乘,最终输出的频率取决于两个信号的最低频率。我们把两个函数相乘后积分的操作认为是滤波操作,相乘后积分的结果的频率是由两个函数更低频的一方决定的。
球谐函数
是定义在球面坐标系中的一系列二维基函数,每个基函数都可以通过勒让德多项式写出,可以表示任何球面上的二维信息,而对于球面环境光贴图,可以把它认为成一个球面上的二维函数,我们要用球谐函数来恢复它。
根据
那么想要使用球谐函数来描述某个函数
求出对应系数
计算球谐函数系数的过程称为投影,计算方法是对该基函数与原函数的乘积求积分,公式如下:
求球谐函数的积分很难求,所以需要预计算出相应系数。
球谐函数的性质:
- 正交性,每个基函数相互正交
- 能将任意函数投影到球谐函数,也可以从球谐函数重建出这个函数
- 支持旋转:基函数旋转后,能够被同阶基函数线性组合得到。(这意味着:旋转光照后,能立即得到新的基函数系数)
- 更多地倾向于描述低频信息
Precomputed Radiance Transform(PRT,预计算辐射传输)
我们需要将可见性项考虑进来。这时候渲染方程的形式如下所示:
我们可以将环境光照、可见度、BRDF看成是三个球面函数,最直观的着色方法就是对这三个纹理进行立体角采样,需要采样多次,计算困难。
所以我们引入PRT,PRT的思路是:假设渲染过程中可见关系(可见关系得到方式:预计算,通过光线追踪等方法,预计算部分这里不考虑性能)、BRDF不变,只有光照会发生变化(旋转或更换光源,旋转可以通过球谐函数性质计算,更换光源只需多预计算几个光源即可)。将BRDF与可见项统一视作光线传输项,那么渲染方程可以看作光照项与光线传输项的积分。公式有:
由于光线传输项是不变的,可以被预计算出来,我们只需将光照项用球谐函数表示出来,于是这两部分都可以被预计算出来。
将PRT分两种情况来说:
一、Diffuse的情况下
由于是DiffuseBRDF, BRDF可以认为是个常数
最终渲染方程为:
只需要将光照项在球谐函数上投影的系数
另一种理解思路
将光照项与光照传播项同时写作球谐函数的形式。
于是渲染方程可以写作:
由于球谐函数基函数的正交性,积分项只有0和1两个值,也就是只有对于时,才有结果,最终结果和上文结果一致。
Diffuse PRT总结:只需要进行预计算,计算并保存每个点的两个向量,就可以把着色过程转化为这两个向量的点乘,这个性能提升是巨大的。对于每一个着色点的可见性如何计算,最简单的方法是从着色点出发,向四周发射光线,因为是预计算,所以时间可以认为无限。
二、Glossy的情况下
Glossy的BRDF我们不能把它假设为常数,它是与观察方向相关的,于是BRDF项是关于入射光线和出射光线
的函数
,从而光线传播项也是一个关于入射光线
和出射光线
的函数
。
这时不能将光线传播项投影到光线项的球谐函数基函数上了,因为二者参数空间不一致,光线传播项多了一个观察方向的变量,公式如下所示。也就是说,根据观察方向的不同,着色结果都会不同,这也很符合GlossyBRDF的特点。
将投影到球谐函数上,
,得到
其中
为光照投影的基函数数量,
为视角投影的基函数数量。
从Diffuse情况的两个向量点乘变成了一个向量与一个矩阵点乘,最终结果为一个关于出射光的向量,对不同出射光方向
,在向量中取不同的值。
Glossy的BRDF根据观察角度的不同,分别对应一组基函数光线传播系数,光线传播预计算的结果就是不同观察角度的基函数系数,组成了一个矩阵,最终计算渲染结果,就是光照项的系数与矩阵项的乘积,根据不同视角排列的向量,不同视角在向量中取不同的值 需要每个顶点储存一个向量和一个矩阵,在正常情况下,人们会用到3、4、5阶的球谐函数来还原光照,可以看出,由于乘以的是矩阵,glossy相比diffuse会尤其的消耗性能。
三、多次反射的间接光照计算
在实时渲染PRT时,光线反射的复杂度是不受影响的,哪怕光线反射了多次,因为PRT的思路把渲染方程拆分为了光照项和光线传播项,光线传播的复杂度是预计算的部分,与实时渲染速率无关。
对于任意种类的BRDF,尤其是同一物体上不同位置的BRDF不同的情况,此时对于每个着色点都要预计算PRT,那么PRT多了位置的两个维度。
PRT的局限
球谐函数基本上只能用于描述低频的部分,对于高频信息多的材质,球谐函数很需要很高阶才能重建。由于方法是通过预计算,这也要求了场景不能动,也不能动态改变材质。
选用球谐函数PRT的原因:能够准确算出环境光照下,甚至多次光线反射下,整个场景的渲染结果,甚至能够考虑遮蔽问题。
其他种类的基函数
Wavelet小波基函数:要用到的是二维的小波——Haar Wavelet:定义在块上,而不是球面上,将函数投影到小波上,是一种非线性的·全频率的表示。将一个正方形面的纹理,经过小波函数,保留了高频信息在右上右下和左下,左上保留了低频信息(右上右下和左下的投影中,为零的信息);将左上继续小波投影,不断迭代。这样能通过小波函数同时保留高频和低频的信息。
虽然小波函数解决了球谐函数的频率限制,但它同时也有缺陷,比如没有SH的旋转不变性,所以导致使用小波函数就无法做到像之前那样随意转动灯光,每次旋转都必须重新进行预计算。