GAMES101-现代计算机图形学学习笔记(16)
Lecture 16: Ray Tracing 4 Monte Carlo Path Tracing
原课程视频链接以及官网
b站视频链接: link.
课程官网链接: link.
Review
课程首先简单回顾了上节的内容:包括渲染方程、概率论:
Monte Carlo Integration
课程随后介绍了 Monte Carlo Integration,它是一种求解定积分的技术。
①直观解释
定积分本质上是求解曲线在区间内与坐标轴所围成的面积。Monte Carlo Integration 是一种近似求解积分的方法,它在所求定积分的函数中随机取样多次,分别对取样得到的 f(x) 值和定积分上下限的矩形求面积,然后将这些面积平均,以近似求解定积分。
②数学定义
定义积分:
∫
a
b
f
(
x
)
d
x
\int_{a}^{b} f(x) d x
∫abf(x)dx 和随机变量:
X
i
∼
p
(
x
)
X_{i} \sim p(x)
Xi∼p(x),那么 Monte Carlo estimator 的计算方式就如下:
F
N
=
1
N
∑
i
=
1
N
f
(
X
i
)
p
(
X
i
)
F_{N}=\frac{1}{N} \sum_{i=1}^{N} \frac{f\left(X_{i}\right)}{p\left(X_{i}\right)}
FN=N1i=1∑Np(Xi)f(Xi)
当然,采样次数越多,该方法求解的定积分结果就越准确。
Path Tracing
为什么需要 Path Tracing ? 是为了解决 Whitted-Style Ray Tracing 中的一些问题,让渲染更加真实。
问题①:Whitted-Style Ray Tracing 在处理光照反射时总是沿着镜面反射方向进行,这适用于镜面材质,但却不适用于 Glossy 之类的材质:
问题②:Whitted-Style Ray Tracing 不考虑物体表面漫反射会进一步反射,但实际上漫反射物体仍会继续反射光线:
相较于这些问题,渲染方程的结果是对的,所以我们只需要按照渲染方程来求解物体表面的着色问题即可:
L
o
(
p
,
ω
o
)
=
L
e
(
p
,
ω
o
)
+
∫
Ω
+
L
i
(
p
,
ω
i
)
f
r
(
p
,
ω
i
,
ω
o
)
(
n
⋅
ω
i
)
d
ω
i
L_{o}\left(p, \omega_{o}\right)=L_{e}\left(p, \omega_{o}\right)+\int_{\Omega^{+}} L_{i}\left(p, \omega_{i}\right) f_{r}\left(p, \omega_{i}, \omega_{o}\right)\left(n \cdot \omega_{i}\right) \mathrm{d} \omega_{i}
Lo(p,ωo)=Le(p,ωo)+∫Ω+Li(p,ωi)fr(p,ωi,ωo)(n⋅ωi)dωi
不考虑自发光项,那么渲染方程就可以写成:
L
o
(
p
,
ω
o
)
=
∫
Ω
+
L
i
(
p
,
ω
i
)
f
r
(
p
,
ω
i
,
ω
o
)
(
n
⋅
ω
i
)
d
ω
i
L_{o}\left(p, \omega_{o}\right)=\int_{\Omega^{+}} L_{i}\left(p, \omega_{i}\right) f_{r}\left(p, \omega_{i}, \omega_{o}\right)\left(n \cdot \omega_{i}\right) \mathrm{d} \omega_{i}
Lo(p,ωo)=∫Ω+Li(p,ωi)fr(p,ωi,ωo)(n⋅ωi)dωi
为了求解这个在球面上的积分,这里就需要 Monte Carlo 方法来近似求解:
L
o
(
p
,
ω
o
)
=
∫
Ω
+
L
i
(
p
,
ω
i
)
f
r
(
p
,
ω
i
,
ω
o
)
(
n
⋅
ω
i
)
d
ω
i
≈
1
N
∑
i
=
1
N
L
i
(
p
,
ω
i
)
f
r
(
p
,
ω
i
,
ω
o
)
(
n
⋅
ω
i
)
p
(
ω
i
)
\begin{aligned} L_{o}\left(p, \omega_{o}\right) &=\int_{\Omega^{+}} L_{i}\left(p, \omega_{i}\right) f_{r}\left(p, \omega_{i}, \omega_{o}\right)\left(n \cdot \omega_{i}\right) \mathrm{d} \omega_{i} \\ & \approx \frac{1}{N} \sum_{i=1}^{N} \frac{L_{i}\left(p, \omega_{i}\right) f_{r}\left(p, \omega_{i}, \omega_{o}\right)\left(n \cdot \omega_{i}\right)}{p\left(\omega_{i}\right)} \end{aligned}
Lo(p,ωo)=∫Ω+Li(p,ωi)fr(p,ωi,ωo)(n⋅ωi)dωi≈N1i=1∑Np(ωi)Li(p,ωi)fr(p,ωi,ωo)(n⋅ωi)
实际上通过该公式就可以简单描述出求解着色的步骤:
- 随机采样 N 次入射方向
- 根据采样的入射方向,针对能够反射到光源的部分,计算 L i ( p , ω i ) f r ( p , ω i , ω o ) ( n ⋅ ω i ) L_{i}\left(p, \omega_{i}\right) f_{r}\left(p, \omega_{i}, \omega_{o}\right)\left(n \cdot \omega_{i}\right) Li(p,ωi)fr(p,ωi,ωo)(n⋅ωi)
- 累加该次求解结果
- 平均,完成着色
同时,还需要考虑反射如果打到物体表面,物体会吸收光源进行二次反射,着色过程描述为:
但是这里还存在几个问题:
问题①:物体表面在进行反射的过程中,反射的光线数目应该为多少?如果反射的光线数目为 N,反射 次数为 M,那么对于一个像素上的射线的计算量都有可能为:
N
M
N^{M}
NM,这个计算量是相当大且呈指数增长的。为了减少计算量,人们将反射的光线数目设为1,而在每个像素处打入多条射线来解决这个问题:
这一步可以在一个循环里面做,即对于一个像素选取不同的位置打入射线以求解着色:
问题②:着色何时停止,即当光线反射多少次后,不再进行反射?这里采用了 Russian Roulette (RR) 来解决这个问题。当满足概率为 P 时,返回除以该概率的着色结果:
L
o
/
P
L_{o} / P
Lo/P ,当概率为 (1-P) 时,就停止反射光线,通过这种方式,我们仍然能够得到正确的着色结果:
E
=
P
∗
(
L
o
/
P
)
+
(
1
−
P
)
∗
0
=
L
o
E=P*(L_{o} / P)+(1-P)* 0=L_{o}
E=P∗(Lo/P)+(1−P)∗0=Lo
转换为伪代码就是:
问题③:光线在反射的过程中打到光源是存在一定概率的,它往往与光源自身大小相关,如果光源过小,会使得大量光线无法打到光源:
这里的做法就是将物体表面接收到的 radiance 分解为两部分:来自光源和来自其他反射物体。对于来自光源的部分,直接在光源上进行采样即可,采样过程就是换积分域的过程,在采样完后我们还需要判断光源能否作用在物体表面:
问题④:在对光源进行采样的过程中,可能会存在光源是无法打到物体的,这时需要判断一下:
经过上述所有步骤,就完成了 Ray Tracing。归纳一下,它的着色步骤描述如下:
1. 给定射线
2. 判断射线是否击中场景中的物体;若击中就记录下该位置,并进入 3 和 4
3. 对光源进采样,判断光源能否对该位置进行作用
4. 对反射后的光线进行采样,判断该光线能否反射到其他物体,如果可以,递归回到 1 ;否则进入 5
5. 返回光源对该位置的作用和其他物体对该位置的作用
光线追踪正确吗? 回答是正确的