您的位置:首页 > 其它

3D未来争夺战 光线追踪算法浅析

2010-06-01 22:27 302 查看
光线追踪通过模拟光的自然流动,我们可以模拟有关折射、反射以及光在半透明物质中的行为、阴影以及色渗的物理原理,完成对各类相关效果的模拟。光线追踪算法能够渲染出近乎真实的图片。在之前,人们已经提出多种算法用以提高光透射和光线追踪的速度,比如采用适应性采样、样本复用、减少阴影光线的数量等方法。如果没有在算法上进行优化,目前的显卡还无法实现流畅的实时光线追踪算法。我们处于光线追踪研究的初级阶段大概再过2~3年,我们才有可能看到支持光线追踪的游戏。
如果你看过精美的3D建筑效果图、复杂的好莱坞科幻片,你就会发现他们对玻璃材质、液体的渲染处理远远超越我们日常玩的3D游戏。这是因为他们都采用了光线追踪算法,相比3D游戏的光栅化算法有更真实的表现力。在3DS Max、Maya、Softimage XSI等软件中,无一例外地采用了基于光线追踪(Ray Tracing)和光能传递(Radiosity)的算法。由于光线追踪算法完全符合真实世界中光线的传播、折射、衍射、吸收等过程,所以可以渲染出肉眼无法分辨的3D场景。

随着CPU和GPU性能的爆炸性增长,在过去的几年里,已经有越来越多的公司试图实现实时光线追踪算法。



和当今构建我们实时3D游戏中的光栅化技术不同,光线追踪技术能实现真正基于物理学的水面、倒影、折射等效果。但是光线追踪算法又无比复杂,大部分好莱坞大片渲染一帧就要拥有数千个CPU内核的渲染集群耗费十几个小时,要实现每秒30帧~60帧的实时光线追踪,谈何容易。早在2004年,德国青年Daniel Pohl就通过修改《Quake 3》游戏,引入了光线追踪算法。通过这一翻天覆地的改变,修改版《Quake 3》所展现出的图形效果足以让当时大部分游戏汗颜。之后的几年里,Daniel Pohl更将注意力放到了《Quake 4》、《Quake War》等游戏上,试图在这些游戏中实现实时光线追踪算法。有趣的是,Daniel Pohl的实时光线追踪技术完全不依赖于GPU,仅仅是借助多内核CPU的运算能力“硬抗”。也许正因为如此,Daniel Pohl随后被Intel高薪聘用,继续向实时光线追踪领域迈进。

在Intel披露Lar rabee显卡计划后,就有人惊呼,难道Intel希望用光线追踪代替日常实时3D计算中最基本最传统的光栅化算法,从而在根基上撼动NVIDIA、AMD的统治?2009年3月,一家名不见经传的公司—Caustic Graphics突然浮出水面,带来了一种具有突破性意义的实时光线追踪软硬件解决方案。这家由苹果公司图形部门三大元老创办的公司,声称一举解决了光线追踪算法效率低下的难题。究竟未来实时3D的世界,光线追踪和传统光栅化算法谁主沉浮?我们一起从原理入手,来了解什么是光线追踪。



光线追踪技术实际上是由几何光学通用技术衍生而来。它通过追踪光线与物体表面发生的交互作用,得到光线经过路径的模型。简单地说,3D技术里的光线追踪算法,就是先假设屏幕内的世界是真实的,显示器是个透明的玻璃,只要找到屏幕内能透过人眼的光线,加以追踪就能构建出完成的3D画面。

在真实世界里,光线投射到物体表面的时候,会出现三种情况。这就是光线的吸收、反射、折射。光线被反射到不同地方被选择性地吸收后,光谱就会随之改变。经过多次的折射和反射,光线就会进入我们的眼睛,然后被我们感知。光线追踪技术就是要计算出光线发出后经过一系列衰减再进入人眼时的情况。





际算法中,渲染引擎会为每个像素赋予一束光线,光线沿着直线传播,然后与场景中的各个物体交汇,根据开发者赋予这些物体的属性,光线的传播路径、颜色、强度都会发生变化,最终所有的光线会在屏幕视点上汇聚,从而构建出我们所看到的3D世界。在光线追踪计算中,光线还被分门别类,其中主光线和光栅化系统中的Z-Buffer一样,是用来判断物体是否可见的。如果主光线不可见,那光线追踪引擎就会直接抛弃整条光线路径。如果主光线被判断为可见,那接下来光线追踪引擎还会计算其余的辅助光线。根据光线性质不同,辅助光线被分成了Shadow Rays(阴影光线)、Reflection Rays(反射光线)、Refraction Rays(折射光线)三大类别。在主光线完成可见度判别后,这三类光线就将完成剩下的包括色彩、透明度等操作。





