背景
在渲染中,积分的计算非常普遍。最基础的渲染方程就是一个积分公式,其他的如相机传感器响应,材质次表面散射等渲染功能也涉及到积分计算,所以计算积分的算法设计在渲染系统中非常重要。
通常情况下计算积分时会想到使用解析法,即求解被积函数的原函数,然后使用牛顿-莱布尼茨公式求解,然而这种方法在渲染系统中是行不通的,渲染中计算的积分函数非常复杂,无法求解出原函数,并且一般会涉及到二维甚至三维的积分,所以解析法难以在渲染系统中实现。
另一种计算积分的方法是数值法,也就是蒙特卡洛积分,通过对数值的估计求解积分的近似解,只要求出被积函数f(x)在某个点x0的取值f(x0),就可以通过多次采样再求平均的方法来求出积分的解,并且这种方法可以也用于多维积分,这样就解决了渲染中求解积分困难的问题。
蒙特卡洛积分的基础
蒙特卡洛积分是一种基于随机数的方法,需要一些概率与统计的基础知识,所以在了解蒙特卡洛积分之前,先了解一些相关的背景知识。
随机变量和概率
随机变量指的是通过某些方法随机选取的一个值,通常使用X来表示,随机变量可以是离散的,也可以是连续的。通常随机变量都有着定义域,比如随机选择一个实数,它的定义域就为R。
关于离散型的随机变量,以最常见的掷骰子为例,以X来表示掷出的点数,则 。以p来表示每个点数掷出的概率,则,这表示掷出每一个点数的概率都是1/6,明显可以看出,掷出所有点数的概率相加为1。用来给出离散随机变量的概率的函数称为概率质量函数 (PMF),通常使用p来表示,在掷骰子这个例子中,。
连续型随机变量与离散型不同,它的取值有无穷多个,并且充满整个定义域。比如在[0, 2]中随机选择一个实数,就无法直观地看出这个数的具体概率(事实上连续型随机变量取到特定值的概率为0,但它并不是一个不可能事件,一般研究连续型随机变量的时候都是研究取到某个区间的概率)。在渲染系统中,比如向半球面的随机一个方向投射光线,该方向就是一个离散型的随机变量。
一种比较特殊的随机变量叫做规范均匀随机变量(canonical uniform random variable),这种随机变量相互独立,并且在其定义域上以均匀的概率取值,掷骰子和掷硬币就是典型的规范均匀随机变量。这种随机变量在程序设计中经常应用,因为很多库都提供了在运行时的随机数生成器。
累积分布函数 cumulative distribution function (CDF) P(x)描述了随机变量X小于或等于x的概率,即
比如在掷骰子的例子中,P(2) = 1/3,因为点数小于等于2的可能性有两种:1和2,出现的概率为2/6。在离散型随机变量中,,在连续型随机变量中,。
概率密度函数 probability density function (PDF)描述了一个连续型随机变量取到某个特定值的概率,与离散型随机变量的PMF类似。PDF的定义是CDF的导数。即
pdf是一个非负数,并且在随机变量定义域内的积分等于1,对于给定区间[a, b]来说,随机变量的概率为:
对于均匀分布的连续型随机变量来说,它的pdf是一个常数。假设随机变量x在[a, b]上连续均匀分布,那么它的pdf为:
假设在一个单位球体的表面均匀采样,比如从一个点选定某一个方向向四周发射光线,那么这些样本的pdf就为,为球体的表面积。
数学期望
在概率论和统计学中,一个离散性随机变量的数学期望是试验中每次可能的结果乘以其结果概率的总和。换句话说,期望像是随机试验在同样的机会下重复多次,所有那些可能状态平均的结果,便基本上等同“期望”所期望的数。数学期望通常也称为加权平均数,通常使用E来表示。
对于连续型随机变量来说,数学期望的定义是随机变量x在其分布函数f(x)定义域上的平均值,,
其中p(x)表示x的pdf。
假设一个随机变量x在上的分布函数是,并且它是均匀分布的,即,那么它的数学期望为:
数学期望有两个重要的性质,
- 假设a为常数,则
- 多个变量之和的数学期望等于每个变量的数学期望之和
蒙特卡洛估计器
定义一个蒙特卡洛估计器(Monte Carlo estimator)来近似一个积分的值。
假设需要计算一维积分的值,给定一个独立均匀的随机变量,那么蒙特卡洛估计器的定义为:
则它的数学期望近似于积分的值。
证明其正确性:
这里用到了数学期望的两个性质,并且由于随机变量是独立均匀分布的,所以它的pdf正好可以和外面的消掉。在这个证明的过程中有一步将替换成了,这一步是遵循了大数定律,即样本均值会随着样本数量的增加而收敛于真实的数学期望。只有在样本数量足够多时,这个结论才成立,所以蒙特卡洛估计器是有误差的,并且这个误差随着样本的增加而减小。
虽然这里说的是数学期望近似于积分的值,但是需要注意的是本身就是一个对采样点求平均值的过程,所以在样本数够多的情况下,,所以只需要计算就可以估计积分的值了。 Doubtful 这里的理解还不够深入
这个结论可以扩展到多维的积分计算,比如想要计算二维积分的值,它的蒙特卡洛估计器就为:
其中随机变量是独立且均匀分布的。
更通用的,假设选取的随机变量并不是独立均匀分布的,它的pdf函数为,则它的蒙特卡洛估计器定义为:
证明它的数学期望等于积分的过程与上面独立均匀随机变量相似。
使用这个方法求解积分的优势就是可以在计算多维的积分时在多个维度任意选择样本,不用过多考虑积分的维数对计算的影响。比如计算二维积分时可以直接在x和y上采样一个二维点,而不用考虑x和y的计算顺序这些问题。
蒙特卡洛估计器的误差
在统计学中,通常使用方差来衡量统计结果与期望值的偏差。这里同样用方差来衡量蒙特卡洛估计器的误差,并且方差在评估该算法的收敛性能上也有帮助。
方差的定义为:
由于方差有以下性质:
其中a为常数。结合上面数学期望的性质,可以将方差用以下形式来表示:
即方差等于采样数平方的期望减去期望的平方。
同样,多个随机变量的方差也有以下性质:
在蒙特卡洛估计器中,方差随着采样数量的增加而减小,假设n为采样的数量,则方差的减小速率为。它的好处就是不论采样的维数如何增加,它的方差减小速率是恒定的,这在计算多维积分时很有优势。这个性质导致在使用这种方法进行图像渲染时,最开始的采样点可以很快地提升渲染质量,而当采样点数变得很多时,每增加一个采样点,渲染质量的提升会变得很不明显。
可以使用方差来估算蒙特卡洛估计器的效率,假设一个蒙特卡洛估计器的方差为,而它运行消耗的时间为,那么它的效率为:
方差越小,消耗时间越短,这个蒙特卡洛估计器效率就越高。
并不是所有估计器的期望值都等于积分的值(假设采样数量足够大),这种估计器叫做有偏估计器(biased estimator),与之相对的如果估计器的期望值等于积分的值,那么此估计其叫做有偏估计器(unbiased estimator)。看起来无偏估计器总是比有偏估计器更好,实施却并非如此,除了精度之外,估计器也要考虑效率问题,如果一个有偏估计器的效率很高,那么它可以将节省的时间用来进行更多的采样,以此弥补精度不足的问题。
在渲染中,使用的蒙特卡洛估计器大都是无偏的。
提升采样效率
前面已经提到,使用蒙特卡洛估计器时,方差随着采数量的增加而减少,假设渲染出的图片噪点太多,可以使用更多采样来减少噪点。然而有时渲染有性能要求,采样的数量必须被限制在一个范围内,防止渲染时消耗过多的时间,这时就要从另一个角度考虑,在不提升采样数量的情况下,让采样的效率更高。就比如如果一个函数定义域为,但是它在内的值非常接近于0,而在上的值很大,那么在样本数有限的情况下,将采样的区间放到内会更有效果。
分层抽样
分层抽样的思想是将积分的定义域分解成多个区域,然后在每个区域中放置样本。对像素的超采样就是使用了这种方法,将一个像素的区域分解成个小区域,并在其中进行采样,与直接生成像素点内的坐标的方式相比,分层采样可以保证样本在像素内的分布是尽量均匀的,不会出现多个样本聚集在一起的情况,这也就保证了采样误差的减少。
下面详细分析分层抽样对方差的影响。
分层抽样将积分的定义域分解成了多个区域,每一个区域叫做层(stratum) ,所有层合并起来等于原始的定以域:
使用表示第i层的采样数量,表示第i层的概率密度,那第i层的蒙特卡洛估计就为:
其中指的是第i层的第j个样本,如果使用来表示每一层的权重(如果是均匀地分层,那么所有层的权重均为),最终整个积分的蒙特卡洛估计器为:
假设第i层的真实积分值为:
那么第i层的误差为:
(这个结果的不知道是怎么的得到的,不过不影响分析)
因为第i层是由个样本的,那么第i层的方差为:
总体的方差为:
假设每层的样本数量也是按照权重分配的,那么,则上面的方差可以化简为:
如果不使用分层抽样,而是直接采样,可以把直接采样考虑成随机在所有层中选择了一层,然后随机在这层选择一个样本,那么直接采样的方差为:
其中Q是f在域上的平均值。从上式可以看出,分层抽样的方差总是小于直接采样的方差,除非每一层的平均值都等于该函数真实的积分值。
重要性采样(Importance Sampling)
重要性采样是蒙特卡洛积分中最有效的提升采样效率的方法,甚至说到蒙特卡洛积分就不得不提到重要性采样。
重要性采样得基本思想是挖掘出最影响估值的(重要)因素,利用好这些因素来估值就能达到减小方差的目的,从而提升采样效率。
以高斯函数函数为例,它的函数图像为:
如果想要计算它的积分值,就需要在它的定义域上采样。这个函数的分布特征非常明显,只有在区间函数值是明显大于0的。假设使用的是均匀采样,在内随机选择采样点,那么蒙特卡洛方法得到的结果方差为0.0365。
如果可以找到一个合适的分布,比如以下分布:
这个分布的图像为:
这样进行采样的时候,样本主要分布在区间内,与原始的函数大致相符,采样效率就会大大提高,使用这种方法计算出的结果方差大约可以缩小6.7倍。
从上述示例可以看出,计算蒙特卡洛积分时概率密度函数的选择是至关重要的,然而除了独立均匀分布等几种特殊的分布外,许多函数的概率密度函数是难以得到甚至无法获得的,即使可以得到,有的概率密度函数形式非常复杂,没有办法根据它来采样,所以需要找到一个与被积函数形状相似的函数作为pdf,这个过程就是重要性采样。
寻找一个与函数形状相似的pdf是一个比较复杂的过程,在最理想的情况下,希望该pdf为:
因为这样的话蒙特卡洛估计器:
当然很难的,蒙特卡洛积分就是为了计算的值,如果事先知道这个值的话就不用计算了。不过从中可以看出,寻找的是一个很好的选择,作为新的分布函数,依然要遵循pdf的原则,比如在定义域内的积分为1。
多重重要性采样(MIS)
如果我们需要计算的是多个函数乘积的积分,比如渲染方程:
积分项中包含了三项,使用蒙特卡洛积分进行计算时,如果进行重要性采样,该样本就需要同时考虑这个三个函数的分布。
为了便于讨论,假设要求的值,并且已经知道了它们的分布和,如果采样时只考虑其中一个分布的话,假设只考虑,则
这个方差是非常大的,同理只考虑也一样。
多重重要性采样就是为了解决这种多个函数乘积求积分的问题,它的思想是:在对多种分布进行采样时,应该从多个分布中抽取样本,保证样本至少和其中一个分布是相吻合的,然后将每种分布的样本进行加权,以此消除样本与分布不匹配带来的误差。
以上面的函数为例,采用MIS方法,采样时同时考虑两种分布,假设样本、,则样本估计器的值为:
其中和是两个分布的权重。
更通用地,MIS可以写成如下形式:
其中,并且当时。
于是,寻找合适的权重就成了MIS中重要的一步。最直观的方法是令,即每一个分布的权重都是一样的,这个方法固然是可行的,但是稍加思考就可以明白,更好的情况是当样本非常符合函数的分布时,权重应该更大,当样本不太符合函数的分布时,权重应该更小,这样最终的方差才会更小。
实际使用时,一种非常有效的方法是balance heuristic函数,它考虑样本可能产生的所有方式,具体定义为:
即每个分布函数的权重等于它的采样数量和分布函数的乘积在总的采样数量和分布函数中的权重,假设是一次采样的话,权重就等于该次采样的分布函数占所有分布函数的和的比例。使用这种方式可以有效降低对积分贡献较小的分布所占的比重,也就能减小误差。
balance heuristic函数的实现:
另一种有效的确定权重的方法叫做power heuristic,它与balance heuristic思想类似,只是分子和分母同时取指数,
当时,power heuristic的实现为:
MIS唯一的缺陷在于,当样本非常符合被积函数中的其中某一个分布时,方差会增加。
多重重要性采样补偿(MIS Compensation)
TODO
不是很重要,先略过
俄罗斯轮盘
俄罗斯轮盘也是一种提升蒙特卡洛积分的方法,它的思想是跳过那些对计算结果影响很小的采样,假设我们需要计算的积分项形式为:
渲染方程中积分项有3个,所以这种形式是很常见的。如果的计算结果为0或者非常接近于0,那么的计算是完全没有必要的,因为这一次采样的显然对最终结果影响很小,这一次的采样就可以立即结束。当然这样直接结束可能会引入误差,因为接近于0的时候的结果还是会贡献此次采样的值,但俄罗斯轮盘可以消除这些误差。
在俄罗斯轮盘中,首先确定一个终止概率(termination probability)q,这个概率是可以人为确定的,比如在渲染中,随着光线的不断弹射,它每一次弹射”采集到“的光照强度对当前像素计算结果的贡献会越来越小,那么我们就可以让q随着光线弹射的次数增加而增加,这样弹射次数越多,该路径终止的概率越大。当此次采样在概率q之内时,表示此次采样应该终止,使用一个常数c来代替此次采样的结果,为了方便,通常可以使;当此次采样在概率q之外时,此次采样正常计算,但是最终的计算结果要除以,这是为了补偿之前终止的采样。
使用这种方法,新的估计器就可以表示为:
它的数学期望:
还是与原来的数学期望是一样的。
使用俄罗斯轮盘并不会降低蒙特卡洛积分的误差,反而会引入一些误差,但是它可以非常有效地提升采样效率,在光线追踪渲染时基本都会使用这种方法。
分割
当对二维积分进行计算时,比如:
按照通常的蒙特卡洛积分方法,应该在定义域A和B上共取n个随机变量,假设、,则蒙特卡洛估计器的值为:
使用分割的方法可以在采样时先确定A上的一个样本X,再在X的基础上在定义域B上确定一个样本Y,于是蒙特卡洛估计器的值就为:
假设可以先计算,这种方法相当于采样个样本,它的效率会比第一种方法更高。
使用逆变换采样法(Inversion Method)采样
直到现在为止,蒙特卡洛积分中还有一个重要的步骤是未知的,那就是如何通过选择的概率分布来生成随机样本。如果只是简单的独立均匀分布,当然可以通过在定义域区间内随机生成数字来作为样本,因为此时概率密度函数是一个常数,但大多数情况下概率分布都没有这么简单。通过概率分布来生成随机数的技术有多种,在渲染中最常用的叫做逆变换采样法,它通过求CDF的反函数,将上均匀的样本映射到给定的概率分布上。
离散型随机变量
假设有一个离散型随机变量,它有4种可能,其概率分别为和,所有的概率相加为1,且它的PMF如下所示:
从上图可以看出,最大,最小。
计算该变量的CDF,结果如下图所示:
此时在纵坐标轴上取一个随机值,很明显,如下图所示:
那么对应的横坐标区域就是它的PMF。
这就是逆变换采样法的名称由来,通常情况下,都是使用横坐标即随机变量的值来求它的CDF,这里反其道而行之,在CDF上取值来映射到随机变量的值,并得到它的PMF。在上面的示例图中,
对应的随机变量的值为,所以此次样本的PMF即为。
通过观察上图也可以看出,在取随机值时,取到区间的概率是最大的,而取到区间的概率是最小的,与原随机变量的概率分布相符。
使用这种方法采样的操作实际上就是通过生成一个随机数,根据这个随机数找到该随机变量的某一个样本值和该样本对应的概率(PMF),这样该样本就可以用来做蒙特卡洛积分的计算了。
下面是一个离散随机变量采样的实现函数,它接收该变量的各个取值的权重(该权重并不一定标准化,即它们的和不一定等于1)weights,一个随机生成的区间的数u,返回该次采样的值(这里是返回weights的偏移,由于每一个weight都会对应一个随机值,所以通过这个weights的偏移很容易获得具体的值),得到该次采样的pmf和u重新映射的值。
代码来自PBRT书籍:
其中uRemapped并不是一个必选项,它将u经过映射后又映射回,这在某些随机数生成算法中可能会有用处。
连续型随机变量
在连续型随机变量中,逆变换采样法的思想是一样的,但是具体的做法需要改进。
假设已经知道的随机变量的PDF为,通过以下步骤来进行采样:
- 使用PDF来计算CDF,计算方法为。(这里假设该随机变量的定义域从负无穷开始)
- 生成一个规范的随机数。
- 通过来计算样本X的值。这里也可以先计算CDF的反函数,再计算。
连续型随机变量采样示例—对线性插值函数进行采样
线性插值函数是渲染中常用的函数之一,它的形式是
其中,这个函数根据变量x在a和b之间进行插值。假设现在需要使用蒙特卡洛积分求它的某个组合函数在一个定义域上的积分值(这个函数本身求积分是可以直接计算出来的),那么需要根据这个函数的分布对它进行采样,根据上面对连续型随机变量的采样步骤,具体的做法如下:
第一步:确定这个线性插值函数的pdf,然后求出它的cdf。
非常幸运的是这个函数在其定义域上的积分是可以计算的,,根据重要性采样(Importance Sampling)章节介绍的求pdf的方法,可以求得它的pdf为:
用代码来实现(代码来自PBRT):
知道了pdf之后,求出这个函数的cdf,
第二步:生成随机变量,通过函数的cdf计算对应的采样值。
生成一个间的随机值后,通过就可以得到此次采样的值,可以求得
为了防止时除数为0,一般将其化为如下形式(平方差公式)
代码实现:
分布的变换
上面逆变换采样法只介绍了针对一维随机变量的采样方法,然而在渲染中,多维随机变量的采样非常常见,在一张图片上随机采样时,需要生成二维随机变量的样本,在空间中对某个方向进行采样时,需要生成三维随机变量的样本。
接下来研究如何使用同样的方法来采样多维的随机变量。
一维随机变量的分布变换
假设有一个随机变量x,它的cdf为,pdf为,另一个随机变量,如果是连续且单调的,那么根据cdf的定义,
根据pdf和cdf的关系,可求得
更加直观的写法:
其中h(y)是f(x)的反函数。这就是概率密度变换公式。
这里加了绝对值符号是为了让单调递增和递减的情况都能适用。
举一个例子,x的pdf为,现在,很明显f(x)在区间内是单调递增的,现在要求y的pdf,求解的过程为:
有了,就可以使用逆变换采样法进行采样了。
多维随机变量的分布变换
与一维随机变量相似,多维随机变量之间的变换也是有变换公式的。
在多维随机变量中,概率的分布使用联合概率密度函数表示,对应了一维随机变量中的概率密度函数。这里以二维随机变量为例,更多维的随机变量也是类似的。
假设存在二维随机变量x, y,它们的联合概率密度为,现有随机变量,则称u,v为x,y的变换,u,v的联合概率密度求解方法如下。
如果函数存在连续的偏导数且存在唯一的逆变换,假设它们的逆变换为:
则(u,v)的联合概率密度为
其中J为变换函数的雅可比行列式,
以笛卡尔坐标系变换到极坐标系为例,假设现在坐标中随机变量(x, y)的联合概率密度为,根据坐标系的转换关系:
求的联合概率密度。
首先,根据上面的转换关系,可以求得它们的逆变换:
然后求雅可比行列式
所以的联合概率密度为
同样的方法也可以用在三维坐标场景,类似地,在三维笛卡尔坐标系和极坐标系下,联合概率密度的转换关系为:
多维随机变量的采样
在知道了多维随机变量之后,同样使用逆变换采样对其进行采样,假设随机变量(x,y)的联合概率密度为p(x,y),如果x和y是相互独立的,一般来说p(x,y)是通过它们各自的概率密度求得的,即
这时按照它们各自的概率密度采样就可以了。
在大多数情况下,x和y都不是独立的,此时对它们的采样就需要使用另一种方法,首先,先求出x的边缘概率密度,
这个概率密度就可以作为随机变量x的概率密度,它表示了在所有y可能的取值下x的分布。
然后求y的条件概率密度,计算方法为
这个条件概率密度就是随机变量y的分布。
在更高维的随机变量下,采样的方法也是一样的,先求其中一个随机变量的边缘概率密度,再求其他随机变量的条件概率密度,每一次操作都会让变量的维数减一,直到剩余一维随机变量为止。
多维随机变量采样示例—对双线性插值函数进行采样
双线性插值函数的形式为:
其中为插值的权重,同样使用之前求pdf的方法,可以求得
代码实现(PBRT):
这是一个二维的随机变量,首先要从联合概率密度中求得边缘概率密度,这里选择求y的边缘概率密度:
可以发现,将常数先忽略,是一个线性插值的函数。
用之前的线性插值函数来采样,
再来求x的条件概率密度:
现在y对于来说也是常数,现将其忽略,可以发现只与相关,将看作以下形式:
则也可以看作一个线性插值函数。
这样采样点p的坐标就确定了。
双线性插值函数(PBRT):