900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 从华为手机实现光线追踪谈起

从华为手机实现光线追踪谈起

时间:2020-05-01 14:00:06

相关推荐

从华为手机实现光线追踪谈起

最近研究了一点光线追踪在手机上实现的知识,权当做个研究笔记,我也好多年没写图形加速技术方面的东西了,权当练手。本文得到了NVIDIA几个资深顾问的支持,在此特别感谢:

光追使者的莅临

如果说游戏是硬件发展的重要动力,那么更逼真的游戏画面则是大多数玩家喜闻乐见的游戏加分项,同时也是电子游戏的最大魅力所在,而游戏画面直接关联的 GPU 依然保持着高速发展,也印证了人们对画面逼真感有着极高的期盼。11 月 20 日,在软件绿色联盟开发者大会上,华为 EMUI 和网易宣布在游戏《遇见逆水寒》上实现了光线追踪渲染,现场公布了一些视频和若干张幻灯片,以目前掌握的消息来看,这是迄今首个实时光线追踪的手机游戏实现。

我们都知道,光线追踪已经有 40 年以上历史的图形渲染技术,并非新的概念。相对于传统的光栅渲染技术来说,它可以实现更逼真的光影效果,但是由于硬件性能因素,在很长一段时间里,我们都只能在影视等非实时应用上才能看到该技术的采用,台式机也是去年才在游戏中出现,当时我还写过一篇 NVIDIA 图灵架构的介绍短文。

相对于台式机来说,手机有极为严苛的耗电约束,在这样的条件下,引入光线追踪,可以带来怎样的体验以及如何实现都是非常有意思的话题,我收集了一些目前华为方面提供的资料,结合一些业界的信息,撸了这篇文章,希望可以给大家一些参考。

光线追踪这个名字源自英文 Ray Tracing,在图形渲染中,它是用来确定不同元素可见性的渲染方法,实现原理非常简单,以至于网络上出现了很多个可以把全部代码放进着色器的光线追踪代码版本。

我们这里也简单介绍一下它的实现流程。

光线追踪的最基础版本被称作 Ray Casting,它原理是从观察者(或者说摄像机)发出一条光线或者更准确地说是虚拟射线(被称作主射线),打到屏幕上的某个点,然后射线穿过这个点抵达到渲染场景内,当场景中有三角形挡住其去路的时候,需要根据三角形被赋予的表面属性,做出反射、折射、吸收等计算。

而光线追踪在 Ray Casting 的基础上还要在反射、折射的情况下做进一步的衍生射线计算,直到衍生射线抵达吸收表面或者场景的极深处。

光线追踪的最大计算复杂度就是因为有场景中可能有大量的衍生射线需要进行这样重复的操作,带来了庞大的三角形随机存取和求交计算,使其性能需求远高于光栅渲染。

当然,这只是光线追踪的一种实现方式,也就是从观察者发出射线,被称作逆向光线追踪,还有从场景中的光源发射线(正向光线追踪)以及比较特别的从场景对象发射线的方式(点云渲染可以采用这样的方式)。

相较之下,目前大多数游戏采用光栅渲染是先用被称作光栅器的单元计算出三角形投射在屏幕空间上的投影,查出有哪些像素需要渲染,然后 GPU 的像素渲染流水线同时对这些像素进行渲染计算。

由于同一时间里只跑一个三角形,所以内存里只需要放一个三角形的数据就行了,减少了内存传输。

问题是现实世界中,物体表面的光影其实是受到很多其他对象的反射等光学现象影响的,单独计算一个三角形的话,会造成渲染效果存在瑕疵,然后为了追求更逼真的效果,光栅渲染需要使用非常复杂的算法和大量的中间渲染对象来模拟高级效果,这就涉及到算法的复杂性和内存管理问题,增加了渲染器的编写和维护难度。

光线追踪渲染计算简单,但是需要大量重复计算,而光栅渲染则是一个萝卜一个坑,不同效果需要不同的算法来实现,其中涉及的瑕疵可能需要额外的步骤来隐藏或者消除。当然,两者是可以共存的,PC 上的光线追踪游戏其实都是两种渲染技术混合实现的,相辅相成。

如何实时光线追踪?

前面提到,光线追踪最消耗资源的部分就是求交运算,也就是找出场景中有哪些三角形会和射线相交。

因为在没有任何优化措施的情况下,这个过程就好像是从几百万到上千万个拼图碎片里找出合适的碎片,是完全的随机性搜索。

主射线搜索一遍,然后随后的 n 条衍生射线也需要搜索 n 遍,一个像素一条主射线的话,一个全高清的画面光是主射线就有两百万条,场景越复杂,衍生射线的数量以及需要求交的三角形次数量也会急剧增加。

实时渲染的实时在不同的应用下定义会有点不一样,对于工作站应用来说,能达到每秒 10 帧就是不错的交互体验。

但是对于游戏来说,人们能接受的渲染速度一般都在每秒 30 帧以上,这意味着每帧画面的平均渲染时间得控制在 33 毫秒以内,目前光线追踪作为一种画面效果添加剂,自然也不能超过这个标准。