由于光线追踪算法和现实世界中的物理规则几乎一样,所以在构建精美的3D场景的时候,就有了得天独厚的优势。在画面质量上,光栅化在光线追踪算法面前几乎没有还手之力。光栅化技术要实现媲美光线追踪算法一样的真实场景反射、折射效果,对开发者而言简直是噩梦。









在当今大部分游戏中,实现环境光反射效果都使用了Environment Map(环境贴图)技术。这种技术可以比较好地欺骗玩家的眼睛,特别是实现远处细小物体的反射效果,但当我们靠近3D物体仔细观察的时候,环境贴图就会露出马脚。环境贴图效果实际上只能对一张静态图片进行处理,在你仔细观察的时候,就会发现环境贴图里面的景物不过是开发者之前预设的障眼法,无法根据实时状况发生变化。

在大部分赛车游戏中为了实现近距离车身的反光而不穿帮,大多使用了动态立方贴图(Dynamic Cube Map)技术。立方贴图技术允许开发者将场景视点和玩家观察角度保持一致,然后再重新渲染画面,把渲染结果保存下来供渲染使用。立方贴图虽然看上去不容易穿帮,但仔细观察你就会发现问题。自然界中的光线总是会存在不断的相互反射,例如上图中,使用立方贴图技术实现的茶壶,虽然很好地反射出了飞机,但却无法在茶壶口上出现飞机的反射画面。在现实世界中,不仅仅是光滑的茶壶壁上会反射出飞机,在茶壶口上依然会出现飞机的倒影。





你千万别以为我们在吹毛求疵,事实上要实现图中如此逼真的反射效果已经需要巨大的运算量,通过立方贴图实现的反射,往往需要重复渲染多次。而在渲染过程中,立方贴图也不像传统3D画面那样重新计算视点和坐标。为了获得理想的运行速度,日常游戏中大多只在近处使用立方贴图,为了避免大幅降低显卡填充率,在使用立方贴图的时候很多游戏开发者还故意使用了低分辨率渲染。至于游戏中的其他反射,由于显卡性能限制,大多只是用简单的环境贴图实现。

如果用光线追踪来实现各种反射效果会怎么样?根据我们上面介绍的光线追踪特性,这个技术可以用算法控制整个3D场景中的所有反射效果。在光线追踪计算中,所有的反射效果都能被计算在内,就连漫反射和多次反射都不会漏掉。以下方汽车渲染图为例,这辆布加迪车身的反射不仅相当真实,就连赛车背后的玻璃表面的反光也和现实世界完全吻合,如果使用光栅化算法要实现这样的效果,开发者的工作量简直难以想象。





如果说反射效果是光栅化和光线追踪算法的试金石的话,那透明效果的实现,就是光栅化算法和光线追踪算法的分水岭。传统的光栅化算法要获得准确的透明效果,十分依赖透明多边形在渲染序列中的位置。一般来说,透明多边形必须在最后被渲染处理,并且最好远离视点附近的物体。这样一来,开发者不仅需要耗费大量的时间精力在安排渲染顺序上,还需要确保调整过的渲染顺序不至于渲染出错误的结果。在业界包括A-Buffer等技术都被开发出来辅助实现透明效果,但这些技术大多收效甚微,没办法成为业界标准。要处理透明效果,光线追踪算法完全不费吹灰之力——还记得我们之前介绍的反射、折射辅助光线吗?即便是透明物体,也因为表面发生反射才能被人眼所看到,对于光线追踪算法而言,透明物体和不透明物体在处理上没有任何区别。

在阴影处理方面,光线追踪算法也同样有着得天独厚的优势。传统的光栅化渲染中,处理阴影大多使用阴影贴图的方式,这样的方式需要耗费大量的显存,并且难以实现抗锯齿效果。而在光线追踪算法中,光影计算是整个算法最基础的部分,无需对渲染引擎做任何修改就能实现真实的渲染效果。





