听说华为手机能玩光线追踪游戏,动作比NVIDIA还快?
原创
黄烨锋
电子工程专辑
前天
去年年底的
软件
绿色联盟开发者大会上,
华为
EMUI
和网易宣布在游戏《遇见逆水寒》中实现光线追踪渲染,也就是在手机游戏上做到实时光线追踪(ray tracing)运算。这听起来是件大事,虽然光线追踪的硬件实现早在上世纪90年代就有了,而且在如今的3D动画作品与游戏CG中也常见,但实时(real time)的光线追踪在桌面PC平台尚且刚刚开始,手机现在竟然也有了?
游戏《遇见逆水寒》光线追踪开启前后的对比
我们在去年的Imagination新品发布会报道中曾经提过[1],Imagination预计将会在2020年的B-Series
GPU
中加入光线追踪架构。至少就商业应用来看,GPU的实时光线追踪在移动平台的应用还并不能算是眼下的事情。比较有趣的是,2020年伊始,Imagination宣布
苹果
再度与其签署多年的授权协议,虽然具体获取的是哪方面的IP我们并不清楚。国外有分析师认为,苹果可能是对Imagination的
光线追踪技术
感兴趣。
苹果
A系列芯片的
GPU
是个黑匣子,我们也无从探究其GPU从硬件层面对光线追踪支持做到何种程度。在去年的WWDC 2019开发者大会上,
苹果
曾经做过一个名为Metal for Accelerating Ray Tracing的主题演讲[2],表明在
软件
层面,苹果已经在做针对光线追踪的筹备。这个演讲的简介提到,“Metal Performance Shaders利用GPU的大规模并行能力,为当代光线追踪与光线投射(ray casting)技术计算做加速。”从这样的描述合理猜测,苹果的GPU尚未在硬件层面针对光线追踪做出特别的支持。
那么《遇见逆水寒》这款游戏的光线追踪又是怎么做到的?是否海思Kirin
SoC
已经从硬件层面实现了光线追踪?这是我们期望去理解的问题。由于文章篇幅比较长,非技术爱好者可略过本文的第二、三部分,而仅阅读第一与第四部分。
光线追踪有什么用?
消费电子市场上,推实时
光线追踪技术
比较积极的无非就是
英伟达
(
Nvidia
)和Imagination两家公司,分别对应PC端与移动端。这也就成为我们能够更清晰地理解当代
光线追踪技术
发展到何种程度,及其趋势的窗口。不过在此之前,还是花点笔墨回顾一下,究竟什么是光线追踪。
从这种技术能做什么的角度来说,有了光线追踪,相对狭义的讲,在游戏或图形计算相关的动画中,我们就能看到各种更真实的光线反射、折射、阴影等光影关系。这些反射、折射、阴影需要的因素很多,比如图形对象的材质,不同材质对光的吸收、反射都是不一样的,镜子能够反射出实物,而大理石地面虽然也有光线反射,但程度与方式有异。另外,光线从光源发出被反射后碰到新的对象还会再次反射或折射、吸收,其复杂程度可见一斑。
就现实生活来看,这似乎是理所应当的。但在过往的3D图形世界里,它在外显方面就只是一种模拟现实世界的特效。而要实现这些效果,是从硬件到
软件
中间层,及开发共同努力才可达成的。举两个简单的例子:
来源:
Nvidia
,游戏《古墓丽影:暗影(Shadow of the Tomb Raider)》截图
在上面这个来自
英伟达
的例子中,光线追踪(英伟达将自家的
光线追踪技术
称为RTX)关闭与开启后的区别,这两张图的主要差异在阴影的呈现上。在人物脚下,及身体各部位考虑光影关系时,这个场景才显得自然;如果阴影计算不完整,则人物就像漂浮在画面中一样。
来源:
Nvidia
,游戏《战地5(BattleField V)》截图
如上图这样的反射,区别相当显著,也就不需要多谈了。不过实际上,传统的rasterization(
光栅
化)方案仍然可以做出反射效果,只是其开发复杂度会明显更高,且经常会出现缺失,包括处在画面外的反射并不会加入进来。上面这个场景中,一旦火焰处在屏幕显示以外的区域,rasterization通常都不会再将其显现在汽车外面的反射效果中。
在这个问题上比较有趣的一个设想是,玩如主视角射击竞技游戏时,借由光线追踪,如果有敌方在窗户下方潜行,玩家躲藏在角落位置,从某些视角依然能够从窗户玻璃中看到潜行的敌人——这也算是游戏的技术外挂吧。
来源:Imagination
而在上图的Imagination示例中,左边通过常规rasterization方式计算得到的阴影似乎已经算是比较到位了——实际由于rasterization方案流程问题,造就的阴影经常出现各种
失真
(比如锯齿)。再加上计算阴影边缘模糊的效果——这种所谓的半影(penumbra)效果对rasterization来讲已经很难。而像右图这样阴影的半透明化对rasterization而言又是个难点,但对光线追踪来说就简单很多。
用比较简单的话来说,光线追踪就是在生成某个3D场景时在某个阶段所采用的一种技术,这种技术能够模拟现实世界中光的行为。而利用光线追踪,就需要为开发者提供开发工具,并且生产更具真实感的视觉效果。
光线追踪在电影行业的应用已经非常广泛了,而电影所需的光线追踪会用上专业图形计算工作站,可能花几个月时间把最终画面给渲染出来。这对于实时的电子游戏来说是不现实的,一方面是因为游戏需要实时地生成每秒至少30帧画面;另一方面光线追踪对于图形计算性能要求也是疯狂的,过去是不可能用一块显卡就搞定3D游戏实时光线追踪的。
如果我们仅从“光线追踪”字面理解,处理器需要追踪所有光源发射的光线,并且场景中不同对象表面还会对光源的光进行反射、吸收、折射,而且不同
材料
表面实现这些效果的特性还不同,成千上万的光线需要计算。一个ray tracer性能度量因此就要达到每秒数百万、千万光线的计算能力,相当于
GPU
像素填充率的GPixels/sec级别,以及算力的GFLOPs级别[3]。
这个量级是Imagination在自家有关光线追踪的白皮书中提到的,它或许还不够具体。几年前
三星
尖端技术研究院(SAMSUNG Advanced Institute of Technology)和几所韩国、美国的高校曾联合发表过一篇题为《SGRT: A Mobile
GPU
Architecture for Real-Time Ray Tracing(为实时光线追踪
设计
的一种移动GPU架构)》的paper[4],其中提到“在720p分辨率下,实时光线追踪(30fps)的实际应用,要求的性能至少是300Mrays/s(单精度要求大约1-2TFLOPs)。”现在的手机GPU即便全速跑,与此都还有比较大的差距。
这个数据当然可能并不绝对,而且并没有标明更具体的计算环境和要达成的目标。但似乎要让现在的手机
GPU
硬跑光线追踪,难度还实在是颇大的。
来源:Imagination
如果我们抛开光线追踪对算力的贪婪需求不谈,光线追踪能够实现的特性并不仅限于游戏,更高阶的应用是
AR
(现实增强)。比如像上面这张图片,原场景是用摄像头实拍的,AR则在场景中加入了一辆汽车。要让这辆汽车更真实,就必须让汽车在光影方面融入到场景中去。当然这种应用的要求就比较高级了,因为相机需要分析场景的光分布,考量各种光线因素后加入到虚拟汽车的渲染中去。
除此之外,可畅想有关光线追踪的应用也与
汽车电子
相关——环视摄像头收集数据所呈现的画面,将光影也考虑进去,那么中控板显示的画面不仅更真实,而且也易于进行障碍物距离的估计和判断。
主流的光线追踪实现
相对硬核的3A大作玩家应该很清楚,前文提到的这些反光、阴影、折射等效果,并不是光线追踪特有的。前面提到的rasterization(
光栅
化)有时也能达到这样的效果。那么我们就不妨简单地谈一谈,什么是rasterization,以及光线追踪又是怎么回事。
Rasterization
光栅
渲染的过程,本质上也是一种将3D对象在2D屏幕上显示出来的技术。3D对象就是一堆三角形或多边形,构建起的不同形状、大小。三角形的角或者顶点,包含了很多信息,包括它在空间中的位置、色彩、贴图、法线等。而3D模型的这些三角形,要显示到屏幕上,则最终都需要将其转化为像素。这就是rasterization的过程。每个像素都会分配一个初始色彩值——这个值来自于三角形顶点中存储的数据。像素随后还会得到进一步的处理或者shading(着色),比如说基于场景中的光源来改变其色彩,并且应用一个或更多贴图,最终生成像素色彩。[5]
GPU
渲染流水线
这是比较简单的一个形容方式。Rasterization如果只从
GPU
渲染所处的阶段来看,它位于比较靠后的位置。而这个大步骤还可以分成很多细致的处理阶段,包括三角形设定、三角形遍历,以及像素着色、输出合并。
实现最后一步输出合并(Output Merging)的功能单元叫ROP(Raster Operation Units,
光栅
化处理单元)。这一阶段根据z-buffer(深度buffer,z坐标的深度值)存放的深度信息,判断是否需要更新色彩buffer中的色彩值——说白了就是判断场景中对象的可视性(visibility),比如某个对象是否被另一个对象遮挡(在像素级别),以此判断是否需要更新当前像素的buffer,以及再去计算相应图元(primitive)的色彩,并更新buffer作像素着色。[6][7]
为达成更加逼真的效果,对像素进行着色是需要考虑其“上下文”或者说所处的具体环境的。比如说光来自哪里,光是否被其他表面遮挡或反射等等。Rasterization方案的问题在于,它并不擅长去做这种上下文考量,而是孤立地去计算每个三角形,于是很难达成错综复杂的光影效果。所以rasterization本身还需要搭配更多复杂的方案来实现模拟现实世界的高级效果。
来源:
Nvidia
,左上图是rasterization应用传统阴影贴图后的效果,看起来似乎还不错,但它对阴影边缘的模糊处理过于一致,其contact hardening实际上是有问题的;而后面几张光线追踪达成的阴影不需要应用阴影贴图,可模拟更自然的阴影contact hardening,这几张应用了不同的锥角
比如对阴影的处理,就rasterization来看,需要从每个光源的视角作渲染,再存储到纹理(texture)中,然后在lighting阶段(应该是几何处理的顶点着色阶段)将其再投射到场景自身。绝大部分
光栅
化过程还需要支持某些特定的阴影贴图类型,比如说针对全向光的立方体贴图阴影(cubemapped shadows),针对大型户外场景的层叠阴影(cascaded shadows)[8]。为消除阴影的接触硬化(contact hardening)问题,raterization还需要应用PCSS(Percentage Closer Soft Shadows)和Distance Field Shadows这样的技术,但这些技术同样存在应用场景的局限性,如PCSS不仅算力需求很大,而且无法针对任意区域光生成完全正确的阴影。
这些附加的方案不仅对算力、
带宽
、功耗都提出了更高的要求,而且增加延迟。更重要的是,它们极大增加了复杂性,效果还并不见得很理想。这其实是在光线追踪同样对算力要求很高的情况下,让rasterization越来越失去吸引力的一些原因。光线追踪对开发者而言也会明显更友好和简单。
那么光线追踪又是怎么一回事呢?笼统地说,就是以遵循自然规则的方式,模拟场景及对象光照,正确渲染反射、折射、阴影及间接光照等。不过现在比较主流的光线追踪
算法
并不是从光源的视角出发,去“追踪”每一缕光线的,而是完全逆向的,从我们的观察视角出发。
假想有一台摄像机在对着3D场景拍摄,发射出一条ray(线),这条ray首先从这台摄像机出发,通过2D视觉平面(也就是屏幕对应的像素平面 ),进入到3D场景中,这条ray会打到场景中的对象表面,最终能够追溯光源。
在这个过程里,ray可能从一个对象反射到另一个对象,则形成反射;或者被某个对象阻挡,则形成阴影;也可能穿过透明或半透明对象,就形成折射。对象表面与ray相交的点就有了相应的色彩、照明信息,这样一来ray穿过的像素也就有了色彩和亮度等级信息。
这种“逆向追踪”的方案要比从光源多角度正向追踪高效很多。即便如此,它对算力的需求也是非常贪婪的,这与进入场景中的ray数量有很大的关系,而且还要考虑反射、折射生成更多的ray(所谓的衍生ray)。至于要向场景中“发射”多少ray,则需要考量光线追踪对象的类型数量、
GPU
的处理能力、屏幕分辨率,以及发射通过每个像素的ray有多少个。
在具体实现上当然还有不同的技术和优化方案,用于加速ray与图元相交的检测,以及尽可能减少ray的数量。因为如果真的考察场景中每个ray与每个图元的相交,现有技术的硬件资源还是不允许的。所以就诞生了像是Bounding Volume Hierarchy(BVH,包围盒层次)这样的加速结构。
这里简单地谈一谈这种BVH技术。BVH是一种树形结构,包括了很多层级结构的包围盒子。这些盒子自身包围、或者环绕着不同量的场景几何体。越往外部的包围盒,也就包含更多的图元;更小的包围盒则包含更少量的几何体。上面这张图展示的就是BVH结构,更大的包围盒在树形结构中就是更高层级的节点,再向下遍历更小的盒子。每个节点都被一个包围盒包围,它们自身又包围很多子节点及其包围盒。
每个ray都应用BVH结构——整个流程首先是针对这条ray,检测根节点包围盒(root node bounding box),从上图来看就是兔子头,用一个比较大的包围盒根节点套住的;随后按照树形结构检测子节点,也就是后续哪些包围盒与受测的ray存在相交关系。
采用这种方案进行ray与图元相交检测,能够极大减少工作量。不需要检测ray与场景中每个图元的相交,而仅需检测明显更少量的、树形结构中每个层级的包围盒,直到相应的ray最终抵达末端节点(包含三角形图元)。
另外在首次渲染场景之前,就需要构建BVH结构(BVH building)。很多情况下,画面这一帧与下一帧的变化并不会特别大,那么基于这些变化修改现有BVH结构(BVH refitting),也不需要构建全新的BVH结构——就能节约计算资源。[9]
鉴于篇幅的关系,这里不再介绍有关光线追踪的更多技术。实际上,从
英伟达
和Imagination介绍光线追踪的白皮书来看,仍有另外一些比较重要的配套技术也在光线追踪的实现中起到重要作用,例如Denoising Filtering(去噪过滤)——大幅提升
噪声
比较重的画面的画质,尤其着眼于减少光线追踪影像渲染的时间。
那么
GPU
是怎么做的?
英伟达
是在2018年3月宣布推出自家的RTX实时
光线追踪技术
的[10]:除了为Volta及后续
GPU
提供光线追踪加速,还有针对开发者的光线追踪加速工具,尤其是配合微软的DXR(
DirectX
Raytracing)API支持(后续也有了Vulkan支持)。实际在更早的时间
英伟达
就有类似Iray插件、OptiX光线追踪引擎之类的工具提供光线加速渲染——不过那是非实时的。
去年3月,
英伟达
又宣布通过驱动升级,已经在市场上销售的部分GTX系列显卡(Pascal架构)也能获得实时
光线追踪技术
支持[11]。这至少表明,即便没有Volta架构的张量核心,以及如今专为RTX技术及显卡打造的RT光线追踪核心,实时光线追踪效果依然可以在过去的老显卡中得到实现,只要
GPU
的通用计算单元够强。
只不过实时光线追踪怎么说都还是对算力要求十分饥渴的技术,所以这种“
软件
”实现方案会受到诸多限制,比如针对支持光线追踪的游戏,更早的GTX显卡能够以比较低配的方式支持《战地5》的反射效果,但无法支持《Metro Exodus》游戏中更复杂的全局照明(global illumination)。所以更复杂的光线追踪特效,仍然是需要最新的Turing架构(RTX系列显卡)才行的。
那么像Turing这种特别针对
光线追踪技术
做加持的架构,在硬件层面有什么特别呢?实际从
英伟达
和Imagination两家的实施方案来看,目前已有实时光线追踪的硬件实现还是比较相似的。
当某种技术实现起来,对计算、存取要求很高,而且对这种技术的使用很频繁时,通常就应该考虑专有加速硬件或单元,以实现算力与效率的双重快速提升。
英伟达
针对Turing的光线追踪加速,引入了一种名为RT核心的专用硬件单元,每个SM(Streaming Multiprocessor)都包含有RT核心。它的作用就是加速前文提到的BVH遍历,ray和三角形的相交检测运算,以及去噪过滤等。
RT核心会自动去遍历BVH盒子;包括BVH building, refitting一类函数都由驱动去处理;ray的生成和着色(shading)工作则通过shader单元来完成。
Nvidia
更早的Pacal(左)与Turing(右)架构实现光线追踪的差异
在没有专用加速硬件的情况下(比如GTX显卡),BVH遍历的过程主要就是shader操作执行的,针对每个ray都要承载上千个指令slot,对包围盒相交做检测直到最终获得像素色彩值。所以如果是一个完整的场景的话,仅是这样的光线追踪工作,就已经让一般的
GPU
算力资源无力招架了。
Turing架构的RT核心则是专门干这活儿的,这种专用核心包含了2个单元,其中一个进行包围盒检测,另一个则执行ray与三角形相交检测,那么SM的其他硬件就能用于其他图形计算任务了。
英伟达
自己对比两种方案的算力时提及,较老的Pascal“
软件
模拟”方案达到的性能水平是大约1.1 Giga Rays/Sec(每秒十亿ray)或者10 TFLOPs/Giga Ray(每十亿个ray的
每秒浮点运算次数
);而Turing有了RT核心,则能够达到10+ Giga Rays/Sec,在光线追踪方面快10倍。这两个值具体对比的是GTX 1080Ti和RTX 2080Ti显卡。
Imagination光线追踪专用的
RTU
单元
Imagination的光线追踪专用硬件实现似乎还要早,可以追溯到
PowerVR
Series6时代,那会儿的
GPU
架构名为Wizard。Imagination好像在2014年或者更早就开始着眼光线追踪了[12]。当时的PowerVR GPU就已经包含了一个专门用于光线加速追踪的
RTU
单元(Ray Tracing Unit)。而且当时Imagination也针对游戏开发者,着眼在了OpenGL ES扩展;不过似乎在那个时候,实时光线追踪还太过超前,尤其对于移动平台而言。
RTU
内部包含一个SHG(Scene Hierarchy Generator),用于生成BVH数据结构。这个硬件单元似乎是Imagination独有的,
英伟达
则并未在Turing的白皮书中提及BVH数据结构生成由谁完成。按照Imagination的说法,SHG也因此对于动态几何体的光线追踪,有了更为高效的支持——结合前文对于BVH结构构建的内容,似乎的确如此。另外,我们猜测这也可能与
PowerVR
着力于移动
低功耗
市场有很大关系。
此外,从上面的图中还能看到一个可选的“Ray Coherency Engine”引擎。一般ray在打到3D场景中的绝大部分类型材质上时,就会随机散射开。它们分散前往不同的方向,与不同的三角形相交。Imagination认为,这对于存储访问的效率不利,所以Coherency Engine是要发现ray之间的共性,并将其分组,以提升效率。这可能也是在移动平台降
低功耗
的一种方式。
Imagination在宣传资料中说,早年的Wizard
SoC
运行功耗仅2W,而当时的demo板也就10W,频率为600MHz,峰值算力为300MRays/Sec。看起来在算力上与
英伟达
的桌面
GPU
仍然是有量级差距的,不过Imagination在效率上还是有优势,毕竟两者的定位是不同的。
这部分的最后值得一提的是,就目前的算力水平来看,rasterization与光线追踪还不是相互替代的关系。至少
英伟达
与Imagination的策略都是让这两者在
GPU
计算中并存,名为“混合渲染管线”,毕竟光线追踪的算力要求还是太高了。Rasterization在判断对象可视性方面,利用z-buffer仍然很快,另外还能承担光线追踪流程中的一些工作阶段(primary ray casting stage);而光线追踪则用于发射secondary ray,用于实现正确的反射、折射和阴影。
似乎rasterization仍然是构成场景的主要组成部分,所以并不能说
光栅
渲染已经要淘汰。
所以《遇见逆水寒》的光线追踪是?
就我们查阅的资料来看,除了
英伟达
和Imagination之外,其他主要的市场参与者还没有或者说尚未完全在硬件层面对实时光线追踪做专门的支持,包括
AMD
、
Arm
等,
高通
的
Adreno
在PBR支持上似有在最新的产品中初露端倪。这可能与不同
GPU
厂商的发展策略,及其GPU渲染架构本身的特性也有关。
至少在海思Kirin
SoC
的Mali
GPU
,以及近代
Arm
的Bifrost架构中,并没有看到特别针对光线追踪的专用硬件加速单元出现。就
英伟达
与Imagination指出“
软件
模拟”的光线追踪方案,利用shader进行计算,猜测就是
华为
在《遇见逆水寒》中实现光线追踪特效的方案。它能够部分应用光线追踪来模拟阴影、反射、折射等特效,但考虑到移动平台的功耗与算力限制,加上又是
GPU
的通用计算单元执行的,效果应该会相对简单。
所以实际的联合发布方是
华为
EMUI
,与海思和Kirin芯片、Mali
GPU
大概是没有什么关系的。不过即便是
软件
层面,即具体应用的推进,对于
光线追踪技术
的发展也有相当大的作用。
Imagination已经在对外提供光线追踪相关的IP授权;去年的GTC China大会上,
黄仁勋
还演示了光线追踪版的《我的世界》,相比原版的确提供了更加美轮美奂的游戏画面[13]。大概实时光线追踪在民用图形计算世界的普及也只是时间问题了。
参考来源:
(本文参考来源,请点击阅读原文查看)
作者:
黄烨锋
本文为EET
电子工程专辑
原创文章,如需转载,请留言
↓↓ 扫描二维码 免费订阅杂志 ↓↓
阅读原文
阅读
在看
已同步到看一看
写下你的想法
前往“发现”-“看一看”浏览“朋友在看”
前往看一看
看一看入口已关闭
在“设置”-“通用”-“发现页管理”打开“看一看”入口
我知道了
已发送
取消
发送到看一看
发送
听说华为手机能玩光线追踪游戏,动作比NVIDIA还快?
最多200字,当前共
字
发送中