实时光线追踪技术简介

h5b2a 发表于 2020-05-27 23:21:13

标签: webgl, ray casting

- +

实时渲染视频级别的计算机三维图形是计算图形领域的终极目标,与现在普遍使用的光栅化渲染技术相比,光线追踪普遍被视为视觉技术的未来方向,可带来近乎真实的真正电影级图形和光影物理效果,光线追踪算法是达到这个目标的圣杯,经过几十年的努力,终于要接近这个理想了。


视觉技术的圣杯:光线追踪如何再现真实世界?

光线追踪的定义和原理

而大家在游戏中对水面之类的场景并不陌生,不过它所生成的画面效果,好像永远都不那么真实。即使人们尽再大的努力,它的画面始终还是动画,和人们心目中的“电影级别的画质”总是差那么一点。这是因为,我们目前的游戏,无一例外都在使用光栅化算法。而在这些电影中,则采用的是光线追踪算法。在3DSMax、Maya、SoftimageXSI等软件中,也都无一例外地采用了这一算法。


光线追踪技术是由几何光学通用技术衍生而来。它通过追踪光线与物体表面发生的交互作用,得到光线经过路径的模型。


简单地说,3D技术里的光线追踪算法,就是先假设屏幕内的世界是真实的,显示器是个透明的玻璃,只要找到屏幕内能透过人眼的光线,加以追踪就能构建出完整的3D画面。


说到光线追踪,就不得不提光栅化。


光栅化是指把景物模型的数学描述及其色彩信息转换至计算机屏幕上像素的过程。使用光栅化,我们可以将几何图形转化成屏幕上的像素。


Direct3D使用扫描线的渲染来产生像素。当顶点处理结束之后,所有的图元将被转化到屏幕空间,在屏幕空间的单位就是像素。点,线,三角形通过一组光栅规则被转化成像素。光栅规则定义了一套统一的法则来产生像素。光栅得到的像素一般会携带深度值,一个RGB Adiffuse颜色,一个RGB specular颜色,一个雾化系数和一组或者多组纹理坐标。这些值都会被传给流水线的下一个阶段像素的处理,然后注入到渲染目标。由于实时3D渲染程序要求对用户的即时操作做出迅速反应,因此通常要求每秒至少20帧以上的渲染速率,这也使得高效率的“光栅化”渲染技术成为当今最受青睐的3D即时成像技术。但是光栅化的缺点也很明显,那就是无法计算真实的光线,导致很多地方失真。


光线追踪算法分为两种:正向追踪算法和反向追踪算法。


其中,正向追踪算法是大自然的光线追踪方式,即由光源发出的光经环境景物间的多次反射、透射后投射到景物表面,最终进入人眼。


反向追踪算法正好相反,它是从观察者的角度出发,只追踪那些观察者所能看见的表面投射光。就目前而言,所有3D制作软件的光线追踪算法都是采用反向追踪法,原因是这种算法能够最大程度地节省计算机的系统资源,而且不会导致渲染质量的下降。


在现实世界中射到物体表面上通常有三种情况:折射,反射,吸收。光线在经过反射到不同的地方,被选择性吸收,从而光谱发生改变,再多次反射与折射,最终进入我们自己的眼睛。而光线追踪技术要做的就是模拟这一过程。


在渲染中,光线追踪会赋予每一个像素几条甚至几十条光线,然后光在场景中传播,与场景中各个物体产生交汇,而场景中的物体在事先就已经被开发者设置好了属性,从而导致光束发生各种改变,最终聚集在屏幕上。从而被我们感知。


而反向追踪方式则是计算最终射入我们眼睛的光线的反向光路,即眼睛—物体—光源的过程。因为这么做的话,可以省掉很多并不需要计算的光路,在光线追踪中,并不是每一束光都有用。有些光最终并没有射入我们自己的眼睛,但是如果依旧计算的话就会造成不必要的计算资源浪费。在光线追踪中,光同样也被分类,假设一条主光线是不可见的,那么系统则会抛弃掉整条光路,如果可见的话,那么辅助光线(反射,折射,阴影)的计算就开始了。在完成主光线的判别之后,辅助光线的其他属性(透明度,色彩)操作也已经基本完成了。


光线追踪在图形渲染中的应用

将光线追踪算法应用于图形渲染最初是由Arthur Appel于1968年提出,那时还叫ray casting。


1979年Turner Whitted带来了新的研究突破:递归光线追踪算法《Recursive RayTracing Algorithm》。


1984年,Carpenter等人发表了一篇分布式光线追踪的论文《Distributed RayTracing》,影响甚广。发展到今天,大多数的照片级渲染系统都是基于光线追踪算法的。基本的光线追踪算法并不难,相信大部分计算机图形学的同学都写过的,难的是如何优化提高效率。


说到皮克斯直到《汽车总动员》才开始大规模使用光线追踪。皮克斯的《汽车总动员》于2006年6月在美国上映,如今已经8年多过去了。皮克斯一直使用的是自家开发的渲染器RenderMan,基于REYES(Renders Everything You Ever Saw)。


REYES是另一种渲染算法,它对于处理复杂场景非常高效。


1984年的时候皮克斯有考虑过光线追踪,但最终还是坚持使用REYES。那篇关于《汽车总动员》的论文《RayTracing for the Movie“Cars”》里提到五年前他们就启动了添加光线追踪功能到RenderMan这个项目,同期《汽车总动员》正在制作中。REYES在处理反射强烈的汽车表面材质方面有些捉襟见肘,只能用环境贴图,但仍然达不到光滑闪耀的质感。而这正是光线追踪擅长的。


