图形学笔记(十四)光线追踪4——蒙特卡洛(Monte Carlo)积分、路径追踪详细过程(Whitted-Style的问题于RR(俄罗斯轮盘赌)算法、Ray Generation)、照片级真实感渲染

图形学笔记(十三)光线追踪3——双向反射分布函数BRDF(反射方程、递归方程)、辐射度量学基础radiometry、立体角、Radiant Energy、Flux、Irrdiance、Radiance
图形学笔记(十五)材质和外观 —— 菲涅尔项、常见材质(微表面材质、各向同性与各向异性)、BSDF、BRDF的性质、测量BRDF

1 蒙特卡洛(Monte Carlo)积分

1.1 用处

蒙特卡洛(Monte Carlo)积分目的是解决定积分,但是它难以积分(不定积分不好求)。
在这里插入图片描述

1.2 方法

1.2.1 基本思想

在积分域内不断采样,获得y值,不断的与ab范围获得一个个长方形,然后把所有长方形的面积相加求平均。

1.2.2 过程

对于给定函数 f ( x ) f(x) f(x)的定积分,定义蒙特卡洛(Monte Carlo)积分。

首先有定积分
∫ a b f ( x ) d x \int^b_af(x)dx abf(x)dx
然后不断的取样,对于每个取样点有 X i ∼ p ( x ) X_i \sim p(x) Xip(x)
最后获得每个采样点的 f ( x i ) f(x_i) f(xi)值,作为长方形的高,然后按照下面的式子相加评分就获得了Monte Carlo方程。
在这里插入图片描述更通用的形式:
∫ a b f ( x ) d x = 1 N ∑ i = 1 N f ( X i ) p ( x i ) X i ∼ p ( x ) \int^b_af(x)dx=\frac{1}{N}\sum^N_{i=1}\frac{f(X_i)}{p(x_i)} \quad X_i\sim p(x) abf(x)dx=N1i=1Np(xi)f(Xi)Xip(x)

注意

  • N越大,得到的结果越精确。
  • 在x上积分就一定要在x上取样。

1.2.3 例子

假如有一个均匀分布的变量。
X i ∼ p ( x ) X_i \sim p(x) Xip(x)
在这里插入图片描述

计算a到b的积分,有
∫ a b p ( x ) d x = 1 = > ∫ C d x = 1 = > C = 1 b − a \int_a^bp(x)dx=1 => \int Cdx=1=>C=\frac{1}{b-a} abp(x)dx=1=>Cdx=1=>C=ba1
如果使用Monte Carlo积分来计算,有如下方程:

F N = b − a N ∑ i = 1 N f ( X i ) F_N=\frac{b-a}{N}\sum^N_{i=1}f(X_i) FN=Nbai=1Nf(Xi)

2 路径追踪(Path Tracing)

2.1 动机:改进Whitted-Style Ray Tracing

Whitted-Style Ray Tracing对光线进行了如下假设:

  • 总是进行镜面反射和折射
  • 光线在漫反射面停止跳跃

2.1.1 Whitted-Style Ray Tracing存在的问题

问题1 如下是Mirror reflection和Glossy reflection,但是对于打到Glossy的物体上的光线,传播的路径不能与Specular完全相同
在这里插入图片描述
问题2 对于漫反射物体,如果光线传播到它的表面上,那么还是会有光线传播的,不应该停止

在这里插入图片描述

color bleeding:面的颜色流到其他的面上去。 就像上方右图高长方体的左面被全局光照映照出红色。

2.1.2 Whitted-Style Ray Tracing问题的解决办法

Whitted-Style Ray Tracing是错的,但是渲染方程是正确的。
L o ( p , ω 0 ) = L e ( p , ω o ) + ∫ Ω + L i ( p , ω i ) f r ( p , ω i , ω o ) ( n ⋅ ω i ) d ω i L_o(p,\omega_0)=L_e(p,\omega_o)+\int_{\Omega^+}L_i(p,\omega_i)f_r(p,\omega_i,\omega_o)(n·\omega_i)d\omega_i Lo(p,ω0)=Le(p,ωo)+Ω+Li(p,ωi)fr(p,ωi,ωo)(nωi)dωi