曲面处理同样是光线追踪算法最为擅长的领域。在当今各种3D游戏引擎中,要处理曲面大多是通过镶嵌细分曲面(Tessellation)来实现,简单地说就是把一个曲面自动用更多的多边形填充以获得“圆滑”的显示效果。要实现这个功能,对于开发者而言并不费劲,但却会极度消耗GPU资源。即便是微软也只是在DirectX 11中有限地引入对Tessellation功能的支持——在DirectX 11以前,Tessellation曲面处理技术只是各个显卡厂商的独家标准,没有任何兼容性可言。

光线追踪算法如果遇到曲面,又该怎么处理呢?难道也是把弧形拆分成若干三角形吗?非也,任何曲面都将导致光线传播路径的变化,也就是说只要计算出光线的交点,就能精确地得知渲染对象曲面的各个数值,更无需为复杂的三角形填充。



尽管在反射、阴影效果方面光线追踪算法有着压倒性的优势,但是光线追踪并不是完美的3D世界的解决之道。许多人游戏玩家以为,运用了光线追踪算法,就能获得类似于皮克斯动画、好莱坞大片那样的惊人效果,但事实上这样的想法是毫无道理的。

皮克斯和众多好莱坞大片,大多使用合成图片效果来构建虚拟世界。其中皮克斯使用了被称作REYES的基于光栅化原理的渲染算法。而光线追踪仅仅作为辅助渲染技术被引入到了其自家的Renderman渲染器中。一直到《Cars(汽车总动员)》这部动画,皮克斯才首次引入光线追踪算法。根据皮克斯的说法,即便是只用光线追踪算法来处理环境光吸收(ambient occlusion)等复杂计算,也让《汽车总动员》的运算量大幅增加,成本陡增不少。





在光栅化算法中,最终输出一个场景只要首先用像素填满3D场景中的三角形,然后再确定像素点之间的深度距离,以确定哪个像素会被显示。在这样的过程中,光栅化算法速度和复杂度只取决于场景中三角型的多少。在光线追踪算法中,渲染器首先要从观察者角度,投射出光线以确认哪个三角形距离最近,然后再计算出每个三角形距离观察者(也就是显示器平面)的距离。从原理上看,光线追踪算法似乎并不因为三角形的增加而导致运算量增加和性能下降。但在实际过程中,仅仅是计算三角形是否会和光线相交就已经要把整个场景中的所有三角形计算一遍。而在光栅化算法中,所有开发者都使用BSP(Binary Space Partition)空间二叉树算法来判断哪些三角形会被显示,哪些会被丢弃。这样一来,光栅化算法就能大幅减少每个场景的三角型填充计算量,以实现比光线追踪快得多的渲染速度。

什么是BSP树 BSP树就是用来对N维空间中的元素进行排序和查找的二叉树,它被用来在空间中消除隐藏面。BSP树表示整个空间,BSP树中的任意一个结点表示一个子空间,这些结点将分成两个子空间,作为上面结点的子结点。





每个结点除了保存其两个子结点的引用以外,还可以保存一个或多个元素。上述过程是一个递归过程,直至每一子空间仅包含一个多边形为止。通过BSP树程序员可以选择性的渲染只被人们看到的多边形,而不必理会被遮挡或被覆盖的多边形。


光线追踪有着如此明显的优势,而且在实现方法上和现在的光栅化算法也没任何“不共戴天”之仇,那为什么我们至今仍然没有看到任何显卡能提供实时光线追踪渲染呢?答案首先是光线追踪惊人的运算量,即便光线追踪是并行度相当高的运算,在多内核时代计算机并行性能和内核数量几乎呈线性增长关系,但要实现每秒30帧的实时光线追踪计算,依然有很远的路要走。

根据Intel和Daniel的说法,要用光线追踪渲染出达到现代游戏的画面质量,同时跑出可流畅运行的帧数,每秒需要计算大概10亿束光线。这个数字包括每帧每像素需要大概30束不同的光线,分别用来计算着色、光照跟其它各种特效,按照这个公式,在1024×768这样的入门级分辨率下,一共有786432个像素,乘以每像素30束光线以及每秒60帧,我们就需要每秒能运算141.5亿束光线的硬件,而Intel双路4内核处理器每秒也不过只能处理830万束光线。





