[计算机图形学]蒙特卡洛积分与路径追踪(前瞻预习/复习回顾)

一、Monte Carlo Integration—蒙特卡洛积分

我们学过如可求解不定积分,前提是我们可以求出这个函数的解析式,但是如果我们不知道这个函数解析式是什么怎么办呢?我们知道黎曼积分,它可以把整个函数图像切分成无限密的小长方形来求解。那么蒙特卡洛积分是怎么样做的呢?也很简单,我们以上图为例,在a-b间任取一点x,我们可以得到它对应的f(x),然后我们此时认为该函数图像就是一条水平线,也就是它的面积变成了一个矩形,底长为(b-a),高为f(x),我们用这样一个长方形的面积去近似这个不规则图形的面积,然后重复这个过程,我们可以取到很多很多长方形的面积,把它们加起来然后求平均,就可以近似得到这个函数图像的面积了,而每次取得长方形的过程就是一次采样的过程,也就是说如果对上图这个函数值进行均匀多次采样的话,其实就相当于将整个积分面积切成了许许多多个长方形,然后将这些小长方形的面积全部加起来这与黎曼积分的思想几乎一致

由此我们可以基本得出用蒙特卡洛积分方法求解定积分的公式,如上图。当然这里用到的采样分布函数是均匀分布,实际上还有重要性采样,以方便我们得到的的误差更小。当然,即使是用均匀分布采样,只要采样点足够多,我们仍然可以得到一个相对准确的结果,但是性能开销可能会加大,所以有时候我们不一定会采用均匀分布来进行采样,而是整体形状和被积函数拟合的一个采样分布函数,那么由此,我们可以推出一个更加通用的公式。

同时要注意,如果我们对x进行积分,那么采样就一定要在x上。另外关于蒙特卡洛积分,知乎有位大佬写的一篇文章非常好,如果大家不太理解,大家可以看看:蒙特卡洛积分 - 知乎 (zhihu.com)

二、Path Tracing-路径追踪 

1.Whitted-Style光线追踪的错误

(1)Glossy材质的错误表现

对于Whitted-Style光线追踪,我们之前说到的时候,假象了发生的反射都是镜面反射,但是事实上在有些时候并不是这样,如上图右边的Glossy反射,它看上去并不光滑,而是相对模糊,也就说明它反射的时候是对一小片区域进行反射,而不是完美的一条直线。

(2)漫反射材质之间缺少的反射

我们之前在做Whitted-Style光线追踪的过程中,我们发出eye ray之后打到透明材质折射,反射,但是当我们打到漫反射材质的时候却没有继续进行下去,这显然是不对的,因为光线在打到漫反射材质的时候还会继续在场景中弹射,上图揭示了这一规律。(左:无全局光照/右:有全局光照)

2.用蒙特卡洛积分来求解渲染方程

渲染方程是我们上一篇得到的,基于物理的准确的描述光的一套方法,所以它比Whitted-Style光线追踪更准确。关于渲染方程,我们之前得到的右边的项,是关于光源的照射/其它表面反射来的光,而这些的集合显然就是对半球的积分,我们用上面提到的蒙特卡洛积分方法来求解。其次这是一个递归的问题,因为光线会弹射多次。

(1)只考虑直接光照的情况

先考虑简单情况,如上图的较为简单的场景,一个面光源light,一个box,然后我们对这地面上的一个着色点进行分析。

我们先不考虑间接光照,只考虑光源的直接光照,且该着色点没有自发光,那么我们的渲染方程就可以减少一项,那么就只剩下了对半球的积分。那我们当然可以用蒙特卡洛方法进行求解。

那我们确定我们的f(x)被积函数就是上面的一大堆积分,那么采样分布函数呢,很简单,就是1/2π,因为我们是对半球的每个方向均匀采样,也就是采用均匀分布采样,而我们之前说过整个球的立体角是,那么半球的立体角就是,所以均匀分布函数的值就是1/2π,得到如下式子。

 ↑通过蒙特卡洛积分求解渲染方程只计算直接光照的伪码↑

(2)引入间接光照

如果我们从摄像机发出一条光线打到上图中P点,和光源连线,那么这计算的是P点的直接光照,但是我们不能忽略Q点对P点的光照的贡献,也就是间接光照。在渲染方程中我们提到,对于一个着色点,我们所作的积分中,并不区分是直接光照还是间接光照,那么直接光照我们前面已经提到了如何求解,Q点的间接光照呢?很简单,我们想象在P点有一个摄像机沿着Q的反射方向看向Q点,那么P点接收来自Q点的间接光照就相当于Q点接收到光源的直接光照反射后得到的结果。于是在上面的伪码上我们可以增加一项。如下图,而这恰恰是一种递归算法。

但是这里有一个问题,就是光线在递归之后会越来越多,如果我们设置递归发出的光线是100条,那么在递归的算法下,我们每次弹射都会再反射出100条光线,而我们的弹射点又不止一个,这是一个指数级的增加,会产生指数爆炸

解决方法也很简单,1的多少次方都是1,所以我们不用100根光线,只用一根光线即可解决指数爆炸问题。所以修改一下伪码如下图所示。

