参考课程:
https://www.bilibili.com/video/BV1X7411F744?p=16
一、蒙特卡洛积分 Monte Carlo Integration
1.Why
蒙特卡洛积分方法是为了算那些计算起来比较困难的定积分(解析式很难写或者写不出),它提供了一种数值的方法可以直接算出值。
黎曼积分(Riemann Integral),也就是所说的正常积分、定积分。
2.What&How
举个简易的例子,我们可以在定义域内随意取一个样本,然后得到对应的f(x)的值,那么整个函数的积分就是f(x)。我们也可以取多个样本,然后把它们的值均起来,整个函数的积分就是这个结果。
蒙特卡洛积分正式的定义方式为,为了计算一个定积分,用一种pdf在定义域采样。我们看一个用均匀分布采样的例子
蒙特卡洛积分可以算任何的积分,它只需要知道采样的pdf是多少就可以算积分。当然更多的采样会更准确,并且在哪里采样就在哪里积分。
二、Whitted-Style Ray Tracing的问题
我们已经学过了Whitted-Style Ray Tracing,它会在镜面进行反射,并在漫反射表面停止。
whitted-style 光线追踪:比较早的光线追踪技术,从观察点对每个像素打出一条射线,计算该光线与物体相交后出射光线与光源的关系(主光线以及经过多个物体反射的副光线)后,用BlinnPhong等模型进行着色
但是这样是不太对的,我们可以用Path Tracing的方法做出更好的效果。
1.问题一
Whitted-Style Ray Tracing无法做Glossy的材质(光滑,但不完全光滑),不能说光线打到Glossy的材质上也沿着Specular的方向走,即镜面反射是不对的。
2.问题二
Whitted-Style Ray Tracing不考虑漫反射的效果,但是实际上漫反射表面和漫反射表面之间还是会有作用的,比如color bleeding。下图的直接光照与全局光照的对比可以看出效果
- 屋顶的光源是照不到光源旁边的天花板的,但漫反射实际上能照亮
- 红墙旁边的立方体不应该是黑的,漫反射会把它变成稍微有点红
三、求解渲染方程 A Simple Monte Carlo Solution
我们考虑一个简单场景,这个场景有一个大的面光源,有一个着色点,有其他物体可能挡住光,还有观测方向。我们先计算这个点的直接光照:
我们忽略发光项,这个着色点的最后被我们看到的光,就是四面八方来的光和BRDF作用之后反射到我们的观察方向上,这就是个半球上的积分,我们使用蒙特卡洛的方法来解它
我们考虑着色点为P点,先用简单的均匀采样的方法(半球的面积是2π,概率密度函数也就为1/2π)
于是我们可以用蒙特卡洛积分计算直接光照
用伪代码表示,先选N个方向,对于每个方向打光,如果打到了光源(这里是和推导逆向),就累加计算
直接光照好做,但是我们还要引入间接光照才能更真实。如图光源经过Q到P到眼睛,我们希望知道从Q到P有多少,又是从P看Q,其实也就相当于眼睛在P,看Q的直接光照。这里是类似递归的思路:
我们用简单直观的方法在伪代码中加上一段,看它有没有光线打到物体所在的Q,进行递归来求间接光照,但是这样行不通
1.问题一
按照上面的方式做路径追踪不行,一个问题是因为光线数目以指数的数量级上升。
那么N为几的时候,指数才不会爆炸呢,那么只有N为1,即每个着色点只有一条光线。当然,我们也知道N为1是个误差很大的结果,怎么解决是后话,暂且搁置。到此为止,我们用N为1做蒙特卡洛积分,这也就是路径追踪,N不为1就是分布式光线追踪。
之前说到N为1误差大,这没问题,因为这只是一个路径,我们可以在一个像素中可以有很多路径,这些所有的路径都会穿过这个像素。像素最后的颜色是什么要看这些路径的Radiance求平均,所以我们只要有足够多的Path就可以了。
像素内取N个位置,对于每个位置,形成光线,计算着色,随机产生N个路径其实也是蒙特卡洛积分。
2.问题二
递归问题,这个递归没有终止条件。但是在光线弹射的现实世界中,光线是不会停下来,因为限制次数会损失能量,比如下面三次和十七次弹射的对比图,明显有亮度差异。那我们应该怎么解决呢?我们引入俄罗斯轮盘赌的概念
我们用类似算伯努利分布期望的方法来算能量。我们期望的结果还是 L o,也就是轮盘赌的期望依然是原来的能量结果。也就是 P × ? + ( 1 − P ) × ? ? = L o P×?+(1-P)×??=L_o P×?+(1−P)×??=L o。
我们巧妙的让P的概率得到能量是 L o / P,1-P的概率得到的能量是0,此时刚好要求。这样未必准确,但期望值是正确的。
四、优化
现在我们得到了一个正确的Path Tracing的方法。左边用较低的采样率,跑得快但是效果差;右边用高采样率,跑得慢但是效果好,但是效率不高,我们想要在低采样率下也效果好。
问题出在哪里呢?光源有时候有大的有小的。这样的话,之前的方法中,着色点往外是均匀采样,打光线出去的时候,很多光线都被浪费掉了,真正能打到光源的很少。如下图,左一的光源很大,可能5根光线就打到了光源;最右就相反,可能5万根,才可能有1根打到光源。我们不希望这种浪费的现象,是不是可以有其他的pdf采样?
如果我们可以直接在光源上采样,也就是采样样本直接分布在光源的表面上,那么所有光线都不会被浪费了。
之前我们是盲目地在着色点上往各个方向打出去,打不打得到光源看运气,现在我们直接对光源采样。此时考虑着色的结果时,分为两部分
- 来自光源的贡献,直接采样光源
- 来自其他反射物的贡献,用俄罗斯轮盘赌来做
我们对光源采样其实还有一个小问题,就是光源和物体之间可能还有遮挡。我们要判断一下是否遮挡,到此为止路径追踪就结束了
五、没覆盖的话题
- 让方向均匀分布在半球上,怎么做?
- 蒙特卡洛积分用什么pdf是比较好的?(重要性采样)
- 随机数有质量区分吗?
- 我们可以采样光源,也可以采样半球,可以结合起来吗?(muliple imp. sampling)
- 为什么路径能量平均起来就是像素?要不要加权?
- 我们得到radiance,但是最后像素显示需要颜色,我们要做伽马矫正,怎么做?