要将光线追踪应用到游戏中,首先要解决的就是减少无效求交次数。最有效地办法就是将场景中的模型按照一定的规则进行“分仓”处理,这时候涉及的主要是数据结构,例如 KD 树、包围盒。

以目前的研究资料和实践来看多层包围盒(BVH)被认为是最适合实时光线追踪应用的,它的原理并不复杂,就是把场景中的物体逐次分离。例如场景里有一栋楼房,然后里面有不同的单元、单元里有客厅、客房、卫生间等,它们按照大小放在一个套一个的包围盒数据结构体中,直到最小的渲染图元:三角形。

目前的光线追踪硬件加速也是围绕 BVH 来进行的,例如 ImgTec的 PowerVR 6XT GR6500、NVIDIA 的 GeFroce RTX 20 系列等,都是以各自的实现方式把 BVH 求交硬件电路做进去,可以预期的是,未来的硬件光线追踪实现也会是类似的方式。

如果是软件方式的话,其实很早之前就有人尝试透过着色器来跑简单的光线追踪效果,现在台式机方面,NVIDIA 就开放了 GeForce GTX 1000 系列的光线追踪执行,目的主要是为了尽快推动光线追踪软件的开发。

华为手机实现的实时光线追踪效果?

网易在现场公布了一段《遇见逆水寒》的视频,其中包含了开关实时光线追踪的对比:

网易在演示的时候主要介绍了两种实时光线追踪特效的应用,即软阴影、磨砂镜面反射,视频都有两个片段展示,然后还有一段是两者集合一起的全场景应用。

软阴影:

磨砂玻璃镜面反射:

结合一起应用:

从效果来看,实时光线追踪在这里实现的效果的确会带来比较明显的差别。根据网易的幻灯片,在实现同样的反射效果时,实时光线追踪的耗电和性能表现都要比光栅化更出色:

在这个场景中,只有一面镜子的时候,光线追踪和光栅渲染时的每一帧耗电分别是 15.84 毫安和 19.04 毫安,但是当场景中有多个镜面的时候,光线追踪和光栅渲染时的每一帧耗电分别是 19.7 毫安 和 63.43 毫安。场景特效应用的位置越多,光线追踪的优势就越明显。

所以,从网易公开的视频来看,在《遇见逆水寒》中,实时光线追踪的确带来了可见的画面优势以及节电效果。

关于华为实时光线追踪实现方式的猜想

相对于台式机游戏来说,上面的场景并不复杂甚至可以说有点简陋,但是要知道,这是在手机上实现的,使用的处理器是麒麟 990,其中的 GPU 模块是 660MHz 的 ARM Mali-G76 MP16。

Mali-G76 MP16 具有 16 个内核,每个内核里有三个 Execution Engine(简称 EE),每个 EE 有 8 个 FP32 执行单元(见参考 1),因此 600MHz 的 Mali-G76 MP16 的 FP32 性能大约是 460.8 GFLOPS(这里假设每个 FP32 执行单元可以每个周期跑完一条 FMA FP32 指令),这个性能水平相当于台式机 Radeon RX 5700 XT 的 5% 不到。

那么,网易图形小组是如何在麒麟 990 上实现光线追踪的呢?

如果我们把目光倒回 14 年前,也就是 年,NVIDIA 或者说英伟达公司当年发布了一款 GPU:GeForce GTX 7800,随之推出了一个技术演示程序——Luna。

根据 NVIDIA 同年在 SIGGRAPH 大会上发表的技术幻灯片“GPU Programming Exposed: The Naked Truth Behind NVIDIA's Demos”介绍,这个技术演示程序就应用了光线追踪技术来计算其中巨型眼球的折射效果。

翻查资料,我们可以得知 GeForce GTX 7800 的单精度性能号称是 165GFLOPS,只有 Mali-G76 MP16 的三分之一(如果 Mali-G76 的 FP32 单元只能一个周期跑一个 FMUL 或者一个 FADD 的话,那么 GTX 7800 的单精度性能就是 Mali-G76 MP16 的一点五分之一)。

所以,我们认为网易的实现方式很可能并不复杂:直接使用 GPU 通用计算单元跑光线追踪,也就是所谓软件方式,不涉及类似 NVIDIA GeForce RTX 那样的光线追踪内核(硬件 BVH 加速)设计。

不管怎样,这次《遇见逆水寒》的技术发布,说明了在现有的高端手机上,已经可以实现初步的实时光线追踪处理,随着技术的进步,硬件 BVH 加速很可能会在今后的新处理器中集成,届时我们一定会看到效果更强大的光线追踪特效。

一项新技术的引入往往会伴随着大量的未知挑战,网易和华为的联合对于光线追踪的采用无疑是大有裨益,前者强在游戏开发,后者强在软硬件结合,随着这样的强强联手日益增多,光线追踪的普及也将日渐临近。

参考资料

1、Mali-G76 微架构细节参考:

Arm Mali-G76 GPU deep dive

2、光线追踪原理示意插图:

/wiki/Ray_tracing_(graphics)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。