一、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. [计算机图形学]几何:曲线和曲面(前瞻预习/复习回顾)

    一.曲线 1.Bézier Curves-贝塞尔曲线 贝塞尔曲线也是一种显式的几何表示方法.贝塞尔曲线定义了一系列的控制点,致使确定满足这些控制点关系的唯一一条曲线:如上图定义的贝塞尔曲线满足 起始点 ...

  2. [计算机图形学]重心坐标应用纹理(前瞻预习/复习回顾)

    一.重心坐标,插值 上篇的最后我们提到了,当顶点在纹理上的对应uv坐标成功找到之后,三角形三个顶点中间的值需要用三角形的重心坐标插值计算得到,那么这个运算是怎么进行的,本篇我们将介绍.插值的运算不仅仅 ...

  3. [计算机图形学]辐射度量学、渲染方程与全局光照(前瞻预习/复习回顾)

    一.前言 我们前面讲到的Blinn-Phong着色,Whitted-Style光线追踪都有一定问题,那就是它们并没有严格的按照物理规则定义各个变量.比如,Blinn-Phong中的光的强度,并没有一个 ...

  4. [计算机图形学]反走样(前瞻预习/复习回顾)

    一.前言:走样的产生 上一篇我们谈到了光栅化,在讲述光栅化时我们得到了光栅化之后的这样一张图,如下图 显然,这和我们原本的三角形严重不符,原因是像素是方块,而无法完美的拟合三角形. 也就是说我们得到的 ...

  5. [计算机图形学]材质与外观(前瞻预习/复习回顾)

    一.图形学中的材质 不同的物体表面有着不同的材质,而不同的材质意味着它们与光线的作用不同.那么我们之前在介绍辐射度量学和渲染方程提到过其中一个函数,叫做BRDF,而在实际上,也就是BRDF定义了不同的 ...

  6. [计算机图形学]动画与模拟:关键帧动画、质点弹簧系统、运动学与绑定(前瞻预习/复习回顾)

    一.动画的简要概念 动画和语言一样,一开始都是作为传达信息的工具.什么是动画呢?简单的理解就是让画面变成"活的",也就是让它们能够动起来,其次需要一定的美观.在图形学上,我们可以把 ...

  7. [计算机图形学]动画与模拟:欧拉方法、刚体与流体(前瞻预习/复习回顾)

    一.前言 这是本专栏的倒数第二篇文章了,为什么不是最后一篇?因为我要单独写一篇总结哈哈,不管怎么说,从今年的3.13的MVP变换开始写,写到现在,也是一个很大的工程了,我很高兴能在大二下学期的期中这个 ...

  8. [计算机图形学]光线追踪的基本原理(前瞻预习/复习回顾)

    一.光栅化的弊端 我们为什么要用光线追踪呢,在之前的篇章中,我们提到了,光栅化的方式很难表示一些全局的效果,如(1)软阴影,(2)Glossy的反射(类似镜子但又不像镜子那么光滑的材质,如打磨的铜镜和 ...

  9. [计算机图形学]纹理的高级应用(前瞻预习/复习回顾)

    一.前言 上节课我们讲了纹理的放大缩小产生问题后,我们的解决方法,那么纹理是什么呢?在现代GPU中,我们可以理解为是内存+范围查询(滤波),也就是对一块区域做点查询/范围查询,并且做的非常快,也就是说 ...

  10. 19、计算机图形学——蒙特卡洛路径追踪

    一.蒙特卡洛积分 蒙特卡洛积分主要解决的问题是当被积函数很难被以函数的形式表示时,需要对该被积函数指定概率密度函数并进行多次采样.然后用采样得到的局部面积除以局部采样点的概率来近似得到整体的面积(积分 ...

最新文章

  1. [翻译]Python中yield的解释
  2. 问题集锦(54-55)
  3. 【手写系列】透彻理解Spring事务设计思想之手写实现
  4. ROS:ubuntuKylin17.04-Ros使用OrbSLAM2
  5. iphone个系列尺寸_最值得入手的4款iPhone,都是内行人的最爱,拿出去有面子
  6. Java ClassLoader findResources()方法与示例
  7. flutter 一个用户登录页面
  8. 服务器系统reid,服务器主机做reid
  9. 线程不安全 静态变量_【高并发】面试官问我:为啥局部变量是线程安全的?...
  10. Autojs微信自动操作免root脚本源码
  11. 网络安全先进技术与应用发展系列报告 用户实体行为分析技术(UEBA)
  12. 产业分析:2022南京市产业全景
  13. 超人视觉启蒙班一些零散笔记
  14. 论文阅读笔记:《Neural3D: Light-weight Neural Portrait Scanning via Context-aware Correspondence Learning》
  15. 家庭光纤宽带有必要升级千兆双频路由器吗?
  16. 牛刀小试:利用Python分析豆瓣电影Top250(一)
  17. HTML5期末大作业:篮球网站设计(6个页面) HTML+CSS+JavaScript
  18. 啥是预乘?——Nuke中的Premult(预乘)和Unpremult(预除)
  19. 记一次mysql数据库转储sql文件到另外一台电脑运行失败的解决办法
  20. 物联网系列--整体框架搭建

热门文章

  1. 初中生的心理特征与管理对策
  2. 睡眠不足怎么办?试试这几种助眠好物,让你一觉睡到大天亮
  3. 抓取预测二手车价格的机器学习模型
  4. 快速学好一门编程语言
  5. 腾讯出手了,你的羞羞聊天记录凉了!
  6. 帝都攒钱买房的哥们(zz)
  7. 从55%到11%‼️两个pdf查重复
  8. 文件系统的建立与类型
  9. 时统ptp_OTC, PTP, RTR, TE是什么意思
  10. 内推 | 【泸州老窖 - 渠道数字化运营​】成都