下面介绍几个使用光线追踪的主流渲染器:


Mentalray,NVIDIA出品,已经集成到3D建模软件Autodesk的Maya和3ds Max中。


Arnold近些年日渐风行,Sony Pictures Imageworks,Digital Domain,ILM,Luma Pictures等著名特效公司均有使用该渲染器。


VRay,比Arnold大众一点,近几年也在疯长,它目前有CPU版本和GPU版本(V-Ray和V-Ray RTGPU)。


光线追踪目前多用于影视特效中做静帧渲染,但对大众最有影响的3D图形游戏领域显然还没有光线追踪的踪影,这是为什么呢?


光线追踪迟迟不能应用在游戏行业中的原因很简单——它那恐怖的计算量。即便是用了反向追踪算法之后也是如此。


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


而即便到了今天,顶级的Corei7每秒能处理的光线还不足千万条。而且这只是运算量上的差距,由于光线追踪的辅助光线每一条都没有任何相关性,这意味着包括各种缓存技术在内的“投机取巧”方式都没有用武之地,计算光线追踪辅助光线的所有的计算都将直接读取内存,这对于内存延迟和带宽来说都是惊人的考验。而且对于显存容量也是一个不小的挑战,十几甚至几十GB的显存会变的非常有必要。


虽然在游戏领域引入光线追踪是有极大挑战的事情,但这项技术一直有研究机构和图形处理器厂商在投入研究。光线追踪若想要应用到游戏中就需要做到实时渲染,就是大家所说的实时光线追踪(Real-time raytracing)。


光线追踪算法前面说过了,那什么样才是实时的?


6FPS左右就可以产生交互感,15FPS可称得上实时,30fps不太卡,60FPS感觉平滑流畅,72FPS再往上肉眼就已经分辨不出差别。


所谓实时就是需要达到每秒渲染30帧以上,否则就达不到画面的流畅度要求,就没有实用价值。实时的光线追踪的难点就在于场景复杂度和需要的真实感渲染效果决定了遍历和相交检测的巨大计算量(场景分割数据结构的重构和光线与场景的相交测试是两项主要计算)。


这是渲染领域以及任何模拟计算领域里终极的矛盾:效率和质量的矛盾。


possitive(14) views5614 comments1

发送私信

最新评论

㌍㌫㌶㍊㍍㍑㌫㌶㍍㌫㌍ 2020-07-25 17:49:09

光线追踪效果看着真棒


请先 登录 再评论.
相关文章
  • CentOS6 Apache2.2多站点HTTPS配置

    可以使用letsencrypt(certbot)免费证书服务。支持多系统、多站点和多目录,支持wildcard(通配符域名),90天生效,可用定时任务自动更新。需要注意一点的是apache2.4以下版本需要在默认的ssl配置中添加如下的指令:NameVirtualHost

  • 如何使用BabylonJS加载OBJ或STL模型

    BabylonJS(也就是babylon.js,这是一个和three.js类似的WebGL开发框架),更多的用在游戏领域。
    本文说明和演示如何使用babylon.js来加载一个标准3d模型文...

  • ES6小知识:动态对象键(Dynamic Object Keys)语法简介

    在ES5,对象的键(key)总是被解释为字符串。ES6允许我们使用计算的值作为对象的键,使用方括号:[myKey]const

  • 深入理解JS和CSS3动画性能问题和技术选择

    本文对比了JS及其框架和CSS3的动画性能,并深入剖析了其内在原因。技术结论大致如下:1. jQuery出于设计原因,在动画性能上表现最差2. CSS3由于把动画逻辑推给了...

  • HTTP1.1协议现状、问题和解决方案

    HTTP的现状最早的HTTP协议非常简单,只能用来传送文本,方法也只有GET,后来逐步发展到1.1,能够支持多种MIME格式数据(如文本、文件),支持GET,POST,HEAD,OPTI...

  • 使用SVG和CSS3创建圆形进度条动画

    圆形进度条是一个经典的控制面板元素,常用于显示任务进度,比如用户档案的完整程度,或者升级状态。有很多方法来实现圆形进度条,比如用JS, CSS3, Canvas, SVG...

  • 粒子运动模拟 - Verlet积分算法简介

    Verlet算法是经典力学(牛顿力学)中的一种最为普遍的积分方法,被广泛运用在分子运动模拟(Molecular Dynamics Simulation),行星运动以及织物变形模拟等领域...

  • 纹理基础知识和过滤模式详解

    1、 为什么在纹理采样时需要texture filter(纹理过滤)。
    我们的纹理是要贴到三维图形表面的,而三维图形上的pixel中心和纹理上的texel中心并不一至(pixe...

  • WebGL入门教程2 - GPU基本概念和工作流水线(渲染管道)

  • D3.js读取外部json数据

    D3.js是一个很好的数据可视化工具,支持从web服务读取json数据,或者从外部文件如.json, .csv文件中直接读取。由于部分服务比如flickrs上的图文数据服务需要VPN...

  • 如何使用CSS3实现一个3D商品标签

    使用3D缎带形状的标签是常见的一个设计模式,用在商品折扣、文章标题或网站推荐信息上,来突出显示重点内容,吸引用户视觉焦点。实现的方法有2种,一种是使用背...

  • SVG过滤器feColorMatrix矩阵变换效果用法详解

    在计算机图形学(数学)中,矩阵乘法可用于把空间向量进行几何变换。我们可以把颜色的值(RGBA)表示成一个四维空间向量:color = (r, g, b, a);那么就可以应用...

  • 更多...