但是此方程涉及

  • 解半球的积分
    解决方法:使用Monte Carlo积分解渲染方程的积分。
  • 递归
    解决方法:使用俄罗斯轮盘法来结束递归。

2.2 使用Monte Carlo积分解渲染方程的积分

2.2.1 步骤

目的:渲染下面场景的一像素的直接光照。
在这里插入图片描述
ω o \omega_o ωo:观测方向,从着色点到观测方向。
ω i \omega_i ωi:各个不同的入射的方向。

先忽略渲染方程的发光项:
L o ( p , ω 0 ) = ∫ Ω + L i ( p , ω i ) f r ( p , ω i , ω o ) ( n ⋅ ω i ) d ω i L_o(p,\omega_0)=\int_{\Omega^+}L_i(p,\omega_i)f_r(p,\omega_i,\omega_o)(n·\omega_i)d\omega_i Lo(p,ω0)=Ω+Li(p,ωi)fr(p,ωi,ωo)(nωi)dωi

  1. 由Monte Carlo积分 ∫ a b f ( x ) d x = 1 N ∑ i = 1 N f ( X i ) p ( x i ) X i ∼ p ( x ) \int^b_af(x)dx=\frac{1}{N}\sum^N_{i=1}\frac{f(X_i)}{p(x_i)} \quad X_i\sim p(x) abf(x)dx=N1i=1Np(xi)f(Xi)Xip(x)
  2. 寻找f(x)
    f ( x ) = L i ( p , ω i ) f r ( p , ω i , ω o ) ( n ⋅ ω i ) f(x)=L_i(p,\omega_i)f_r(p,\omega_i,\omega_o)(n·\omega_i) f(x)=Li(p,ωi)fr(p,ωi,ωo)(nωi)
  3. 寻找pdf
    p ( ω i ) = 1 2 π p(\omega_i)=\frac{1}{2\pi} p(ωi)=2π1
  4. 得到方程
    L o ( p , ω o ) ≈ 1 N ∑ i = 1 N L i ( p , ω i ) f r ( p , ω i , ω o ) ( n ⋅ ω i ) p ( ω i ) L_o(p,\omega_o) \approx \frac{1}{N}\sum^N_{i=1}\frac{L_i(p,\omega_i)f_r(p,\omega_i,\omega_o)(n·\omega_i)}{p(\omega_i)} Lo(p,ωo)N1i=1Np(ωi)Li(p,ωi)fr(p,ωi,ωo)(nωi)
  5. 引入间接光照(即来源于物体反射的光照):在p点收到的Q点反射来的光照相当于,以p为观测点,Q为着色点的着色结果,所以有L_i=shade(q,-wi)。
    在这里插入图片描述

对于只考虑直接光照,获得算法如下,

shade(p,wo)
	随机选择wi~pdf的N个方向
	Lo=0.0
	for 每个wi
		追踪一个光线r(p,wi)
		if 光线打到了光源
			Lo += (1/N)*L_i*f_r*cosine / pdf(wi)
		else if r达到了一个物体上的q点
			Lo += (1/N)* shade(q,-wi)*f_r*cosine / pdf(wi)			
	Return Lo
	

2.2.2 路径追踪解决光线数量爆炸

使用上面的方法,由于光线跳跃多次,光线的数量会爆炸(有递归): r a y s = N b o u n c e s rays=N^{bounces} rays=Nbounces

解决方法 令N=1,即每次只选取wi~pdf的一个方向。

路径追踪就是上面N=1的算法 ,即每次路径追踪只是随机选择一个方向反射。

shade(p,wo)
	随机选择wi~pdf的1个方向
	追踪一个光线r(p,wi)
	if 光线r打到了光源
		Return L_i*f_r*cosine / pdf(wi)
	else if r达到了一个物体上的q点
		Return shade(q,-wi)*f_r*cosine / pdf(wi)			

但是噪声会很大。但是只要对每个像素trace more paths并求它们radiance的平均就可以减少噪声。如下所示。

在这里插入图片描述

2.2.3 Ray Generation

为了减少噪声,所以每个像素要生成多个光线,进行多次路径追踪,光线生成算法如下。