而由此,我们得到了一个及其简化的公式(如上面伪码所示)因为我们的采样方向变成了1个,也就是N=1。而N=1的这种方法就叫做路径追踪而如果N≠1,这是另一种,叫做分布式光线追踪,会产生指数爆炸

但是我们如果只发出一条光线,会产生非常多的噪点。其实我们在一个像素中会发出很多条光线,而通过这些光线在场景中的不断弹射,最终这个像素会得到这个着色点接收不同弹射点的着色结果之和。

那么我们同样的可以写出伪码,如上图:在一个像素里发出Npath,也就是采样,对于每个像素的每个path发出一条光线,如果它打到了场景中的某个点p,该像素的radiance就等于不断累加的着色之和,而这里同样用到了蒙特卡洛积分方法

但是现在仍然有问题,我们说过这个着色的算法是一个递归的算法,但是递归需要停止条件,而我们写的着色方法就是没有停止条件,它反映了光线弹射无限次,而现实中就是这样,但是这在计算机中是不能实现的,而如果我们把它限制在某一个固定的弹射次数违背了能量守恒,它损失了很多能量的计算,这也是不对的,那该怎么办呢?

3.Russian Roulette(RR)—俄罗斯轮盘赌

俄罗斯轮盘赌,简称RR,假如一把左轮枪里面装2发子弹,(弹匣容量6),然后朝自己开枪,那么活下来的概率就是4/6。那么这和光线弹射有什么关系呢?

对于每一条发射出的path,到达着色点的时候,我们提前设置一个概率P,让它以P的概率决定它继不继续进行弹射,如果弹射了,那么最终计算的积分结果我们取Lo/P,否则取0。这么做的原因是当我们取期望的时候,我们会发现我们的期望是Lo,也就是正确的。

 而把俄罗斯轮盘赌总结到着色的代码上就得到了最终的伪码,如上图。

但是此时得到的图像效果质量取决于我们的SPP(samples per pixel),也就是每个像素发出的path数量,也就是采样率。也就说明我们的算法并不是那么高效

问题出在哪里呢?我们对于每一个着色点,我们是均匀的朝着四面八方采样的,也就是说,我们的光线能否能打到光源完全取决于运气如果光源小,那么我们就会浪费许多光线,如最右图,我们平均每发射50000条光线才能打中一次光源。也就是说我们需要换一种采样方式。而且我们之前在说蒙特卡洛方法的时候特意提到了,采样分布函数不一定非要用均匀分布函数。

4.直接对光源采样—改写渲染方程

我们换一种思路,如果我们直接对光源进行采样,那岂不是就不会浪费了?如上图。但是我们要先想到渲染方程并不是定义在光源上的,而是定义在着色点的半球上的 。而我们之前也说过蒙特卡洛积分要求对谁积分就要在谁上面进行采样。但是此时我们是对光源进行采样,但确实在对立体角积分,所以是错误的。所以要对渲染方程进行改写,从对积分改为对dA积分我们只需要知道dA的关系然后替换即可。怎么替换?我们想想立体角的定义,面积除以距离平方,那我们只需要dA这块面积投影到球面上然后除以着色点x和光源处点x'距离的平方即可,面积投影可以用cosθ'求得。而采样分布函数p(X)就是1/A,因为我们在光源上进行均匀的采样这样一来我们就把渲染方程改为了对光源的积分

而由此,我们就可以把任何一个着色点接收光的贡献拆成两部分,一部分光源的直接光照对该着色点的贡献另一部分则是间接光照的贡献。而光源直接的贡献经过我们改写的渲染方程积分之后可以直接得出,而且只涉及到一次弹射,所以光源这部分不需要用俄罗斯轮盘赌

 于是,我们得到如上图的伪码。

最后的细节,就是判断这个着色点p是否能接收到直接光照,也就是从p与光源的连线向光源发出一条光线,如果能到达光源,则说明该点与光源之间没有遮挡,也就是可以计算光源对该着色点的直接贡献,否则只计算间接光照,也就是除光源外的其它贡献。而到此,路径追踪的一整套流程就都完成了,而它基本上是100%正确的,如下图真实拍摄照片和路径追踪渲染结果的比较。

三、我们没有提到的细节

1.如何对半球进行采样?——采样理论

2.蒙特卡洛积分所用的采样分布函数不一定是均匀分布——重要性采样

3.随机数的选取优劣,随机数可以均匀分布在0~1——低差异序列

4.对光源采样和对半球采样可以相结合——多重重要性采样图形学|Robust:Multiple Importance Sampling 多重重要性采样 - 知乎 (zhihu.com)

5.像素的Radiance真的只是各种path的简单平均吗?还是加权平均?—pixel reconstruction filter

6.我们最终计算的结果是Radiance,而Radiance≠Color,如何将Radiance转化成Color呢?——伽马矫正,曲线,颜色空间

感兴趣的朋友可以自行了解。

参考:

Lecture 16 Ray Tracing 4_哔哩哔哩_bilibili

GAMES101_Lecture_16 (ucsb.edu)

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值