加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

光线追踪及相关数学原理与实践(一)

(2021-01-07 00:27:21)
标签:

游戏

渲染

光线追踪

分类: 游戏

光线追踪及相关数学原理与实践(一)

 

写在前面

PS:这篇文章主要内容源于以前学习时我记录的一个word文档,现在整理时为了表述更形象些又去找了些用来说明的图片,再加上word里面的数学符号这个平台都不支持,所以又做了不少改动和删减,有的只能上传截图了,排版会有些丑。具体渲染实践也是后来用我自己的渲染器临时渲出来加上去的,为了节约时间出图都用的500*500的分辨率。里面的内容包括案例和推导基本都是当时纯按照自己的理解写的,自我感觉整理的还是非常通俗易懂的。封面图片是在建筑艺术史上将光的魅力运用的比较成功的日本著名建筑——光之教堂。

光线追踪(Ray Tracing)是一门古老而又前沿的渲染技术。

光线追踪在1968年诞生后不久便广泛应用在广告界和电影界,比如1982年迪士尼的《电子世界争霸战》(《Tron》)。《Tron》第一次把CGI(Computer-Generated Imagery)广泛运用在了电影领域,在数字特效发展史上具有里程碑的意义。影片中15分钟的CGI动画总共花费了2千万美元,由MAGI公司制作完成,该公司在70年代还为IBM制作了第一个CGI广告视频。顺便提下时隔28年后迪士尼还上映了这部经典科幻电影的续集《创:战纪》(《Tron:Legacy》)。

光线追踪及相关数学原理与实践(一) 图电影《Tron》镜头

提到光线追踪自然会联想到与之相对的光栅化(Rasterization)。光栅化目前依然还活跃在实时渲染领域,它其实是一种局部照明的渲染方案,缺陷是无法考虑光源的光线经过场景的不断反弹后对最终画面效果的贡献。不同于三角形的光栅化,光线追踪的每条光线可以知道整个场景的信息,以此实现全局光照(Global Illumination)来得到更真实的渲染效果,所以即便在实时渲染领域光线追踪成为主流的渲染技术是必然趋势。2004年梦工厂的《怪物史莱克2》(《Shrek2》)是第一部在镜头中大量使用全局光照的电影。

光线追踪及相关数学原理与实践(一)

图 电影《Shrek2》镜头

2018年Nvidia的RTX平台和Microsoft的DirectXRaytracing(简称DXR)的API的出现打开了实时光线追踪的大门。同年年底EA发行了使用寒霜引擎(Frostbite Engine)开发的游戏《战地5》(Battlefield ),它是第一款支持实时光线追踪的游戏。在后续的几年里支持实时光线追踪的游戏像雨后春笋一般陆续涌现。

光线追踪及相关数学原理与实践(一) 图游戏《Battlefield V》的官方演示Demo画面

因此这不是一篇讲离线渲染的文章,因为区分离线渲染和实时渲染唯一的判定依据就是到底是边使用边渲染还是在使用前已渲染完毕。光线追踪本身是一门技术,不能以技术来区分离线渲染和实时渲染,只不过实时光线追踪起步较晚,目前普及程度还没有离线渲染那么广泛,这主要是受到硬件的制约。但是硬件的发展经常是让人始料不及的,相信大家近几年也能明显感受到,所以我在这个时间点发出了这篇文章。

 

 

 

 

 

