上节课的内容:辐射度量学、光线传播、反射方程、渲染方程、全局光照、概率论复习
这节课要介绍一种真实的渲染方法-蒙特卡洛路径追踪
目录
1 简单回顾
1.1 渲染方程(The Rendering Equation)
1.2 概率
2 蒙特卡洛积分(Monte Carlo Integration)
2.1 宏观把握问题(为什么、是什么、怎么做)
2.2 具体公式
2.3.1 举例:
2.3.2 好用在哪里?
2.3.3 需要注意的地方:
3 路径追踪(Path Tracing)
3.1 对比之前的Whitted-Style Ray Tracing
3.1.1 Whitted-Style Ray Tracing无法处理Glossy材质
3.1.2 Whitted-Style Ray Tracing无法处理漫反射物体的反射光线
3.2 渲染方程的物理正确性
3.3 蒙特卡洛解决方案
3.1.1 考虑某一个点的直接光照
3.3.2 如果要引入间接光照?
3.3.3 问题及改进策略
问题1:在递归中,光线数量会以指数级增加,难以承受的计算量。
问题2:递归算法shade没有停止条件
问题3:路径追踪算法效率
问题4:如果光源和着色点之间存在遮挡物
3.4 关于路径追踪的其他问题
3.4.1 遗留问题:点光源怎么办?
3.4.2 学习路径追踪的作用
3.4.3 ray-tracing一词在不同时期的含义
3.4.4 没涉及到的部分
1 简单回顾
1.1 渲染方程(The Rendering Equation)
1.2 概率
2 蒙特卡洛积分(Monte Carlo Integration)
2.1 宏观把握问题(为什么、是什么、怎么做)
为什么要学习蒙特卡洛积分?
答:要解一个定积分。
定积分就是一个函数在某个区间与坐标轴围成的面积,解出来就是一个数。
蒙特卡洛方法怎么做?
一种采样的思想
在积分域内不断采样,得到x对应的y坐标的值。对每一个小长方形都这么做,最后求个平均。
2.2 具体公式
2.3.1 举例:
假设在a~b之间均匀采样,那么采样的概率相同,记作C。
此概率在a~b区间上的积分就是1。
此时C可以解出来,就是1/b-a。
对应于均匀采样的蒙特卡洛积分可以推出来了,将这些值代入之前的公式,并把每一项都有的b-a提出去就可以了。
推广到一般情况,无论我们怎么采样,只要知道采样的PDF(概率密度函数)就可以用f(x)对p(x)求平均,从而得到对函数定积分的近似。
2.3.2 好用在哪里?
只需要知道采样的PDF就可以了
不用关心积分域,积分域已经在PDF中体现了。
2.3.3 需要注意的地方:
采样越多,结果越准确。
对谁采样,就对谁积分:对x积分,就对x采样。
3 路径追踪(Path Tracing)
3.1 对比之前的Whitted-Style Ray Tracing
光线打到光滑物体:沿镜面方向反射或者折射
光线打到漫反射物体:停止
这两件事情是不合理的。
高级: 让我们逐步改进Whitted-Style光线跟踪并形成我们的路径跟踪算法!
3.1.1 Whitted-Style Ray Tracing无法处理Glossy材质
光线打到壶上之后,反射光线不一定是镜面反射的
比如右边金色壶就带点磨砂的感觉,如果还是按照之前的那种方式,就会得到错误的结果。
3.1.2 Whitted-Style Ray Tracing无法处理漫反射物体的反射光线
光线打到漫反射物体时,是会反射光线的,但是whitted选择不处理这部分光,直接停止光线的弹射,那就会在漫反射物体相互作用的一些地方显示为纯黑。我们更希望看到全局光照的那种情况,而且物体上会出现墙面或者其他物体给它的光线,这些光线丰富了物体的暗部。
3.2 渲染方程的物理正确性
渲染方程是一个积分,把从四面八方来的光积分起来。
那么,我们要做的事:
1 解半球积分
2 递归执行
如何用数值方法解一个积分?
3.3 蒙特卡洛解决方案
假设:
场景内有一个相对较大的面光源。
场景内还有一个物体box
各个方向进来的光是均匀的。
3.1.1 考虑某一个点的直接光照
忽略渲染方程里的发光项,这个点的直接光照就是四面八方入射光照经过BRDF作用后,反射到观察方向的结果。
要计算半球上不同方向的积分,需要先对半球方向采样
为算出一个积分,需要先在积分域上进行采样得到样本X,然后计算出蒙特卡洛方法中的f(x)和p(x),两者相除求平均即可。
我们的f(x):积分号里面的所有东西
我们的p(x):均匀采样,1/2*pai。
然后,我们就把一个积分变成了一个简单的求和式子。
对照这个式子就可以写出着色算法。
从摄像机观察方向w0观察,p点给了它多少光?
对半球面的所有方向以一定的概率采样N个方向,对于每一个采样方向wi,连接点p与wi,判断形成的向量是否打到光源,如果打到光源,就计算这一方向对应的值。(只考虑直接光照)
3.3.2 如果要引入间接光照?
如果P点的某个方向的光来自Q点,那么Q点到P点反射了多少光呢?
这个问题可以转化为:从P点观察,Q点给了它反射了多少直接光照。
代码中加入递归部分:
打到光源就用Li,打到物体就是物体Q在-wi上的直接光照:shade(q,-wi)
3.3.3 问题及改进策略
问题1:在递归中,光线数量会以指数级增加,难以承受的计算量。
N=1的时候指数不会爆炸,所以只随机采样一个方向的样本。
用N=1来做蒙特卡洛积分就叫做路径追踪。
如果N!=1,叫分布式光线追踪,现在很少有人提了。
N=1,噪声很大?
那么对一个像素生成多个path,最后求平均即可。
路径追踪:对每个像素发出若干光线,对每条光线做蒙特卡洛积分。此即路径追踪算法。
问题2:递归算法shade没有停止条件
因为现实中光线就是弹射无数次,如果计算中间停下来会损失光线。
这时候人们引入了:俄罗斯轮盘赌
弹夹内装两枚子弹,如果此时生存概率P ( 0 < P < 1)为4/6,那么死亡概率 (1-P)为2/6
我们利用这个机制:
1.以一定的概率P发射一条光线,得到一定的结果Lo之后再除以这个概率P
2.以1-P的概率不发射光线,那么得到的结果是0.
这样操作的话,最终结果的期望仍为Lo。
向算法中加入这个思想
到此为止,就已经是一个正确的path tracing的方法了
问题3:路径追踪算法效率
但这个方法还有个小问题,它的效率不高。
如果一个像素的采样率小,速度快,但会有很多噪声。
问题在哪呢?
我们之前的算法是在看运气,被观测点发出的光线不一定能打到光源,如果光源很小的话,可能需要随机出非常多的光线才能打到光源,这就造成 很多光线都被浪费了。
我们现在是从被观测点向周围均匀地采样,那么我们有没有别的采样方法PDF?
答:直接在光源方向采样。
现在我们想对光源采样,对被观测点积分。这个事蒙特卡洛积分是干不了的,但我们想在形式上先写出来。
只需要知道dA和dw之间的关系就可以写出来了
上式展示了dA和dw之间的关系。
替换式子中的dw,改变积分域。
现在情况就变成了:对光源采样、对光源积分。
改进算法
被观测点最终的radiance由两部分决定
1.光源(直接通过采样光源计算,不需要俄罗斯轮盘赌)
2.其他反射物(间接地,需要俄罗斯轮盘赌)
代码
问题4:如果光源和着色点之间存在遮挡物
那么就加个条件判断就行了
如果存在遮挡物,结果为0
如果不存在遮挡物,正常计算
到此为止,路径追踪就写完了。
3.4 关于路径追踪的其他问题
3.4.1 遗留问题:点光源怎么办?
对于路径追踪来说,点光源真的不好处理,想把点光源做对需要注意很多。
所以建议把点光源做成一个很小的面积光源,来规避问题。
3.4.2 学习路径追踪的作用
写对路径追踪不容易。学path tracing很有用
通过学习可以让我们查漏补缺,对涉及到的数学物理代码等知识加深理解
因为用路径追踪的方法几乎和现实情况100%相似。
真是让人震惊的算法效果!
3.4.3 ray-tracing一词在不同时期的含义
·在较早前的时候:认为ray-tracing就是指whitted-style ray tracing
·近年来:说到ray-tracing可能在说所有光线传播方法的大集合,包括
-(单向/双向)路径追踪
- 光子映射
- 光线传输
-更复杂的,结合更多方法的光线传播方法。比如VCM/UPBP
反正,现在要生成一张图片,要么光栅化、要么光线追踪。
3.4.4 没涉及到的部分
·如何对一个函数均匀地采样?
·蒙特卡洛方法选取什么样的PDF最好?即如何针对性地对某一形状的函数最好地采样?
·编程中的随机数问题?low discrepency sequences可以解决一些问题
能不能结合采样被观测点和光源的方法?
平均问题
一个像素中的结果和radiance的转化:gamma矫正
等等......
最后,敬畏科学。