工欲善其事必先利其器 软硬兼施解决虚拟现实困境

  • 来源:微型计算机
  • 关键字:VR,虚拟现实,厂商
  • 发布时间:2016-07-01 14:20

  VR,即虚拟现实。3D画面带来的只是视觉上的立体效果,而VR则是完全创造一个三维虚拟世界,通过视觉、听觉、触觉(也许将来还有味觉)反馈,让使用者有完全身临其境的感觉。当然,图像仍是VR最基本的一环,而输出图像的关键仍在GPU。但VR图像与传统的3D图像又有不同,如何让开发者快速上手?显然,工欲善其事必先利其器。AMD的LiquidVR,英伟达的GameWorks VR,就是针对各自GPU平台的VR开发工具,旨在帮助VR生产商和开发者在两个平台上创造出更好的VR体验—当然,也能顺便提升硬件销量。

  VR是一个诞生于上世纪8 0年代的概念,但多年来一直不温不火,毕竟那时候的电脑还不如现在的计算器运算速度快,理想和现实总是差距很大。1995年,任天堂推出了VB(Virtual Boy),是VR用于游戏领域的第一次尝试,但由于理念过于前卫、技术局限、外观丑陋等原因,成为任天堂旗下最失败的产品。直到2014年,FaceBook收购了Oculus,才算是挑起了VR领域的战火。大厂巨头们纷纷投身VR研发,谷歌携手高通注资Magic Leap,英特尔看好Glyph,三星推出了GearVR,索尼在打造Morpheus,微软收购了ODG公司的VR技术,HTC Vive也即将瓜熟蒂落。至于国内的平台厂商更如野草一样蓬勃生长。原本一直呆在实验室里的VR,终于有了能面向消费市场的终端产品。一时间,业内言必谈VR。

  这么多的厂商参与,肯定是一场混战。一个行业想要健康发展,至少在某个方面需要一套标准。眼下VR的输入端没什么标准,为了捕捉使用者的动作,厂商们各显神通。除了基于加速度和角速度传感器追踪外,还有基于磁场的位置追踪、基于眼球追踪、基于激光束扫描追踪等形式。然而,不管怎样追踪,实现V R的流程一定是:动作捕捉—三维位置计算—对应场景渲染输出画面。各种运动捕捉,只是实现了前两步,而第三步必须通过GPU运算最终成大统。如何让开发者能够快速驾驭GPU,让它高效率渲染V R图像?根本方案就是,GPU设计者应该提供一个配套的VR专用开发工具,让VR开发者能节省大量脑细胞。桌面消费市场谁能做出高性能的GPU?我们睡着了都能数出来,这个开发工具也只能靠他们了。所以AMD拿出了LiquidVR,英伟达则有Game Works VR。从字面上理解,Liquid有平滑、流畅的含义,这也是AMD对Liquid VR的期望,即所谓的3C(Comfort,Compatibilityand Compelling Content)。GameWorksVR则似乎更侧重于游戏。

  VR的开发难点

  所有的新技术,都会有一堆难点待解决。对于VR而言,如何捕捉使用者的动作和位置,这并非技术难题。难点是如何与人体动作同步生成即时运算的、符合视觉规律的画面反馈。3D电影由于每一帧都是固定的所以可以通过预先制作,普通3D游戏也只需要绘制一遍场景,但VR必须绘制两遍场景才能做出与现实世界相同的三维深度。在没有更好的办法的前提下,现在大部分VR引擎都是暴力方式直接渲染两遍,这是最简单,却也是效率最低下的方法,因为分辨率和帧率鱼和熊掌不可得兼。

  先说帧率。在2015年蒙特利尔国际游戏峰会(MIGS15)上,索尼表示,VR画面帧率达到60fps是一个最低要求,否则就无法提供流畅的VR体验。索尼建议至少必须达到90fps。PSVR在PS4的机能下达到了120fps,但实际上是通过reproject插值计算出中间帧实现的。

  再说分辨率。我们知道分辨率越高,对真实世界的还原度越大。Oculus Rift和HTC Vive的分辨率达到了2160×1200@90Hz。这种精度下,如果开启135%的超级采样抗锯齿,则颜色缓冲区每秒的数据量为2.33GB,也就是说每秒钟需要着色的像素达到2.33亿个,这还没包括后期还需要进行的光照运算、目标贴图等。

  这种浩瀚的计算量,使得渲染两遍画面的工作方法根本无法达到90fps的标准,能达到75fps已经算是拔尖了。当然,如果不计成本烧钱堆硬件,通过PC计算输出到VR头盔,也能够达到目标,但那样就完全没有意义了。消费级产品的根本宗旨应该是在不降低质量的前提下能省则省。

  V R另一个无法回避的难点就是延迟。用户的每一个动作,需要系统跟踪定位之后提交CPU处理,然后CPU传输数据给GPU绘图,最后由显示器扫描输出图像,这当中的每一个步骤都增加了延迟。假如用户转动头部,却迟迟看不到画面更新,除了糟糕的V R体验外,还会带来晕车的感觉。研究结果表明,大于40ms的延迟就会让人难以忍受,而低于20m s的延迟就不易察觉。为了改善延迟,业界通常采用预测技术,但在VR系统里,这会增加出错的概率。

  在LiquidVR和GameWorks VR里,除了给自家GPU提供专用的A PI接口及开发环境以外,对于VR的上述难题,都必须有一一对应的解决方案,才能广泛适用于开发者和VR硬件厂商。事实上我们会发现两种工具的确有很多相通之处。

  解决低绘图效率(一)

  CrossFire和SLI有两种渲染模式:分割帧渲染模式(Scissor Frame Render ing,SFR)和交替帧渲染模式(Alternate Frame Rendering,AFR)。SFR模式将每帧画面划分为上下两个部分,主显卡完成上部分画面渲染,副显卡完成下半部分的画面渲染,然后副显卡将渲染后的画面传输给主显卡,由主显卡将上下两个半边画面合成为一个完整的帧;AFR模式下,两块显卡分别负责渲染奇数帧和偶数帧画面,二者交替渲染,输出的都是完整的画面,不需要再进行画面整合。

  CrossFire和SLI通常采用AFR模式,但这并不适合于V R,因为它根本不会减少延迟。而且,如果每一帧的渲染需要通过前帧的结果进行位置变换,由于前后两帧数据被存在不同的GPU上,反而还导致延迟增加。

  换个思维,让两个GPU分别负责左右眼图像的渲染,绘图效率就能得到极大提升,AMD的Affinitymulti-GPU和英伟达的VR SLI都是这样一个原理。并且,画面中的有些内容是不需要渲染两遍的,例如阴影贴图、物理计算、游戏逻辑以及部分光反射运算等。这些内容只需要进行一次计算即可,也不会影响到VR图像效果。对此,AMD和英伟达有大致相同的方案。

  Liquid VR中,通过Affinity Multi-GPU API,应用程序可以建立一个单一的指令流,同时发送给VR系统中的任意GPU组合。该程序还能控制由哪些GPU接受API调用。在由单个GPU渲染并分配给双眼可视的场景中,应用程序只需发送一次指令,并且该指令能够被并行处理。渲染后的数据由副GPU通过PCI Express总线传输给主GPU,然后整合输出并显示。此外,AMD的GPU具有独立的DMA引擎,能够异步传输这些数据。

  通过两个GPU的分工渲染,Affinity Multi-GPU能够减少近一半的延迟,并提供双倍带宽和计算资源,同时减少C PU等待时间,提高CPU的指令吞吐量。该技术同样适用于4个或更多的GPU,进一步提升左眼帧和右眼帧的渲染效率。

  英伟达的VR SLI则是建立一个双眼可见对象的列表,合并成一组drawcall指令发送给两个GPU。至于需要进行左右眼区分的画面,开发者只需要准备分别包含了双眼视图模型的常量缓冲区,并指定几个简单参数例如常量缓冲绑定、viewports、scissors等就能完成。

  开发者有两种方法调用VR SLI,一种是Affinity Masking,另一种是GPU Broadcasting。这两种方法可以混用。VRSLI同样支持多GPU,开发者可以通过Affinity Masking将绘图工作明确分配给各个GPU。当然,还要有API通过PCI Express总线在GPU之间传输数据,整合输出图像。所以,VRSLI实际上是控制多个GPU的API,它让开发者能够自行分配各个GPU的工作量,当然也需要由程序来控制如何使用GPU。

  解决低绘图效率(二)

  在提升绘图效率方面,英伟达多走了一步。

  一般VR头盔里都会有一个透镜,主要作用是让使用者获得更大的视角和舒适的对焦。但透镜会扭曲画面,所以VR会将画面进行一个反向扭曲,用于抵消透镜产生的畸变,这样画面就正常了。所以如果拿掉透镜,就会发现VR头盔里的双视图中心像素密集,周围则因为图像压缩、扭曲而分布零散。

  不过这样又出现了新问题:理想状态下,GPU应该直接绘制这种扭曲画面。但GPU是为了渲染正常的线型投影而设计的,它不能原生地去绘制这种扭曲的非线型投影画面,那会使三角形的光栅化非常复杂。目前VR引擎的工作方法是,GPU挥洒汗水辛辛苦苦绘制出了精细的全分辨率图像,但随即就要通过后期处理、重新采样处理成扭曲的视图。这种扭曲后的图像在屏幕上只需要很少的像素也能呈现同样的效果,因此图像周边大量的像素都没有被显示,GPU的劳动成果就被浪费掉了,还拖慢了绘图速度。

  GameWorks VR提供了一个解决方案:多分辨率着色(Multi-Resolution Shading)。将整个图像分割成3×3的网格空间。在中央网格的图像保留完整的分辨率,周围网格的图像则采用类似于传统的缩放方式进行绘图。这样得到结果非常接近于理想的扭曲图像,用户的体验也不会变差,但像素数量能减少25%到50%,而着色效率则提升为原来的1.3倍到2倍。以Oculus CV1为例,其2160×1200像素的屏幕采用多分辨率着色之后,GPU的工作量能减少30%到50%。

  当然,这种技术必须有硬件支持才能实现。英伟达Maxwell架构的GPU,包括GeForce GTX 900系列和Titan X,支持多重投影架构(multi-projection architecture),可以把单个画面分割成不同形状的几个分区,GPU的绘图流水线只需运行一次就能绘制包括缩放视图在内的全部的分区,而且不会额外占用计算资源。

  而AMD没有提供类似的特性。虽说Multi-Resolution Shading现阶段没有游戏支持,但是未来对性能的改善会比较明显,相比单纯地增加GPU数量,会更有效率。

  解决高延迟(一)

  如何解决高延迟这是一个系统工程,因为实现VR的每个环节都会带来延迟,因此AMD和英伟达都提供了多种方案进行“一条龙”处理。在分述这些技术之前,我们需要先了解一下时间扭曲(Timewarp)的含义。

  时间扭曲能够根据使用者头部的运动带来的视角变化而调整图像。例如使用者的头向右转动,时间扭曲会将当前图像向左移动,以符合视觉规律。

  时间扭曲能有效降低人的延迟感。它在场同步信号发出的几毫秒之前对头部姿势进行重新采样,然后扭曲一帧已经绘制完成但还未在屏幕上显示的图像,生成一个中间帧来弥补头部运动所造成的画面延迟。时间扭曲完全依赖于GPU已绘制好的那一帧图像,因为中间帧的调整是发生在这一帧的绘制完成之后。并且“扭曲”的过程是一个额外的进程,如果此刻计算机正在运行着另一个进程的话,画面可能会更加延迟。

  异步时间扭曲

  (Asynchronous Timewarp,简称ATW)是一种生成中间帧的技术。当显示画面不能保持足够帧率的时候,AT W能产生中间帧,在 G PU渲染能力与屏幕显示需求之间寻找一个平衡,例如当显卡输出F P S低于屏幕刷新率时,AT W可以显著降低滞粘感。AT W在每一帧渲染快结束时,更新头部追踪数据并利用time warp算法反馈到图像上,而不必等到下一帧绘制完才更新。这样最多可以将延迟减少25ms。AT W作为一个固定的独立进程运行在GPU上,不管场景的绘制工作是否完成,它都会在每一个场同步信号之前完成自己的事情。

  在Liquid VR中,第一个降低延迟的方案是Latest Data Latch。传统渲染管线的一个缺点是,GPU完全被视为CPU指令“卸货”的地方,而不是对等平级的关系。当CPU向GPU推送指令,指令又暂时不能被GPU执行之前,就会增加系统资源的无谓占用并降低了CPU的并行度。这可能会带来许多毫秒甚至以秒计的延迟,对于V R来说简直是灾难。

  Latest DataLatch让GPU消耗及时的最新数据,而不是接收来自CPU的旧数据。CPU对使用者的定位数据进行持续采样,并不断将更新数据存入环形缓冲区。应用程序通过Latest Data Latch指示GPU绕过CPU直接在缓冲区读取最新的位置数据,并作为位置变换的输入进行渲染,实际上,这就是时间扭曲的另一种表现形式。

  为了配合Latest Data Latch,Liquid VR SDK还提供了名为Asynchronous shaders的新特性,字面理解就是异步着色器。传统的GPU工作方式是同步计算,不同的任务或线程间需按部就班进行处理流程,某些线程需要条件满足后才能继续进行,在条件满足之前一直处于等待状态,这就造成了GPU资源的浪费。与之相反,GPU异步计算则是将渲染与计算任务分别放入不同的队列同时执行。由于计算与渲染所用到的硬件单元并不完全重叠,所以同时执行计算与渲染任务可以最大程度利用硬件资源,从而达到提升性能的目的。这就是Asynchronous shaders的思路。

  Asynchronous shaders必须是GCN架构的GPU才能支持。GCN架构包含一个图形命令处理器,多个异步计算引擎,以及两个数据复制引擎。Asynchronous shaders可以同时调度三个工作序列:图形渲染、工作量计算和数据复制,而且这三个序列都可以达到满负荷运转。在VR系统中,GPU可以在渲染画面的同时对上一帧画面进行时间扭曲处理,可获得更高的帧率、更好的图像质量,消除图像抖动,降低了延迟。

  需要说明的是,由于Direct X11的Direct Compute接口不支持异步计算队列,计算与渲染任务被完全放在同一个队列中排队执行,大大降低了GPU的并行度,也使得AMD的硬件优势无法得以完全展现。而异步计算是DirectX 12的重要特性,也将大大提升AMD的性能优势。

  GameWorks VR方面,前面我们提到,VRSLI可以分配多个GPU的工作量,但GPU之间的数据传输以及图像整合还需要通过PCIE xpress总线来完成。这时候PCIExpress的速度已经不够用了。PCIExpress 2.0x16的带宽为8GB/s,这意味着传输一只眼睛的视图大概需要1ms。在90Hz的高帧率下,这将带来严重的延迟。

  为了降低延迟,GameWorksVR的驱动底层提供了高优先级图形处理背景(High-priority Graphics Context)的特性,能够控制GPU的调度从而在VR平台上实现ATW技术。有了这个功能,GPU在进行普通的图形背景绘制的同时,VR系统服务可以通过高优先级图形背景对图像进行扭曲,在使用者移动头部的同时迅速调整图像,避免重新绘制新的画面,并消除了延迟。

  不过,英伟达建议开发者不要试图依靠异步时间扭曲来“修复”低帧率。原因是GPU绘制图像时,必须等到当前调用的图像绘制完毕才会进行背景切换。所以,即使是一个高优先级的ATW,也有可能因为一个需要长时间执行的draw call指令而发生卡顿,继而错过场同步时间,影响到画面输出,给使用者带来糟糕的体验。

  解决高延迟(二)

  LiquidVR的Direct-to-display只面向VR硬件厂商。这是一个与Latest Data Latch步骤完全相反的特性:渲染完毕的图像绕开GPU直接进入VR头盔设备的缓存区以供显示,相当于输出。由于数据传输的时间大大缩短,这也降低了帧渲染到显示所需的时间,防止因为错过场同步信号引起画面撕裂和抖动。

  由于图像数据远大于头盔的位置数据,所以这一特性能更大程度地降低延迟。

  GameWorks VR的Directmode原理类似,同样也只面向VR硬件厂商。当初Oculus Rift DK1刚出来的时候,接入PC时画面会闪一下,那是因为PC把Oculus Rift识别成了显示器。但VR头戴设备并不完全是显示设备,把它识别为显示器是不对的。Direct mode让系统将头戴设备识别为 VR显示器而不是一个标准的桌面显示器,避免了操作系统层面的一些操作影响它,例如强行将桌面扩展到头戴设备上。这样,VR系统就能接管头戴设备的显示器,控制显示顺序或场同步,直接进行渲染输出,从而提升VR使用体验。

  写在最后

  传统PC游戏,虽然来自不同的游戏引擎,但各种引擎最终都必须通过DirectX接入Windows平台,开发者也就少了很多麻烦。但VR行业正是战国时期,Liquid VR和GameWorks VR都还无法成为一个正式的标准。总体上比较,GameWorksVR多了个很实用的Multi-Resolution Shading,但Liquid VR的Asynchronousshaders又比高优先级图形背景更先进些,因此现在很难说清楚谁更有优势。这就意味着游戏及其他内容制作商不得不同时支持两种技术以获取每种GPU架构的最佳性能,或单独针对其中一家进行优化。

  当然,作为用户,我们不需要关注钉钉子应该用榔头还是铁锤这样的问题。Liquid VR和GameWorks VR都只是实现VR的工具,工具有竞争,有进步,用户才有好的体验。

  文/张明芮 黄兵

……
关注读览天下微信, 100万篇深度好文, 等你来看……
阅读完整内容请先登录:
帐户:
密码: