之前在学习《Ray Tracing From The Ground Up》时,有总结过“蒙特·卡罗积分”:
Q73:蒙特•卡罗积分(Monte Carlo Integration)
后文内容,主要参考PBRT-V3的13.10章节。
一、重要性采样
对于积分:
Monte Carlo estimator:
“重要性采样”就是根据f(x)的值来调整p(x)的概率分布。
也就是说:f(x)值大的地方,就多采几个点;f(x)值小的地方,就少采几个点。
(f(x)值大的地方说明:这个地方的x对积分结果的贡献大,所以要多采几个点)
p(x)的概率分布和f(x)的值越是接近,Monte Carlo estimator计算的结果越精确。
如果不是“重要性采样”,会怎么样呢?
不是“重要性采样”,也就是说:
case 1,f(x)值大的地方,p(x)的概率分布小;
case 2,f(x)值小的地方,p(x)的概率分布大;
回头看看Monte Carlo estimator,累加的单项是:f(x)/p(x)
“重要性采样”的情况是:大/大+小/小
不是“重要性采样”的情况是:大/小+小/大
问题来了,“大/小”会得到一个很大的值,使得整体的方差增大;
“小/大”会得到一个很小的值,也使得整体的方差增大;
前面的内容只是为了说明一点:
p(x)的概率分布和f(x)的值差异越小,计算的结果越精确;
p(x)的概率分布和f(x)的值差异越大,计算的结果越不精确;
二、复合“重要性采样”
对于这种积分:
怎么采样呢?
f(x)和g(x)都有各自的“重要性采样”对应的概率分布。
f(x)g(x)是用哪一个对应的概率分布进行采样呢?
(假设f(x)g(x)乘积的结果不便采样)
不管用哪一个对应的概率分布,对另一个来说可能都不是“重要性采样”,所以,都会导致计算结果方差增大。
在这种情况下,比较容易想到:
分别用f(x)、g(x)对应的概率分布采样求出两个值,然后对这两个值求平均。
(不好!因为“两个值”的方差都很大,“求平均”并不能消除方差)
“复合重要性采样”的策略是:
不是“分别用f(x)、g(x)对应的概率分布采样求出两个值,然后对这两个值求平均。”
而是“在分别用f(x)、g(x)对应的概率分布采样求积分的过程中,分别乘以各自的权系数”。
权系数函数怎么确定呢?
有个被称为“balance heuristic”的函数是个不错的选择:
这个函数“不错”的原因是:
“分母”的式子“所有可能分子”的累加。
这样,一方面保证所有权系数的和为1;另一方面每一项中都考虑了所有其他项的概率分布。
将这个函数代入前面“复合重要性采样”的式子的第一项:
只要f(x)、g(x)分别对应各自的“重要性采样”,即:
f(x)大,pf(x)大;
f(x)小,pf(x)小;
g(x)大,pg(x)大;
g(x)小,pg(x)小;
这样,前面的式子的值只有如下几种情况:
(大*大)/(大+大)=大/大;
(大*小)/(大+小)=大/大(小/小);
(小*大)/(小+大)=小/小(大/大);
(小*小)/(小+小)=小/小;
可以看出,没有出现增大方差的情况:
大/小;
小/大;
所以,最终计算的结果是比较精确的。
pbrt-v3中的代码实现:
inline Float BalanceHeuristic(int nf, Float fPdf, int ng, Float gPdf) {
return (nf * fPdf) / (nf * fPdf + ng * gPdf);
}
pbrt-v3中实际使用的power heuristic(加上一个指数,对减小方差效果更好)
Veach这个哥们,根据经验发现指数=2时效果不错。
所以,在pbrt-v3中也将该指数固定为2。相关代码:
inline Float PowerHeuristic(int nf, Float fPdf, int ng, Float gPdf) {
Float f = nf * fPdf, g = ng * gPdf;
return (f * f) / (f * f + g * g);
}
三、复合“重要性采样”的应用
pbrt-v3中的DirectLightingIntegrator的实现是基于“复合重要性采样”的。
如果只对f(即BSDF)进行“重要性采样”:
当遇到Ld(即Light)是delta光源(点光源只有一个点发光;平行光光源只有一个发光)时,
大部分(大概率)情况下采样点对应光线的radiance都会是0(小值),
即出现“大/小”的情况,所以计算结果方差很大。
如果只对Ld(即Light)进行“重要性采样”:
当遇到f(即BSDF)包含镜面反射时,
也会出现,
大部分(大概率)情况下采样点对应光线的radiance都会是0(小值),
即出现“大/小”的情况,所以计算结果方差很大。
综上,可能出现“意外”的情况有:
1,对BSDF采样时,遇到“小”光源,效果不好;
2,对Light采样时,遇到“光滑”表面,效果不好;
借用PBRT-V3中14.3章节的图来说明“复合重要性采样”:
对BSDF进行重要性采样时,遇到“大”光源,效果还可以:对比a、c图中的绿色框标注部分。
对Light进行重要性采样时,遇到“粗糙”表面,效果还可以:对比b、c图中的红色框标注部分。
对BSDF和Light进行“复合重要性采样”时,效果最好!!!!!!!!
另外,分别采样时,针对的采样对象可以不一样。
比如:
对Light采样时,是针对“面积”;
对BSDF采样时,是针对“立体角”。
用到复合重要性采样的光传播算法:
Q120:PBRT-V3,“直接光照”积分器(14.3章节)
Q136:PBRT-V3,双向路径追踪(Bidirectional Path Tracing)(16.3章节)
图形学中提到的“采样”一般都是指“重要性采样”。
另外,光线从光源经过一系列碰撞到达相机的过程中,对撞击点处的BRDF进行采样是一定要做的。
所以,“复合重要性采样”中的“复合”是看有没有对光源进行采样。然后将“BRDF采样”和“光源采样”进行“复合”。
Q120:PBRT-V3,“直接光照”积分器(14.3章节)
由于是“直接光照”,所以是将撞击点和光源直接连接。
怎么体现“复合”呢?
对撞击点处的BRDF进行采样,得到入射光,入射光撞击光源,得到“贡献值1”;
对光源进行采样得到一个采样点,连接光源采样点和撞击点来确定入射光线,得到“贡献值2”。
将“贡献值1”和“贡献值2”进行“复合”。
Q136:PBRT-V3,双向路径追踪(Bidirectional Path Tracing)(16.3章节)
从相机出发产生一条子路径CameraSubpath,从光源出发产生一条子路径LightSubpath。
然后连接这两条子路径。
怎么体现“复合”呢?
两条子路径的连接可以产生多条完整路径。
将连接后的完整路径上的贡献值进行“复合”。

&spm=1001.2101.3001.5002&articleId=74989755&d=1&t=3&u=d9502db60d754d9a82d3a2bb0205a33b)
9129

被折叠的 条评论
为什么被折叠?



