一、基于图像的光照(Image based lighting, IBL)
只要了解了下面这些,就很容易理解基于图像的光照了:
在 PBR 的前两章,光照考虑的都是直接光源,这一章考虑的就是间接光,或者说是环境光
一样是和环境立方体贴图有关,基于图像的光照就是将环境立方体贴图的每一个纹理像素作为光源,并在前面渲染方程中直接使用它,以实现物体融入环境的效果
换句话说,IBL 最终的目的就是对于确定的反射微表面点 ,求出
的近似值
其中 为半球上任意光源方向 在 点的辐射率,这个值来源于向量 对环境立方体贴图的采样结果
在计算上和前面两张计算定点光源最大的区别就是:前者只需要考虑单一方向也就是光源方向,而现在要考虑整个球面上所有的方向,得到真正的积分结果
二、环境立方体贴图
先考虑作为输入的环境立方体贴图,这也是第一步
在这一章中就曾经尝试生成过环境立方体贴图,以场景中任意点 为中心生成的环境立方体贴图当然都是不同的,这样就会出现两个问题:
- 场景中的每一个物体都需要生成对应的环境立方体贴图,这个不太现实,更何况每个物体又不是以“点”存在的
- 如果场景中有多个动态物体,如何计算光线在多个物体表面的多次反射结果
一个比较幸运的是,这两个问题在一章中都先不考虑,我们就只考虑固定点 的光照情况就可以了,这两个问题可以后面去解决(对于问题①,使用反射探针技术,对于问题②,上光线追踪吧)
2.1 应用 HDR 的立方体贴图
如果固定了点 ,那么我们就只需要考虑唯一的一张立方体贴图,但由于 PBR 的大部分输入基于实际物理属性和测量,因此为入射光值找到其物理等效值非常重要
之前应用的立方体贴图都是以纹理存储的,颜色范围为 [0, 1],也就是 LDR,这样的纹理用于视觉输出还可以,但是用于物理输入参数就非常不科学了(想想灯泡和太阳都一个亮度 1.0),因此这次所需要的环境立方体纹理最好是要考虑了 HDR 的
这涉及到一个全新的文件格式:.hdr 文件,它存储了一张完整的立方体贴图,所有六个面数据都是浮点数。和其它图片文件格式一样,它也是用 RGBA 32位信息存储的每一像素,只不过它的 alpha 通道存放的是指数(尽管这确实会导致精度损失,但是确实有效率)
- .hdr 文件需要有对应的解析程序,以将每种颜色重新转换为它们的浮点数等效值
- 除此之外还有一种文件格式为 .exr,原理和 .hdr 文件类似,都可以用于存储 HDR 纹理
三、漫反射项预计算
对于反射方程:
先考虑它的漫反射项,常数部分很简单可以先拿掉,这样目的就成了先计算 这一部分
3.1 卷积结果
计算积分最简单的一个方法就是暴力枚举所有可能的 求出它们的结果 ,最后求个平均就可以,但是 很明显有无数个,因此这样只能退而求其次:①通过对半球 上的大量方向进行离散采样,对这些采样的结果求出其辐射度取平均值,以作为所有 采样的平均结果(采样次数越多结果越精确)
还有一个难点,上述的微分单元是一个个无穷小的立体角,也就是下图:
好在,②立体角可以使用倾斜角 和航向角 来表示,就可以得到:
其中 来源于 ,当单位向量 与单位法线 重叠时,。又由于当采样区域朝中心顶部会聚时半球的离散采样区域变小,为了平衡较小的区域贡献度,需要使用 来权衡区域贡献度
结合①和②,就可以得到一个我们可以去计算的离散版本,也就是黎曼和公式
最后当然不要忘记常数项 ,对于折射系数 一般是由菲涅尔项得出的,而由于环境光来自半球内围绕法线 的所有方向,因此没有一个确定的半向量来计算菲涅耳效应,为了模拟菲涅耳效应,这儿可以用法线和视线之间的夹角来计算菲涅耳系数
好了大功告成,接下来就是考验代码功底,由于这是理论章所以就不上代码了,后面有机会的话会有实践的文章
3.2 辐照度图
如上对于任意采样方向(观察方向),都可以得到其近似辐照度 ,又由于观察点 确定, 值也是不会变的,因此我们可以对其进行预计算,并将结果保存在另一张立方体贴图中,这就是辐照度(irradiance)图的由来
参考资料: