本文主要是介绍图形学笔记(十四)光线追踪4——蒙特卡洛(Monte Carlo)积分、路径追踪详细过程(Whitted-Style的问题于RR(俄罗斯轮盘赌)算法、Ray Generation)、照片级真实感渲染,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
图形学笔记(十三)光线追踪3——双向反射分布函数BRDF(反射方程、递归方程)、辐射度量学基础radiometry、立体角、Radiant Energy、Flux、Irrdiance、Radiance
图形学笔记(十五)材质和外观 —— 菲涅尔项、常见材质(微表面材质、各向同性与各向异性)、BSDF、BRDF的性质、测量BRDF
文章目录
- 1 蒙特卡洛(Monte Carlo)积分
- 1.1 用处
- 1.2 方法
- 1.2.1 基本思想
- 1.2.2 过程
- 1.2.3 例子
- 2 路径追踪(Path Tracing)
- 2.1 动机:改进Whitted-Style Ray Tracing
- 2.1.1 Whitted-Style Ray Tracing存在的问题
- 2.1.2 Whitted-Style Ray Tracing问题的解决办法
- 2.2 使用Monte Carlo积分解渲染方程的积分
- 2.2.1 步骤
- 2.2.2 路径追踪解决光线数量爆炸
- 2.2.3 Ray Generation
- 2.3 使用俄罗斯轮盘(RR)解决递归算法停不下来
- 2.3.1 RR方法概述
- 2.3.2 RR方法改进后的路径追踪算法
- 2.4 提高Path Tracing的效率
- 2.5 Path Tracing的特点
- 3 Raytracing的概念区分
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) Xi∼p(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=1∑Np(xi)f(Xi)Xi∼p(x)
注意
- N越大,得到的结果越精确。
- 在x上积分就一定要在x上取样。
1.2.3 例子
假如有一个均匀分布的变量。
X i ∼ p ( x ) X_i \sim p(x) Xi∼p(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=b−a1
如果使用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=Nb−ai=1∑Nf(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
- 由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=1∑Np(xi)f(Xi)Xi∼p(x)
- 寻找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) - 寻找pdf
p ( ω i ) = 1 2 π p(\omega_i)=\frac{1}{2\pi} p(ωi)=2π1 - 得到方程
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=1∑Np(ωi)Li(p,ωi)fr(p,ωi,ωo)(n⋅ωi) - 引入间接光照(即来源于物体反射的光照):在p点收到的Q点反射来的光照相当于,以p为观测点,Q为着色点的着色结果,所以有L_i=shade(q,-wi)。
对于只考虑直接光照,获得算法如下,
shade(p,wo)随机选择wi~pdf的N个方向Lo=0.0for 每个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.0For 对于像素中的每个采样点射出一条光线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)+(1−P)∗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_RRelse 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ω=∣∣x′−x∣∣2dAcosθ′
然后重写渲染方程:
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)∣∣x′−x∣∣2cosθcosθ′dA
现在我们认为着色结果来源于两部分:
- 光源的贡献(直接采样光源,无需RR)
- 其他反射(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
这篇关于图形学笔记(十四)光线追踪4——蒙特卡洛(Monte Carlo)积分、路径追踪详细过程(Whitted-Style的问题于RR(俄罗斯轮盘赌)算法、Ray Generation)、照片级真实感渲染的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!