蒙特卡洛积分与路径追踪
蒙特卡洛积分与路径追踪(Lectures 16)
内容:
- 蒙特卡洛积分
- 路径追踪 Path tracing 与 光线追踪Ray tracing
- 渲染方程求解
- 直接光照下的路径追踪算法
- 全局光照下的路径追踪算法
- 如何引入
- N值的处理
- 递归的处理
- 路径追踪算法的效率优化
蒙特卡洛积分
- 蒙特卡洛法:基于概率计算的一类方法,主要的思想是不断的抽样、不断的逼近。一种直接的应用就是求解积分,即蒙特卡洛积分。
区别与黎曼积分:
蒙特卡洛积分法直接的积分公式:
- 其中xi表示为抽样点,f(xi)表示抽样点对应的函数值,p(xi)表示对应的概率密度函数的值。
- 对于一个积分而言,如果对应的函数难以写出解析的形式,那么蒙特卡洛积分法提供了一种计算该积分的方法。
- 在一个积分区域内,按照一定的概率密度函数对里面的x进行抽样,概率密度函数可以由自己规定。按照这种规定抽样得到的点xi,计算其对应的函数值以及对应的概率密度,二者相除。同样的,对于其他抽样点同样计算,最后将二者相除的值相加后求平均,得到对应的值即可认为是该积分的值。(理论上采样点N取无穷)
- 蒙特卡洛积分法的准确性与采样点的选取数目息息相关。
- 不同的函数有不同的概率密度函数(PDF)的选取方法。
例子:
假设对于一个积分,在其积分区域内进行均匀抽样,便可以得到对应的PDF。
带入蒙特卡洛积分公式便可以得到针对均匀抽样的蒙特卡洛积分计算公式:
路径追踪 Path tracing 与 光线追踪Ray tracing
之前的Ray tracing即Whitted-style的ray-Tracing,它假设两件事情:
- 首先,认为光线进行镜面反射的时候,反射方向是按照入射角度进行反射的。
- 其次,认为光线进行漫反射的时候便停止了光线进一步的反射。
明显,这两种假设都是局限的,那么按照这种假设进行的渲染最终结果仍然是不准确的。
- 对于一种情况,有一种材质称为 Glossy ,在其表面也是进行镜面反射,但是反射的角度并不是完全的按照入射角进行反射。
- 第二种情况,真实情况下漫反射后的光线仍然会进行反射,而不是如它所假设的那样停止反射。
但是基于辐射度量学的渲染方程是正确的,由此,通过解渲染方程便可引入路径追踪。
- 从某个方向ω0观察一个着色点p所得到的能量=着色点所在物体本身沿着观察方向ω0发的能量+四面八方的光线照射到这个点且经过BRDF反射到观察方向的能量总和。
求解渲染方程:需要解决两个方面的问题:
- 渲染方程涉及到积分的求解
- 渲染方程本身是递归执行的
渲染方程求解
针对渲染方程的求解,采用蒙特卡洛积分进行求解。
- 先考虑一个简单情况,只考虑一个着色点的直接光照(光线只弹射一次,进来的光线只能是来自光源,如果进来的光线不是来自于光源,直接是0)
- 采用面光源而不是点光源--方便规定PDF,点光源更加复杂些。
- 方向统一朝外
这个点的直接光照是是什么:便是求解问题的最终结果。
- 另一方面,不考虑发光项
考虑着色点p,从这一点反射到摄像机的radiance是多少,就是对应的积分求解。
采用蒙特卡洛积分,必然涉及到采样的概率密度函数PDF。
规定采样是在半球上均匀采样。整个半球的方向角为2pi,那么可以得到 PDF为 1/2pi。
带入蒙特卡洛积分法可以得到:
- 公式表达有些不严谨,分母的p代表PDF 分子的P代表的是着色点。
针对这个公式,给出了一个确定的在直接光照下的着色算法。
直接光照下的路径追踪算法
- 对于我们关心的着色点p 以及已经知道摄像机照向p的方向ω0,则要得到这种情况下p点对应的直接光照(radiance 能量 光线....各种描述本质上都是一回事),计算出的结果并不是对应shading的颜色,其中有量的转化关系,并且这种转化关系并不是线性的。
- 着色点在半球上共发出N个不同的方向,然后在这N个方向中按照规定的PDF选出采样方向 ωi
- 初始化要计算的点的L0=0
- 对于每一个选出来的方向 ωi
- 跟踪从这个点的方向ωi
- 如果打到了光源(直接光照体现)
- 则按照蒙特卡洛积分计算,其中光源的情况已知,BRDF,夹角啥的都可以计算得到
- 最终将结果返回作为这一点的直接光照的结果
全局光照下的着色算法
如何引入
针对直接光照的算法,可以直接进一步推广到全局光照下的计算。
全局光照:包括了弹射一次的直接光照+弹射两次及以上的间接光照。
- 直接光照关心的是如果光线打到了光源,则计算,如果不是光源则不管。
- 全局光照针对后者进一步考虑,如果打到的是其他物体,考虑将先前的着色点当成新的摄像机的位置,打到其他物体对应的点当成p prime,计算从p prime反射到新摄像机的radiance。
改进后的支持全局光照的路径追踪算法。
- 着色点引出的一个方向ωi打到的是光源则直接带入算
- 如果是物体上某点q,则计算从q到沿着方向-ωi到着色点的radiance,等效于计算q点的直接光照(光线只弹射两次的情况下),更多次的弹射同样的处理,最终总会追踪到直接光照的计算
- 递归的算法
- 同时也体现了渲染方程的一个思想,不管是来自光源的光线还是来自物体的光线,都当光源处理。对应会算法则体现在L0的计算等式结构并没有改变。
但全局光照路径追踪算法仍然存在问题:
N值的处理
问题1.
如果取每个着色点散发出的N都取100的话,一根光线到达第一个着色点会散发100根光线方向,那么如果这100根光线方向其中一个打到的不是光源是物体,那么在物体上的那一个着色点这根光线又会散发100根光线方向去进行shade的求解。N最终会爆炸。
解决方法,在路径追踪时,取N为1,这样就能保证N的值的恒定。蒙特卡洛积分并没有规定N,取N为1仍然是对的,只不过N大噪声小,N小噪声大。
对应算法的改进:
- 用N=1的情况去做蒙特卡洛积分----路径追踪
- N不等于1,分布式光线追踪,当然会出现N爆炸的情况。
将示意图表述出来,显而易见到有一条从视点到光源的路径,因此称为路径追踪(Path-tracing)。
- 取N为1时,对应的结果肯定会不好
- 但是这只是一条路径,穿过一个像素可以有很多个路径,最后将这些路径求平均作为这个像素点的radiance,也算蒙特卡洛法的一个思想?多次取样 多次逼近。
那么可以得到对应的光线生成的代码:
- 已知摄像机的的位置,往哪一个像素发射出很多条光线
- 在这个像素内均匀的取N个位置
- 对于每个位置打一条光线,如果光线打到了某个位置
- 则利用之前的路径追踪的算法去计算对应的radiance
- 最终求平均值
- ray generation将二者联系起来,解决了N取1时噪声太大的问题。
如果一个像素对应多条path,即SPP High 得到的效果好,但是慢,如果SPP Low的情况下,效果不好但是快。
递归的处理
问题2:
路径追踪的算法中对应的递归没有终止条件,算法永远不会停,或者说终止条件太小,可能多次弹射也没有打到光源上。
真实的世界中光线的弹射次数本来就是无限的,如果提前限定弹射次数,那么多次弹射的能量就没有考虑,能量有损失。
一方面计算机不能处理无限的弹射,一方面限制弹射次数的话会有能量损失。
解决方法:俄罗斯轮盘赌
规定光线继续弹射的可能性为p,最终得到的结果为相应的radiance除以p,这样的话
在期望上仍然可以保证最终得到的结果为原先的radiance
对应的算法:
通过处理最终得到的路径追踪是正确的,但是效率却不够。
路径追踪算法的效率优化
路径追踪的效率并不算特别高,原因在于:
一个着色点采样出的一个光线方向打不打得到场景中的光源是看运气的,如果对应光源大,那么打到光源的几率就会大,如果对应的光源小,打到光源的几率就会小,有很多的光线是浪费掉的。
关键问题:
- 采样是在着色点处采样的
- 采样的方式是均匀的 (可设置与光源位置有关的PDF)
那么就将采样的地方从着色点转移到光源
- 前面说路径追踪的N只取1,本身从着色点进行采样对应打到光源的几率不大,大量没有打到光源的光线方向对整个路径追踪并没有作用。
- 如果在光源进行采样,就算这个采样光线没有打到我们当前关心的着色点P,那么它对整个路径追踪也是有用的,因为它必然会打到其他的着色点,这些着色点在整个路径追踪中仍然要计算。
- 因此,在光源处采样解决了光线的浪费问题,从而提升了效率。
- 以下的一切推导都是基于光线处的采样光线打到了我们关心的着色点p
假设在面光源均匀采样,则可以得到PDF为:
(如果是点光源可以当成小面积的面光源处理)
进一步,又因为蒙特卡洛积分法的积分变量与采样对应的变量应是一致的,那么应当找出面光源与立体角之间的关系。通过积分关系进行代换,将渲染方程写成在光源上的积分。
结合立体角定义:
也可以理解为任何一个面积投影到单位球上除以1的平方,即投影的面积就是立体角。
将面光源进投影到单位球上,对应的面积与球心形成一个锥,通过光学几何得到:
- 先将面光源转到正对球心
- 然后除以二者距离
将其带入到渲染方程,再改写下蒙特卡洛积分对应的函数以及PDF
注意到前提是采样方法是均匀的。
那么之前的算法可进行修改,将光线传播拆成两部分:
- 光源直接对着色点的贡献,不需要涉及到俄罗斯轮盘赌,因为前面提到过,从光线采样的推导是基于这个采样的光线打到了我们关心的着色点,这样才有一系列的如面积和空间角的积分变量的转换关心。
- 其他非光源的所有点对着色点的贡献,需要俄罗斯轮盘赌(俄罗斯轮盘赌是处理多次弹射对应的间接光照才引入的)
- 区别与第一次引入俄罗斯轮盘赌的算法,那里的直接光照的光线也要基于轮盘赌的原因。
- 可能是因为间接光照的计算需要俄罗斯轮盘赌,但是间接光照最终会转变为直接光照,但是完全基于着色点采样时并没有像这样区分了两者的计算公式,也就是说在优化效率的时候将直接光照与简介光照分开的。但是渲染方程本身并没有区分二者。
- 可能也有对应的处理,只不过入门课没提及或者说影响不大。
- 第一部分,从光源采样的光线到达了着色点p,那么对应的radiance就按照光源采样的公式进行计算。
- 第二部分,非直接的光。仍然考虑从着色点处采样,从着色点引出的一条光线首先通过了俄罗斯轮盘赌,其次没有打到光源,则用之前的在着色点处的计算方法计算。
- 最终将直接来自光源的以及非光源的两部分求和
- 将两部分进行了拆分。
进一步引入了有无物体挡住直接光照,如果挡到了就是0,没有挡住就计算值。
整个路径追踪仍然还要许多细节没有介绍,以上的仅仅为基本的内容。
reference:
[1] GAMES101-现代计算机图形学入门-闫令琪
[2] https://baijiahao.baidu.com/s?id=1692002283287398853&wfr=spider&for=pc
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~