ray_generation(camPos,pixel)
   在像素中平均的选取N个采样点
   pixel_radiance = 0.0
   For 对于像素中的每个采样点
   	射出一条光线r(camPos,cam_to_sample)
   	如果光线击中了场景中的p点
   		pixel_radiance += 1 / N * shade(p, sample_to_cam)
   Return pixel_radiance

2.3 使用俄罗斯轮盘(RR)解决递归算法停不下来

问题 虽然现实中的光源跳跃也不会停,但是不停的话递归就无法结束。

解决方案 Russion Roulette(RR)俄罗斯轮盘赌。

2.3.1 RR方法概述

设定一个概率,0<P<1。

  • 有概率P,射出光线并且返回着色结果 L o / P L_o / P Lo/P
  • 有概率1-P不射出光线,并返回结果0

用这种方法,仍然可以期望得到值 L o L_o Lo
E = P ∗ ( L o / P ) + ( 1 − P ) ∗ 0 = L o E=P*(L_o/P)+(1-P)*0=L_o E=P(Lo/P)+(1P)0=Lo

2.3.2 RR方法改进后的路径追踪算法

进行如上改进后,得到的代码如下。

shade(p,wo)
	手动指定一个概率 P_RR
	在均匀分布[0,1]范围内随机选择ksi。
	if(ksi>P_RR) return 0.0;

	随机选择wi~pdf的1个方向
	追踪一个光线r(p,wi)
	if 光线r打到了光源
		Return L_i*f_r*cosine / pdf(wi) / P_RR
	else if 光线r达到了一个物体上的q点
		Return shade(q,-wi)*f_r*cosine / pdf(wi)	/ P_RR

这样就能保证递归可以停止。

2.4 提高Path Tracing的效率

问题 经过以上改进,现在路径追踪算法是正确的了,但是它不高效

在这里插入图片描述
如下图所示,如果均匀的四面八方采样,对于很多光线只有极少数打到光源,大部分都被浪费掉了。
在这里插入图片描述

所以我们直接在光源上采样,pdf=1/A,但是渲染方程的积分是在立体角上进行的 L o = ∫ L i f r c o s d ω L_o=\int Li fr cos d\omega Lo=Lifrcosdω

在这里插入图片描述

由于Monte Carlo方程要求在哪里积分就在哪里取样,所以只要 d ω d\omega dω转变成对dA积分即可。

我们得到立体角和光源面积微分 d A dA dA的关系如下:
d ω = d A cos ⁡ θ ′ ∣ ∣ x ′ − x ∣ ∣ 2 d\omega=\frac{dA \cos \theta '}{||x'-x||^2} dω=xx2dAcosθ

然后重写渲染方程:
L o ( x , ω o ) = ∫ A L i ( x , ω i ) f r ( x , ω i , ω o ) cos ⁡ θ cos ⁡ θ ′ ∣ ∣ x ′ − x ∣ ∣ 2 d A L_o(x,\omega_o)=\int_AL_i(x,\omega_i)f_r(x,\omega_i,\omega_o)\frac{\cos\theta\cos\theta'}{||x'-x||^2}dA Lo(x,ωo)=ALi(x,ωi)fr(x,ωi,ωo)xx2cosθcosθdA

现在我们认为着色结果来源于两部分:

  1. 光源的贡献(直接采样光源,无需RR)
  2. 其他反射(indirect,需要RR)

优化后将这两部分结合的代码如下。
在这里插入图片描述
再考虑另一个问题,如果光源和着色点之间被物体遮挡,则直接返回0。
在这里插入图片描述至此Path Tracing算法完成。

2.5 Path Tracing的特点

缺点 路径追踪不好处理点光源。

优点 Path Tracing可以做到照片级真实感PHOTO-REALISTIC(如下所示)。
在这里插入图片描述

3 Raytracing的概念区分

早期

  • Ray tracing==Whitted-style ray tracing

现代

  • 包含所有光线传播方法的集合
  • (单向/双向)path tracing
  • 光子映射 Photon mapping
  • Metropoils light transport
  • VCM / UPBR

猜你喜欢

转载自blog.csdn.net/weixin_43399489/article/details/121617338