这里回顾GAMES101 Lecture 16,蒙特卡洛积分与路径追踪。

课程主页:

课程作业:

课程视频:

本讲内容

  • 简要回顾
  • 蒙特卡洛积分
  • 路径追踪

蒙特卡洛积分

蒙特卡洛法是求解定积分的一种方法,即对于定积分:

考虑随机变量:

那么有蒙特卡洛估计器:

我们来计算$F_N$的数学期望:

特例

考虑均匀分布:

此时蒙特卡洛估计器为:

一些笔记

  • 采样点越多,方差越小;
  • 蒙特卡洛积分关于$x$采样,关于$x$积分;

路径追踪

动机

Whitted-Style光线追踪:

  • 始终执行镜面反射/折射;
  • 在漫反射表面停止反射;

这些简化合理吗?

  • 让我们逐步改进Whitted-Style的光线追踪并引入我们的路径追踪算法!

Whitted-Style光线追踪问题

对于有光泽的材质,光线应该在哪里反射?

diffuse物体没有反射?

所以Whitted-Style光线追踪是错误的,正确的是渲染方程:

那么接下来是如何求解该方程,注意到该方程设计:

  • 求解半球上的积分;
  • 递归定义;

蒙特卡洛法

对于第一点,我们利用之前介绍的蒙特卡洛积分进行求解。假设我们要在以下场景中渲染一个像素(点),$\omega_o$是观测点,光源的方向为$\omega_i$:

我们忽略发光项,那么渲染方程为:

为了使用蒙特卡洛法,我们选择$f(x)$和pdf:

  • $f(x)=L_i\left(p, \omega_i\right) f_r\left(p, \omega_i, \omega_o\right)\left(n \cdot \omega_i\right)$
  • $g\left(\omega_i\right)=1 / 2 \pi$
    • 我们选择在半球上均匀采样;

那么:

伪代码:

shade(p, wo)
    Randomly choose N directions wi~pdf
    Lo = 0.0
    For each wi
        Trace a ray r(p, wi)
        If ray r hit the light
        	Lo += (1 / N) * L_i * f_r * cosine / pdf(wi)
    Return Lo

引入全局照明

让我们再进一步:如果光线打到物体会发生什么?

上图中$Q$将光线反射到$P$,那么$P$点的Incident Radiance即为$Q$点的Incident Radiance,所以伪代码可以改进为:

shade(p, wo)
    Randomly choose N directions wi~pdf
    Lo = 0.0
    For each wi
        Trace a ray r(p, wi)
        If ray r hit the light
        	Lo += (1 / N) * L_i * f_r * cosine / pdf(wi)
        Else If ray r hit an object at q
        	Lo += (1 / N) * shade(q, -wi) * f_r * cosine / pdf(wi)
    Return Lo

问题

上述算法有两个问题:

  • 光线数量随着反射次数呈指数增加:
    • $# \text { rays }=N^{ #bounces }$
  • 算法是递归算法,但是没有终止条件;

问题1

对于第一个问题,我们选择的方式是选择$N=1$,即每次只考虑一根光线,此时代码为:

shade(p, wo)
    Randomly choose ONE direction wi~pdf(w)
    Trace a ray r(p, wi)
    If ray r hit the light
    	Return L_i * f_r * cosine / pdf(wi)
    Else If ray r hit an object at q
    	Return shade(q, -wi) * f_r * cosine / pdf(wi)	

注意,这就是路径追踪,$N\neq1$的情形为分布式路径追踪。

该方法可能会噪声较大,但实际中没有什么问题,因为我们需要对每个像素求radiance,而每个像素会有很多个光线穿过,只需通过每个像素追踪更多路径并平均它们的radiance即可:

光线生成

上述描述也为光线生成的过程:

ray_generation(camPos, pixel)
    Uniformly choose N sample positions within the pixel
    pixel_radiance = 0.0
    For each sample in the pixel
    	Shoot a ray r(camPos, cam_to_sample)
    	If ray r hit the scene at p
    		pixel_radiance += 1 / N * shade(p, sample_to_cam)
    Return pixel_radiance

问题2

为了解决第二个问题,我们需要引入Russian Roulette (RR) (俄罗斯轮盘赌):

  • 以$0<P<1$的概率成功;
  • 以$1-P$的概率失败;

现在假设我们手动设置一个概率$P(0<P<1)$:

  • 以概率$P$,发射一条光线,返回着色结果除以$P$:$L_o/P$;

  • 以概率$1-P$,不发射一条光线,你会得到$0$;

  • 此时期望仍然为$L_o$:$E=P ( { L_o } / P)+(1-P) 0=\text { Lo }$

算法

shade(p, wo)
    Manually specify a probability P_RR
    Randomly select ksi in a uniform dist. in [0, 1]
    If (ksi > P_RR) return 0.0;
    
    Randomly choose ONE direction wi~pdf(w)
    Trace a ray r(p, wi)
    If ray r hit the light
    	Return L_i * f_r * cosine / pdf(wi) / P_RR
    Else If ray r hit an object at q
    	Return shade(q, -wi) * f_r * cosine / pdf(wi) / P_RR

路径追踪问题

现在我们已经有了正确版本的路径追踪,但是不高效:

不高效的原因是,当光源很小时,需要发射很多光线才能打到光源,即如果我们在阴影点对半球进行均匀采样,就会“浪费”很多光线:

这里的关键点在于,我们是对着光线进行采样,如果对光源采样则可以避免这点,注意此时做变量替换,首先注意光线和着色点的关系:

我们考虑立体角,那么有:

此时积分公式为:

现在我们考虑来自两个部分的辐射(RR表示俄罗斯轮盘赌):

  1. 光源(直接,无需RR);
    1. 利用刚刚介绍的公式;
  2. 其他反射器(间接,RR);

此时算法为:

shade(p, wo)
    # Contribution from the light source.
    Uniformly sample the light at x’ (pdf_light = 1 / A)
    L_dir = L_i * f_r * cos θ * cos θ’ / |x’ - p|^2 / pdf_light
    
    # Contribution from other reflectors.
    L_indir = 0.0
    Test Russian Roulette with probability P_RR
    Uniformly sample the hemisphere toward wi (pdf_hemi = 1 / 2pi)
    Trace a ray r(p, wi)
    If ray r hit a non-emitting object at q
    	L_indir = shade(q, -wi) * f_r * cos θ / pdf_hemi / P_RR
    	
    Return L_dir + L_indir

最后一个问题

如果有物体遮挡该怎么办?判断物体是否在光源和着色点之间即可:

算法:

# Contribution from the light source.
L_dir = 0.0
Uniformly sample the light at x’ (pdf_light = 1 / A)
Shoot a ray from p to x’
If the ray is not blocked in the middle
	L_dir =

效果展示

最后展示一下效果:

我们没有覆盖/不会覆盖的内容

  • 对半球进行均匀采样
    • 如何? 一般来说,如何对任何函数进行采样?
      (采样)
  • 蒙特卡洛积分允许任意pdf
    • 最好的选择是什么? (重要度抽样)
  • 随机数重要吗?
    • 是的! (低偏差序列)
  • 可以采样半球和光线
    • 我可以把它们结合起来吗? 是的!(multiple imp. sampling )
  • 一个像素的辐射度是通过它的所有路径的辐射度平均值吗?
    • 为什么? (像素重构滤波器)
  • 像素的radiance 是像素的颜色吗?
    • 不是(伽马校正、曲线、色彩空间)