一.光线追踪(Ray Tracing

我们先来看下实现光线追踪的两种思路:

(1) Forward Tracing(Light Tracing)

如果用计算机模拟现实中光照现象首先会想到的是:从光源发出光线,每条光线在场景中不断反弹后最终到达屏幕中的某个像素,直到屏幕的所有像素都被画完为止。然而反弹光线其实并不总能到达屏幕,这种渲染的结果就是屏幕上会有大片未被写入过的像素。现实中光线遇到物体表面时会朝其每个可能的方向反弹,虽然每条反弹光线只有很小很小的概率能到达人眼,但由于光源发出的光线数量是无数的,所以才能有足够的光线到达人眼进而聚焦到视网膜来感受到光的刺激。但在计算机的世界里模拟光源发射无数条光线这一操作是不切实际的

PS:这个问题也有些解决方案比如当光线遇到物体表面时强制让光线朝着相机位置所在方向反弹,根据与相机近剪裁平面的交点位置写入相应的屏幕像素。这个方案能缓解但解决不了此问题,因为所有反弹光线也并不能保证会击满所有屏幕像素。

(2) Backward Tracing(Eye Tracing)

依据光的可逆性原理,与之相反的过程就是从眼睛发出光线去追踪光源。具体过程是从相机的位置发射光线(称为Primary Ray或Camera Ray),使每个屏幕像素中心所对应的相机近剪裁平面上的位置都有一条Primary Ray经过,光线在场景中经过不断反弹后击中光源,形成有效的光的传输路径。这样就可以保证屏幕的每个像素都被计算过。

PS:当上面提到“从眼睛发出光线”时,古人可真是像字面上这么认为的:人眼是可以发出光线的,碰到物体后又返回到人眼形成视觉,而提出这一说法的还是伟大的几何之父欧几里德,并发表于著作《光学》中,后被证明是谬论。

所以光线追踪的研究都是基于Backward Tracing。但Forward Tracing也是有用的,只不过不独立使用,这个要到后续篇章才会讲到。下面就开始进入正题部分。

 

1.Ray Casting

光线追踪的理论正式诞生于1968年,由Arthur Appel提出。Backward Tracing的主要问题是当场景中光源比较小时会导致大量的光线因无法到达光源被浪费,Arthur Appel引入了Shadow Ray来解决这个问题:当Primary Ray与物体表面相交后强制让光线朝着光源的方向反弹,这条反弹光线就是Shadow Ray,Shadow Ray如果碰撞到其它物体说明交点在影子里,否则计算光照。由于此算法比较简单,基本就是投射光线,所以也干脆被称为光线投射(Ray Casting)。Shadow Ray的引入可以显著降低图像噪点,大大提升了光线追踪的质量。

但问题也是显而易见的,用Shadow Ray强制设定反弹方向的做法对于朗伯体而言无可厚非,因为朗伯体在法线半球内的反弹光线呈现出一定的无方向性,但是对于其它材质比如金属、玻璃,其反弹光线的方向是遵循相关物理规律的,强制让其射向光源是违背物理规律的,所以对于这些材质的模拟Ray Casting显得无能无力。

 

下图是我搭建的一个场景并用Ray Casting进行渲染的结果,而这张只有简单明暗关系的图像就是光线追踪的伊始。
光线追踪及相关数学原理与实践(一)

图1-1 Ray Casting的实践

 

 

 

2.Whitted Ray Tracing

1979年Turner Whitted在Ray Casting的基础上做出了研究突破,成果被人们称之为Whitted Ray Tracing(简称WRT),算法核心思想是光线碰到非朗伯体时还应该根据物体的表面特性继续发射一些反弹光线进行递归查找光源,这种递归式查找的算法也称为Recursive Ray Tracing。光线与物体表面交互时除了发射Shadow Ray外,如果遇到含有一定金属度的材质则依据反射定律还要发射一条Reflection Ray模拟镜面反射效果,如果遇到的是有透明度的材质则除了Reflection Ray外还需要再发射一条Refraction Ray并依据Fresnel规律混合来模拟折射效果。对于生成的每条射线以后的处理方式依次类推,直到击中光源或超出允许的最大递归深度为止。

关于反射向量的求解大家都熟悉,那折射向量如何求解呢?物理上,光的折射遵循的是斯涅耳定律(Snell's Law):

光线追踪及相关数学原理与实践(一)

上式代表光线从折射率为ηi的介质入射到折射率为ηt 的介质,其中θi为入射角,θt为折射角;数学上,只要思路清晰这个问题其实很简单。在画速写时有句老话叫做意在笔先,同样道理,我们先不着急求解,先思考求一个向量都有哪些数学方法:首先是求反射向量用到的向量加减法;还有一个很重要方法是依据向量共线定理:a(a0) 和b共线的充要条件是存在唯一实数λ使得ba,其中λ=±|b|/|a|,即b =±(|b|/|a|)a。所以求一个向量只需求出模长,然后再找一个与之共线的向量并求其模即可,那么剩下的无非就是画图找长短关系的事了,具体过程如下:

光线追踪及相关数学原理与实践(一)

图1-2 光的折射分析图

光线追踪及相关数学原理与实践(一)光线追踪及相关数学原理与实践(一)

Turner Whitted的算法模拟的镜面反射其实仅限于理想高光表面(比如镜子),并没有考虑这种高光表面到底有多光泽(比如磨砂金属);模拟的折射效果同理也仅限于理想的透明体(比如普通玻璃)而不适合不完全透明的物体(比如磨砂玻璃)。而且每条射线至多会生成3条射线,导致射线数量随着递归深度的增加呈指数增长。在渲染质量方面目前还存在物体边缘的锯齿问题以及投影的硬边缘问题。

 

有了上述理论后就能够渲染玻璃材质了,下图是我用WRT渲染的效果。可以看到凸面玻璃的折射现象——兔子的左侧明显有右侧红墙的景象,而离着较远的左侧绿墙也对兔子的右侧产生些许影响。

光线追踪及相关数学原理与实践(一)

图1-3 WRT的实践

PS:想要知道渲染效果是否正确必须要在现实生活中对材质的光学现象有一定的观察积累。若摄影时玩过玻璃球的话我们知道玻璃球是成完全倒像的。严谨一点表述的话,是有条件的成完全倒像,因为当玻璃球离物理表面比较近时其实呈的是正像,而且起到放大镜的作用。

 

 

 

3.Distributed Ray Tracing

下一个重大研究突破发生在1984年,Robert L. Cook等人提出了分布式光线追踪的算法Distributed Ray Tracing(简称DRT),核心思想是用多条随机分布的光线取代单一的光线。比如每个像素选取N个随机位置各发出一条Primary Ray取代之前只从每个像素中心位置发出一条Primary Ray的方法,N条Primary Ray最终取平均值来实现抗锯齿效果;发射多条朝向光源的Shadow Ray来实现软阴影效果;发射多条以理想镜面反射光线为中心的Reflection Ray,偏移程度取决于材质到底有多粗糙,来模拟光泽度;类似的还可以发射多条以折射光线为中心的Refraction Ray……

当然这么做的副作用也很明显,就是加剧了光线数量的指数爆炸问题。可能还会有人想用DRT的思想对朗伯体也发射多条光线来模拟间接光照,理论上可以,但是会导致更严重的指数爆炸问题,这个问题对计算机非常不友好,导致实践中没有可行性。

上面提到的软阴影概念在此解释一下。在Ray Casting和WRT中我们其实只能对点光源进行模拟,也就是只存在能被光源照亮和不能被光源照亮两种情况,所以影子的边缘是生硬的。然而现实中的光源很少能被当成一个没有大小的点来理解,光源也是具有一定空间的,导致光源产生的影(Shadow)又可以再进一步划分为本影(Umbra)和半影(Penumbra)。如下图所示,Umbra是光源完全照射不到的地方,而Penumbra是能够被光源的一部分区域照亮的地方,被物体对光源进行了不完全遮挡,这就是软阴影现象的由来,当光源相对物体的表面积越大、距离越近时则该现象越明显。

光线追踪及相关数学原理与实践(一)

图1-4 软阴影的形成原理 

下图是我用DRT渲染的效果。在这里我把兔子换成了金属材质,而且并不再限制于WRT里的理想金属,这里用的是较粗糙的磨砂金属,可以看到兔子表面呈现出典型的金属反射现象而且并不是完全光滑的金属。同时也得到了柔和的影子边缘以及清晰的物体轮廓。

光线追踪及相关数学原理与实践(一)

图1-5 DRT的实践

 

 光线追踪的知识是环环相扣、紧密联系的,本篇仅刚开了个头,下文会继续做更深入的讲解。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有