虽然光线追踪算法有着极高的并行度,但光线追踪中主光线仅仅是为了判别多边形是否可见而存在,和传统光栅化的Z-Buffer计算方式一样,对画质不会有任何贡献。更要命的是,光线追踪的辅助光线每一条都没有任何相关性,这意味着包括各种缓存技术在内的“投机取巧”方式都没有用武之地,计算光线追踪辅助光线的所有的计算都将直接读取内存—这对于内存延迟和带宽来说都是惊人的考验。

在过去的几年间,显卡显存延迟的降低小得可怜。根据某显卡厂商的统计预期,在2004年显卡内存延迟大约在40ns左右,到了2014年显卡延迟也不过减少到了23ns—在10年间节省出来的17ns显然无法满足光线追踪技术的需要。而在这10年里,显卡的晶体管数量会从2.2亿只增加到22.37亿只。

既然传统的显卡架构和发展趋势,完全无法满足光线追踪算法的需求,那推倒重来会怎么样?2003年德国SaarLand大学就拿出了业界首个硬件加速光线追踪算法方案,这个被称作SaarCOR的光线追踪加速卡,使用FPGA(Field Programmable Gate Array现场可编程门阵列)堆砌,在66MHz的频率下就能获得和Pentium 4 2.5GHz相当的光线追踪性能。随后SaarCOR的研发人员接触到了IBM德国的技术人员,获得了一台拥有一枚CELL处理器的工程样机。在IBM技术人员的协助下,SaarCOR在短短两周的时间里就在这台机器上实现了全屏的实时光线追踪渲染效果。SaarCOR的研究人员目前已经在Cinema-4D上以插件方式实现了实时光线追踪。golem还透露了另外一个鲜为人知的消息,那就是SaarCOR其实获得了NVIDIA 2.5万美元的赞助,之前的F PGA原型就是在NVIDIA资助下进行的。SaarCOR至今未能量产,随后SaarCOR项目并入了OpenRT光线追踪开发项目中。





Caustic 1光线追踪卡采用PCI-E 1.0 x4接口,两块黑色散热片下边就是两颗传说中的“光线追踪处理器”(RTPU)。其实这些“处理器”只是简单的FPGA(现场可编程门阵列),运行频率100MHz,每颗搭配自己的一条64bit DDR2 SO-DIMM内存,另外蓝色散热片之下是PCI-E桥接芯片,总功耗约20W。

在2009年3月,光线追踪的困局,由一家叫Caustic Graphic的公司打破。根据该公司的说法,他们的算法之所以独特是因为它解决了传统光线追踪算法偏向随机性的问题。新算法大幅提高了光线追踪计算地局部性,但这部分的算法需要一颗协处理器来完成。Caustic Graphics的工程师们相当明智,他们对于该硬件的定位仅仅是一颗专注于光线追踪运算的协处理器,而绝不会干越俎代庖的蠢事—Shader之类的传统光棚化操作依旧由GPU来完成。

我们之前已经提及,实现硬件光线追踪加速的命门在于存储子系统,Caustic展示的Caustic 1号样卡仅仅搭配了一条64bit DDR2 SO-DIMM内存,这和RV770的GDDR5显存规格对比有较大差异。由于知识产权保护,Caustic Graphics没有披露他们是如何解决存储瓶颈的,但在一个包含500万个三角形(包括两辆汽车的360万个)的场景中,所有可见效果都是使用一块Caustic 1光线追踪卡程序化光线追踪渲染而来的,实时帧率大约为3fps~5fps——这个数字虽然已经数十倍领先于显卡,但austic Graphics坦言,完全实现实时光线追踪化的游戏引擎还得等很多年,并估计至少四五年后他们的硬件才能在1920×1200分辨率下达到60fps的有效帧率。
在画面质量上拥有压倒性优势,在运算量上有着明显的劣势,这两大因素都让光线追踪算法看上去很美,用起来很累。由于当今显卡和CPU性能的制约,光线追踪始终无法达到实时可用的地步。与此同时,光栅化算法也没有在原地踏步,以《Forza赛车3》、《GT5》等游戏为首的光栅化算法阵营,已经逐步***出了以假乱真的汽车反光效果和透明效果,如果不仔细看,很少有人能找到瑕疵。





可以预见在未来的5年间,光线追踪算法都只能活跃在离线渲染领域,以供人们制造出一张又一张以假乱真的效果图和艺术作品。在实时计算和游戏领域,仍将是光栅化算法的天下。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: