“现实是,当你不再相信它时,它不会消失。” -菲利普·K·迪克
虚拟现实(VR)和增强现实(AR)是试图以与现实世界相同的方式刺激感官的技术。在计算机图形学领域,增强现实将合成物体与我们周围的世界相结合;虚拟现实完全取代了世界。见图21.1。本章重点介绍这两种技术特有的渲染技术,这两种技术有时使用总括术语“XR”组合在一起,其中X可以代表任何字母。这里的大部分重点将放在虚拟现实技术上,因为在撰写本文时,这种技术更为广泛。
渲染只是这些领域的一小部分。从硬件的角度来看,使用了某种类型的GPU,这是系统中很好理解的一部分。创建准确舒适的头部跟踪传感器[994995],有效的输入设备(可能带有触觉反馈或眼睛跟踪控制),舒适的头盔和光学系统,以及真实的声音,都是系统创建者面临的挑战。平衡性能、舒适性、移动自由度、价格和其他因素,使其成为一个要求苛刻的设计空间。
图21.1:。前三位作者使用各种VR系统。使用HTC Vive的Tomas;Eric在Birdly fly-like-a-bird模拟器中;Naty使用Oculus裂谷。
我们主要关注交互式渲染以及这些技术对图像生成方式的影响,首先简要介绍了当前可用的各种虚拟和增强现实系统。然后讨论了一些系统的SDK和API的功能和目标。我们以应避免或修改的特定计算机图形技术,以提供最佳的用户体验。
除了CPU和GPU之外,用于图形的虚拟和增强现实设备可以分为传感器或显示器。传感器包括检测用户旋转和位置的跟踪器,以及各种输入方法和设备。对于显示,一些系统依赖于使用手机屏幕,该屏幕在逻辑上分为两半。专用系统通常有两个单独的显示器。显示是用户在虚拟现实系统中看到的所有内容。对于增强现实,通过使用专门设计的光学元件将虚拟世界与真实世界的视图相结合。
虚拟现实和增强现实是一些古老的领域,由于各种移动和控制台技术的可用性,这些领域最近在新的、成本较低的系统中经历了爆炸式的发展[995]。手机可以用于沉浸式体验,有时效果出奇地好。手机可以放在头戴式显示器(HMD)内,从简单的查看器(如谷歌硬纸板)到免提并提供额外输入设备(如GearVR)的查看器。手机的重力、磁北和其他机制方向传感器可以确定显示器的方向。如第4.2.1.1节所述,方向(也称为姿态)有三个自由度,例如偏航、俯仰和滚转。API可以将方向作为一组欧拉角、旋转矩阵或四元数返回。真实世界的内容(如固定视图全景图和视频)可以很好地与这些设备配合使用,因为为用户方向呈现正确的二维视图的成本相当低。
移动设备相对适中的计算能力,以及GPU和CPU硬件的扩展使用对电源的要求,限制了它们的可用性。用户的耳机通过一组电线连接到固定的计算机上的栓系虚拟现实设备限制了移动性,但允许使用更强大的处理器。
我们将简要介绍两个系统的传感器,Oculus Rift和HTC Vive。两者都提供六自由度(6-DOF)跟踪:方向和位置。Oculus通过多达三个独立的红外摄像头跟踪HMD和控制器的位置。当耳机的位置由固定的外部传感器确定时,这称为外入跟踪。耳机外部的红外LED阵列允许对其进行跟踪。Vive使用一对“灯塔”,以快速的间隔将不可见光照射到房间中,耳机和控制器中的传感器会检测到这些灯塔,以便对它们的位置进行三角定位。这是一种由内而外跟踪的形式,其中传感器是HMD的一部分。
手动控制器是一种标准的设备,与鼠标和键盘不同,它可以跟踪并能够随用户移动。基于广泛的技术,已经为VR开发了许多其他类型的输入设备。这些设备包括手套或其他肢体或身体跟踪设备、眼球跟踪以及模拟原地运动的设备,如压力垫、单方向或全方向跑步机、固定自行车和人体大小的仓鼠球等等。除了光学系统外,还探索了基于磁、惯性、机械、深度检测和声学现象的跟踪方法。
增强现实是指计算机生成的内容与用户的真实世界视图相结合。任何提供平视显示器(HUD)并将文本数据覆盖在图像上的应用程序都是增强现实的基本形式。Yelp Monocole于2009年推出,将商业用户评级和距离覆盖在相机视图上。Google Translate的移动版可以用翻译后的等效符号代替符号。像《口袋妖怪》这样的游戏覆盖了真实环境中的假想生物。Snapchat可以检测面部特征并添加服装元素或动画。
对于合成渲染更感兴趣的是,混合现实(MR)是增强现实的一个子集,其中真实世界和三维虚拟内容实时混合和交互【1570】。混合现实的一个经典用例是在外科手术中,患者器官的扫描数据与外部身体的相机视图合并。该场景假设栓系系统具有相当大的计算能力和精度。另一个例子是与一只虚拟袋鼠玩“标签”,在那里,房子的真实墙壁可以隐藏你的对手。在这种情况下,移动性更为重要,注册或其他影响质量的因素则不那么重要。
该领域使用的一种技术是将摄像机安装在HMD的前面。例如,每个HTC Vive都有一个前置摄像头,开发人员可以访问。这种世界观被传送到眼睛,合成图像可以与之合成。这有时被称为通过AR或VR,或中介现实[489],其中用户不直接查看环境。使用这种视频流的一个优点是,它允许更多地控制虚拟对象与真实对象的合并。缺点是,人们对现实世界的感知有些滞后。Vrvana的《图腾》和《枕骨桥》就是AR系统的例子,使用这种类型的头戴式显示器。
微软的HoloLens是本书撰写时最著名的混合现实系统。这是一个不受约束的系统,CPU、GPU以及微软称之为HPU(全息处理单元)的东西都内置在耳机中。HPU是一种定制芯片,由24个数字信号处理核心组成,功耗小于10瓦。这些核心用于处理来自类似Kinect的摄像头(用于查看环境)的世界数据。该视图与其他传感器(如加速计)一起形成由内而外的跟踪,其额外优点是不需要灯塔、QR码(又称基准点)或其他外部元件。HPU用于识别一组有限的手势,这意味着基本交互不需要额外的输入设备。在扫描环境的同时,HPU还提取深度
并导出几何体数据,例如表示世界中曲面的平面和多边形。然后可以将该几何体用于碰撞检测,例如,让虚拟对象坐在真实世界的桌面上。
通过创建称为空间锚点的真实世界航路点,使用HPU进行跟踪,可以在世界任何地方有效地实现更大范围的运动。然后设置虚拟对象相对于特定空间锚点的位置【1207】。随着时间的推移,设备对这些锚定位置的估计也会提高。这些数据可以共享,这意味着少数用户可以在同一位置看到相同的内容。还可以定义锚定,以便不同位置的用户可以在同一模型上进行协作。
一对透明屏幕允许用户看到世界以及投影到这些屏幕上的任何东西。请注意,这与手机使用增强现实不同,增强现实中的世界视图由摄像头捕捉。使用透明屏幕的一个优点是,世界本身从来没有延迟或显示问题,并且不消耗任何处理能力。这种显示系统的一个缺点是,虚拟内容只能为用户的世界视图增加亮度。例如,一个深色的虚拟对象不会遮挡其后面更亮的真实世界对象,因为光线只能增加。这可以给虚拟对象一种半透明的感觉。全息透镜还有一个LCD调光器,可以帮助避免这种影响。通过适当的调整,该系统可以有效地显示三维虚拟对象与现实的融合。
苹果的ARKit和谷歌的ARCore帮助开发者为手机和平板电脑创建增强现实应用程序。通常显示单个(非立体)视图,设备与眼睛保持一定距离。对象可以是完全不透明的,因为它们覆盖在摄像机的世界视图上。见图21.2。对于ARKit来说,由内而外的跟踪是通过使用设备的运动传感硬件以及一组摄像头可见的显著特征来执行的。逐帧跟踪这些特征点有助于精确确定设备的当前位置和方向。像全息透镜一样,水平和垂直表面被发现,范围确定,然后将此信息提供给开发商【65】。
图21.2:。来自ARKit的图像。将检测地平面并将其显示为蓝色栅格。最近的豆袋椅是添加在地平面上的虚拟对象。它缺少阴影,但可以为对象添加这些阴影并在场景上混合。(图片由Autodesk,Inc.提供)
intel的Project Alloy是一款无固定头戴式显示器,与HoloLens一样,它有一个传感器阵列,可以检测房间中的大型物体和墙壁。与全息镜头不同,HMD不允许用户直接查看世界。然而,它感知周围环境的能力提供了英特尔所称的“融合现实”,即真实世界的对象可以在虚拟世界中有令人信服的存在。例如,用户可以在虚拟世界中接触控制台,并在现实世界中触摸桌子。
虚拟和增强现实传感器和控制器正在经历快速发展,令人惊讶的技术以惊人的速度出现。这些产品提供了更少干扰的耳机、更多的移动性和更好的体验。例如,谷歌的Daydream VR和高通公司的Snapdragon VR头戴式耳机不受束缚,使用由内而外的位置跟踪,不需要外部传感器或设备。HP、Zotac和MSI的系统将计算机安装在您的背部,使其成为无约束的系统,可以提供更多的计算能力。Intel的WiGig wire-less网络技术使用短程90 GHz无线电将图像从PC发送到耳机。另一种方法是在云上计算昂贵的照明计算,然后将这些压缩信息发送给耳机中更轻、功能更弱的GPU进行渲染【1187】。软件方法,如获取点云、对点云进行体素化以及以交互速率渲染体素化表示【930】为虚拟和真实的融合开辟了新的途径。
本章大部分内容的重点是显示器及其在VR和AR中的使用。我们首先介绍了图像如何在屏幕上显示的一些物理力学以及涉及的一些问题。本章继续介绍SDK和硬件系统为简化编程和增强用户对场景的感知所提供的功能。本节后面介绍了这些不同因素如何影响图像生成的信息,并讨论了一些图形技术需要如何被修改或可能完全避免。最后,我们讨论了提高效率和参与者体验的渲染方法和硬件增强。
本节介绍现代VR和AR系统的各种组件和特性,尤其是与图像显示相关的组件和特性。该信息为理解供应商提供的工具背后的逻辑提供了一个框架。
缓解延迟的影响在VR和AR系统中尤其重要,这通常是最关键的问题【5228】。我们在第3章中讨论了GPU如何隐藏内存延迟。由纹理提取等操作引起的这种延迟特定于整个系统的一小部分。这里我们指的是整个系统的“运动到光子”延迟。也就是说,你开始把头转向左边。从你的头朝向一个特定的方向到从该方向生成的视图被显示,需要多长时间?链中每个硬件的处理和通信成本
检测用户对响应(显示的新图像)的输入(例如,您的头部方向),所有这些都会导致数十毫秒的延迟。
系统中的常规显示器(即未连接显示器)的的延迟在最糟糕的情况是令人讨厌的,破坏了互动和联系的感觉。对于增强和混合现实应用程序,较低的延迟将有助于增加“像素棒”,即场景中的虚拟对象与真实世界的附着程度。系统中的延迟越长,虚拟对象相对于真实世界中的对象游动或漂浮的次数就越多。在沉浸式虚拟现实中,显示器是唯一的视觉输入,延迟可以产生更剧烈的效果。虽然不是真正的缺陷,但它被称为模拟缺陷,可导致出汗、头晕、恶心,甚至更糟。如果您开始感到不适,请立即服用离开HMD,您无法“克服”这种不适感,只会让不适应加重[公元1183年]。引用卡马克(Carmack)[650],“别推它。我们不需要在演示室里收拾病号。”事实上,真正的呕吐是罕见的,但其影响可能是严重的,使人虚弱,并且可以感觉到长达一天。
当显示图像与用户通过其他感官(如内耳前庭系统的平衡和运动)的期望或感知不匹配时,VR中会出现模拟病。头部运动和正确匹配显示图像之间的延迟越小,效果越好。一些研究指出,15毫秒是难以察觉的。超过20毫秒的延迟肯定会被感知到,并产生删除效应[59941311]。作为比较,从鼠标移动到显示,视频游戏的延迟通常为50 ms或以上,在vsync关闭的情况下为30 ms(第23.6.2节)。在VR系统中,90 FPS的显示速率是常见的,这使得帧时间为11.1 ms。在典型的桌面系统中,通过电缆将帧扫描到显示器上大约需要11 ms,因此即使可以在1 ms内进行渲染,也会有12 ms的延迟。
有多种基于应用的技术可以预防或减轻不适【1089,1183,1311,1802】。这些方法可以从最小化视觉流(例如,在前行时不吸引用户侧视,避免上楼梯)到更多的心理方法(例如,播放调幅音乐或渲染代表用户鼻子的虚拟对象)[1880]。更柔和的颜色和更暗的灯光也有助于避免模拟器缺陷。让系统的响应与用户的操作和期望相匹配是提供愉快的VR体验的关键。让所有对象对头部移动做出响应,不要缩放,使用相机或其他方式更改视野,适当缩放虚拟世界,并且不要将相机的控制权从用户手中夺走,以下是一些准则。在用户周围有一个固定的视觉参考,例如汽车或飞机驾驶舱,也可以减少模拟器缺陷。应用于用户的视觉加速可能会导致不适,因此最好使用恒定速度。硬件解决方案可能也很有用。例如,三星的Entrim 4D耳机会发出微小的电子im脉冲,影响前庭系统,从而可以匹配用户看看他们的平衡感告诉他们什么。时间会告诉我们这项技术的有效性,但这是一个迹象,表明正在进行多少研究和开发来减轻模拟器缺陷的影响。
跟踪姿势,或简单的姿势,是观众头部在真实世界中的方向和位置(如果可用)。姿势用于形成渲染所需的摄影机矩阵。可以在帧的开始处使用姿势的粗略预测来执行模拟,例如环境中角色和元素的碰撞检测。渲染即将开始时,此时可以检索新的姿势预测,并用于更新相机的视图。该预测将更加准确,因为它检索得较晚,持续时间较短。当图像即将显示时,可以检索到另一个更精确的姿势预测,并用于扭曲此图像以更好地匹配用户的位置。每个后续预测无法完全补偿基于早期预测的计算,不准确的预测,但尽可能使用它们可以大大改善整体体验。各种钻机中的硬件增强功能可在需要时快速查询和获取更新的头部姿势。
除了视觉效果之外,还有其他一些元素可以让与虚拟环境的交互更具说服力,但如果图形出现错误,用户最多也会有不愉快的体验。在应用程序中,最小化延迟和提高真实性有助于实现沉浸感或存在感,在这种情况下,界面会消失,参与者会感觉自己是虚拟世界的一部分。
设计精确的物理光学系统,将头戴式显示器的内容映射到视网膜上的相应位置,这是一项昂贵的提议。让虚拟现实显示系统负担得起的是,GPU生成的图像在单独的后处理中被扭曲,以便它们正确地到达我们的眼睛。
图21.3。用于在HTC Vive上显示的原始渲染目标(左)及其扭曲版本(右)[1823]。(图片由阀门提供。)
VR系统的镜头向用户呈现具有枕形失真的宽视场图像,其中图像的边缘似乎向内弯曲。如图21.3右侧所示,通过使用桶形失真扭曲每个生成的图像,可以消除这种影响。光学系统通常也会出现色差,透镜会导致颜色分离,就像棱镜一样。供应商的软件也可以通过生成具有反转色度分离的图像来补偿此问题。这是“另一个方向”的色差当通过VR系统的光学元件显示时,这些单独的颜色会正确组合。这种校正可以在畸变对中图像边缘周围的橙色条纹中看到。
有两种类型的显示器,滚动显示器和全局显示器[6]。对于这两种类型的显示器,图像都以串行流的形式发送。在滚动显示中,该流立即显示为接收到的,逐扫描线显示。在全局显示中,一旦接收到整个图像,它就会以单个短脉冲显示。虚拟现实系统中使用了每种类型的显示器,每种显示器都有自己的优点。与全局显示(必须等待整个图像出现后才能显示)相比,滚动显示可以最大限度地减少延迟,因为结果会尽快显示出来。例如,如果图像是以条带形式生成的,则每个条带可以在显示“racing the beam”之前以渲染的形式发送【1104】。缺点是不同的像素在不同的时间被照亮,因此根据视网膜和显示器之间的相对运动,图像可能会被视为抖动。这种不匹配对于增强现实系统来说尤其令人不安。好消息是,合成器通常通过在扫描线块上插值预测的头部姿势来进行补偿。这主要解决了头部快速旋转时可能发生的抖动或剪切,但无法纠正场景中移动的对象。
全局显示器没有这种类型的定时问题,因为图像必须在显示之前完全成形。相反,挑战是技术性的,因为一个短时间脉冲串排除了几个显示选项。有机发光二极管(OLED)显示器目前是全球显示器的最佳选择,因为它们的速度足以赶上VR使用中流行的90 FPS显示速度。
如图21.3所示,两幅图像偏移,每只眼睛的视图不同。这样做可以刺激立体视觉,即双眼对深度的感知。虽然立体视觉是一种重要的影响,但它会随着距离的增加而减弱,并且不是我们感知深度的唯一方式。例如,在标准显示器上查看图像时,我们根本不使用它。对象大小、纹理模式变化、阴影、相对运动(视差)和其他视觉深度提示仅使用一只眼睛。
图21.4。两只眼睛旋转多少才能看到一个物体,这就是辐合度。会聚是眼睛向内聚焦于物体的运动,如在左侧。发散是指当他们从页面右边缘向外看远处的物体时的向外运动。观察远处物体的视线实际上是平行的。
众所周知,眼睛必须在多大程度上调整形状才能聚焦某些东西作为适应需求。例如,Oculus Rift的光学系统相当于观察距离用户1.3米左右的屏幕。眼睛向内聚焦一个物体所需要的程度被称为收敛需求。见图21.4。在现实世界中,眼睛会改变晶状体形状并一致向内转动,这种现象被称为调节会聚反射。对于显示器,调节需求是恒定的,但当眼睛聚焦在不同感知深度的物体上时,收敛需求会发生变化。这种不匹配可能会导致眼睛疲劳,因此Oculus建议用户将要看到的任何物体放置在距离约0.75到3.5米的地方。这种不匹配也会在一些AR系统中产生感知效果,例如,用户可能会将注意力集中在现实世界中的远处对象上,但随后必须重新聚焦在眼睛附近固定深度处的关联虚拟广告牌上。可以根据用户的眼球运动调整感知焦距的硬件,有时称为自适应焦距或变焦显示,包括由多个团体进行研究和开发[976,1186,1875]。
VR和AR生成立体对的规则不同于单显示系统,在单显示系统中,某些技术(偏振光镜头、快门眼镜、多视图显示光学元件)从同一屏幕向每只眼睛呈现单独的图像。在VR中,每只眼睛都有一个单独的显示器,这意味着每只眼睛的位置都必须确保投射到视网膜上的图像与现实非常吻合。眼与眼之间的距离称为瞳孔间距离(IPD)。在一项针对4000名美国陆军士兵的研究中,发现IPD的范围为52毫米至78毫米,平均值为63.5毫米[1311]。VR和AR系统有校准方法来确定和
根据用户的IPD进行调整,从而提高图像质量和舒适度。系统的API控制包含此IPD的摄像头模型。最好避免修改用户感知的IPD以达到效果。例如,增加眼间距可以增强深度感知,但也可能导致眼睛疲劳。
头戴式显示器的立体渲染很难从头开始正确执行。好消息是,为每只眼睛设置和使用适当的相机变换的大部分过程都是由API处理的,这是下一节的主题。
让我们从一开始就这样说:除非您有很好的理由,否则请始终使用系统提供商提供的VR软件开发工具包(SDK)和应用程序编程接口(API)。例如,您可能认为自己的扭曲着色器速度更快,看起来也差不多。然而,在实践中,这很可能会导致用户严重不适,如果不进行广泛的测试,您不一定知道这是否属实。由于这个和其他原因,应用程序控制的失真已从所有主要API中删除;正确显示VR是一项系统级任务。为了优化性能和保持质量。本节讨论了各种供应商的SDK和API提供的支持。
将三维场景的渲染图像发送到耳机的过程很简单。在这里,我们将使用大多数虚拟和增强现实API所共有的元素来讨论它,并在此过程中注意特定于供应商的功能。首先,确定将要渲染的帧的显示时间。通常支持帮助您估计此时间延迟。需要该值,以便SDK可以计算出在看到帧的那一刻眼睛将位于何处和方向的估计值。考虑到这个估计的延迟,API是查询的方式,该姿势包含关于每只眼睛的相机设置的信息。如果传感器也跟踪此信息,则至少包括头部的方向和位置。OpenVR API还需要知道用户是站着还是坐着,这可能会影响用作原点的位置,例如跟踪区域的中心或用户头部的位置。如果预测是完美的,则渲染图像将在头部到达预测位置和方向时显示。这样,延迟的影响可以最小化。
给定每只眼睛的预测位置,通常将场景渲染为两个单独的目标。这些目标将作为纹理发送给SDK的合成器。合成器负责将这些图像转换为在机器上可以看到的最佳形式。合成器还可以将各个层合成在一起。例如,如果需要单目平视显示器,即双眼视图相同的显示器,则可以提供包含此元素的单个纹理作为单独的层,该层在每只眼睛的视图顶部合成。纹理可以是不同的分辨率和格式,合成器负责转换为最终的眼睛缓冲区。这样可以进行优化,例如动态降低三维场景层的分辨率,以节省渲染时间[619,1357,1805],同时保持其他层的高分辨率和质量[1311]。为每只眼睛合成图像后,SDK将执行失真、色差和任何其他所需的处理,然后显示结果。
如果依赖API,则不需要完全理解其中一些步骤之后的算法,因为供应商为您做了大量工作。然而,如果只是为了认识到最明显的解决方案并不总是最好的,那么对这一领域了解一点仍然是值得的。首先,考虑合成。最有效的方法是首先将所有层组合在一起,然后在此单个图像上应用各种纠正措施。相反,Oculus首先对每个层分别执行这些校正,然后合成这些扭曲的层以形成最终的显示图像。一个优点是,每一层的图像都以其自身的分辨率扭曲,这可以提高文本质量,例如,因为单独处理文本意味着在失真过程中重新采样和过滤只关注文本的内容【1311】。
用户感知到的视野大致为圆形。这意味着我们不需要在每个图像的边缘、角落附近渲染一些像素。虽然这些像素将出现在显示屏上,但观众几乎无法检测到。为了避免浪费生成这些图像的时间,我们可以首先渲染网格,以在生成的原始图像中隐藏这些像素。该网格作为遮罩渲染到模具缓冲区中,或渲染到前面的z缓冲区中。随后,这些区域中的后续渲染片段将在评估之前被丢弃。Vlachos(1823)报告称,这将使HTC Vive的填充率降低约17%。见图21.5。Valve的OpenVR API将此预渲染遮罩称为“隐藏区域网格”。
图21.6。左侧显示最终显示图像的网格。实际上,可以将该网格修剪回右侧的剔除版本,因为绘制黑色三角形不会给最终图像添加任何内容【1823年】。(图片由阀门提供。)
一旦我们有了渲染图像,就需要对其进行扭曲,以补偿系统光学系统的失真。其概念是将原始图像重新映射到所需的显示形状,如图21.3所示。换句话说,给定传入渲染图像上的像素采样,该采样在显示图像中移动到哪里?光线投射方法可以给出精确的答案并根据波长进行调【1423】,但对于大多数硬件来说是不切实际的。一种方法是将渲染图像视为纹理并绘制屏幕填充四边形以运行后期处理。像素着色器计算该纹理上与输出显示像素相对应的确切位置【1430】。然而,这种方法可能很昂贵,因为该着色器必须在每个像素处计算畸变方程。
将纹理应用于三角形网格更有效。该网格的形状可以通过畸变方程修改并渲染。仅扭曲网格一次将无法纠正色差。三组独立的(u,v)坐标用于扭曲图像,每个颜色通道一组【1423,1823】。也就是说,网格中的每个三角形渲染一次,但对于每个像素,渲染图像在稍微不同的位置采样三次。然后,这些红色、绿色和蓝色通道值形成输出像素的颜色。
我们可以对渲染图像应用规则间距的网格,并将其扭曲到显示的图像,反之亦然。将网格网格应用于显示的图像并将其扭曲回渲染图像的一个优点是,由于不会显示薄三角形,因此可能会生成较少的2×2四边形。在这种情况下,网格位置不会扭曲,而是渲染为网格,并且仅调整顶点的纹理坐标,以便扭曲应用于网格的图像。典型的网格是每只眼睛48×48个四边形。见图21.6。通过使用逐通道显示渲染图像变换,该网格的纹理坐标计算一次。通过将这些值存储在网格中,在着色器期间不需要复杂的变换处决GPU对纹理各向异性采样和过滤的支持可用于生成清晰的可显示图像。
图21.5中右侧的渲染立体对被显示网格扭曲。该图像中心移除的切片与翘曲变换生成可显示图像的方式相对应。请注意,该切片是如何从图21.5左侧显示版本中的图像相交处丢失的。通过将显示的扭曲网格修剪回可见区域,如图21.6右侧所示,我们可以将最终变形过程的成本降低约15%。
为了总结所描述的优化,我们首先绘制一个隐藏区域网格,以避免在我们知道无法检测或未使用的区域(例如中间切片)中评估碎片。我们为双眼渲染场景。然后,我们将此渲染图像应用于网格网格,该网格已修剪为仅包含相关渲染区域。将此网格渲染到新目标可以显示图像。这些优化的一部分或全部内置于虚拟和增强现实系统的API支持中。
渲染两个单独的视图似乎需要两倍于渲染单个视图的工作量。然而,正如威尔逊(Wilson)[1891年]所指出的那样,即使是一种幼稚的实现,这也不是真的。阴影贴图生成、模拟和动画以及其他元素与视图无关。像素着色器调用的数量不会加倍,因为显示本身在两个视图之间被一分为二。同样,后处理效果取决于分辨率,因此这些成本也不会改变。然而,与视图相关的顶点处理增加了一倍,因此已经探索了很多方法来减少这个成本。
截锥剔除通常在任何网格被发送到GPU管道之前执行。一个平截头体可以用来包住双眼平截头体【453,684,453】。由于消隐发生在渲染之前,因此可能会在消隐发生后重新检索要使用的精确渲染视图。然而,这意味着在剔除过程中需要一个安全裕度,因为检索到的这对视图可能会以其他方式查看由截锥删除的模型。Vlachos(1823)建议在视野上增加约5度,以便进行预测性剔除。Johnsson[838]讨论了截锥剔除和其他策略,例如实例化和遮挡消隐查询,可以组合用于大型建筑模型的VR显示。
渲染两个立体视图的一种方法是以一系列方式进行渲染,先渲染一个视图,然后渲染另一个视图。实施起来很简单,这有一个明显的缺点,即状态更改也会加倍,这是需要避免的(第18.4.2节)。对于基于平铺的渲染器,频繁更改视图和渲染目标(或剪切矩形)将导致糟糕的性能。一个更好的替代方法是在移动过程中渲染每个对象两次,在两者之间切换摄影机变换。然而,API绘图调用的数量仍然增加了一倍,导致了额外的工作。想到的一种方法是使用几何体着色器复制几何体,创建每个视图的三角形。例如,DirectX 11支持几何体着色器将其生成的三角形发送到单独的目标。不幸的是,这种技术被发现将几何吞吐量降低了三倍或更多,因此在实践中没有使用。一个更好的解决方案是使用实例化,其中每个对象的几何体通过单个绘制调用绘制两次[8381453]。将用户定义的剪裁平面设置为使每只眼睛的视图保持独立。使用实例比使用几何体着色器快得多,并且是一个很好的解决方案,除非有任何额外的GPU支持[18231891]。另一种方法是在渲染一只眼睛的图像时形成命令列表(第18.5.4节),将引用的常量缓冲区移动到另一只眼睛的变换,然后回放此列表用于渲染第二只眼睛的图像[4531473]。
有几个扩展可以避免沿渲染管道两次(或多次)发送几何体。在一些移动电话上,名为多重视图的OpenGL ES 3.0扩展支持只发送一次几何体并将其渲染到两个或多个视图,对屏幕顶点位置和任何依赖于视图的变量进行调整[453,1311]。该扩展为实现立体渲染器提供了更大的自由度。例如,最简单的扩展可能会在驱动程序中使用实例化,发出两次几何体,而需要GPU支持的实现可能会将每个三角形发送到每个视图。不同的实现有着不同的优势,但由于API成本总是会降低,这些方法中的任何一种都可以帮助CPU受限的应用程序。例如,更复杂的实现可以提高纹理缓存效率[678],并仅执行一次视图独立属性的顶点着色。理想情况下,可以为每个视图设置整个矩阵,也可以为每个视图着色任何逐顶点属性。要使硬件实现使用晶体管更少,GPU可以实现这些功能的一个子集。
AMD和NVIDIA提供了针对VR立体渲染的多GPU解决方案。对于两个GPU,每个GPU渲染一个单独的眼睛视图。CPU使用关联掩码为所有要接收特定API调用的GPU设置一个位。通过这种方式,可以将呼叫发送到一个或多个GPU【1104145314731495】。如果右眼和左眼的视图之间的调用不同,则使用关联掩码时,仍然需要调用两次API。
供应商提供的另一种渲染方式是NVIDIA称之为广播的方式,即使用单个绘制调用向双眼提供渲染,即向所有GPU广播。恒定缓冲区用于向不同的GPU发送不同的数据,例如眼睛位置。由于唯一的成本是设置第二个恒定缓冲区,因此广播创建双眼图像的CPU开销几乎不比单个视图多。
单独的GPU意味着单独的目标,但合成器通常需要单个渲染图像。有一个特殊的子矩形传输命令,可以在毫秒或更短的时间内将渲染目标数据从一个GPU转移到另一个GPU【1471】。它是异步的,这意味着传输可以在GPU执行其他工作时发生。由于两个GPU并行运行,两者还可以分别创建渲染所需的阴影缓冲区。这是重复的工作,但比尝试并行化进程和GPU之间的传输更简单,通常更快。整个两个GPU设置的渲染速度大约为30%到35%[1824]。对于已经针对单个GPU进行了优化的应用程序,多个GPU可以应用其额外的计算其他样本以获得更好的抗锯齿结果。
立体视觉的视差对于附近的模型很重要,但对于远处的物体则可以忽略不计。Palandri和Green【1346】在移动GearVR平台上利用了这一事实,使用了垂直于视图方向的分离面。他们发现大约10米的飞机距离是一个很好的默认值。比这更近的不透明对象将以立体方式渲染,比这更近的不透明对象将使用放置在两个立体摄影机之间的单视摄影机进行渲染。为了最小化过度绘制,首先绘制立体视图,然后使用其深度缓冲区的交点 初始化单个单视渲染的z缓冲区。然后,远程对象的图像将与每个立体视图合成。每个视图最后呈现透明内容。而更多涉及到的方法是,跨越分离平面的物体需要额外的一次pass,从而产生了大约25%的资源节约,而不会损失质量或深度感知。
如图21.7所示,由于光学系统所需的失真,每只眼睛图像的边缘会产生更高密度的像素。此外,外围通常不太重要,因为用户在相当长的时间内都会朝屏幕的中心看。由于这些原因,已经开发了各种技术,用于对每只眼睛视图外围的像素进行较少的处理。
一种沿外围降低分辨率的方法称为NVIDIA的多分辨率着色和AMD的可变速率着色。其想法是将屏幕划分为3×3个部分,并以较低分辨率渲染周边区域【1473】,如图21.8所示。自Maxwell体系结构以来,NVIDIA就支持这种分区方案,但启用Pascal后,支持更通用的投影类型。这称为同时多重投影(SMP)。Ge测量最多可通过16个单独的投影乘以2个单独的眼睛位置进行处理,允许网格最多复制32次,而无需在应用方面增加成本。第二只眼睛的位置必须等于第一只眼睛沿x轴的位置偏移。每个投影可以独立倾斜或旋转轴心[1297]。
图21.7:。左侧是一只眼睛的渲染图像。右侧是要显示的扭曲图像。请注意中心的绿色椭圆形如何保持大致相同的面积。在外围,渲染图像中较大的区域(红色轮廓)与较小的显示区域相关联【1473】。(图片由NVIDIA Corporation提供。)
使用SMP,可以实现镜头匹配着色,目标是更好地将渲染分辨率与显示内容匹配。见图21.7。渲染四个具有倾斜平面的圆台,如图21.9左侧所示。这些修改后的投影在图像中心提供了更多的像素密度,而在外围提供了更少的像素密度。与多分辨率着色相比,这会使截面之间的过渡更加平滑。有一些缺点,例如,需要对诸如blooms之类的效果进行返工以正确显示。Unity和Unreal Engine 4已将此技术集成到其系统中【1055】。Toth等人【1782年】正式比较和对比了这些和其他多视图投影算法,并使用每只眼睛最多3×3个视图来进一步减少像素着色。请注意,SMP可同时应用于双眼,如图21.9右侧所示。
图21.8:。假设我们要渲染左侧的视图,外围的分辨率较低。我们可以根据需要降低任何区域的分辨率,但通常最好沿共享边保持相同的分辨率。在右边,我们展示了蓝色区域是如何在像素数减少50%,红色区域减少75%。视野保持不变,但用于外围区域的分辨率降低。
为了节省碎片处理的时间,一种称为径向密度掩蔽(radial density masking)的应用程序级方法以棋盘格四边形模式渲染外围像素。换句话说,每隔2×2个四分之一的片段不会被渲染。然后使用后处理过程从相邻像素重建缺失的像素【1824】。这项技术对于使用单一低端GPU的系统尤其有价值。使用此方法渲染将减少像素着色器调用,但如果跳过然后执行重建过滤器的成本太高,则可能不会获得任何好处。索尼的伦敦工作室在这一过程中更进一步,放弃了一、二 或2×2集合中的三个四边形,在图像边缘附近下降的数量增加。缺少的四边形将以类似的方式填充,并且抖动模式将在每帧中更改。应用时间抗锯齿还有助于隐藏楼梯踏步瑕疵。索尼的系统节省了大约25%的GPU时间。
另一种方法是为每只眼睛渲染两个单独的图像,一个是中心圆形区域,另一个是形成外围的环形区域。然后,这两个图像可以合成和扭曲,以形成该眼睛的显示图像。外围设备的图像可以以较低的分辨率生成,以节省像素着色器调用,而代价是发送几何体以形成四个不同的图像。这项技术与GPU支持很好地吻合,GPU支持将几何图形发送到多个视图,并为具有两个或四个GPU的系统提供自然的分工。虽然是为了减少由于光学元件所涉及的外围过度像素着色头盔显示器Vlachos称这种技术为固定中心凹渲染【1824年】。这个术语是指一个更高级的概念,中心凹渲染。
要理解这种渲染技术,我们必须对眼睛有更多的了解。中央凹是我们眼睛视网膜上的一个小凹陷,由高密度的视锥细胞组成,视锥细胞是与色觉相关的光感受器。我们的视力在这一区域是最高的,我们转动眼睛来利用这一能力,例如跟踪飞行中的鸟,或阅读页面上的文字。视力下降很快,在前30度时,距中央凹中心每2.5度,视力下降约50%,而在更远的地方,视力下降幅度更大。我们的眼睛有114个水平度的双目视野(双眼可以看到同一物体)。第一代消费类耳机的视场较小,大约为80到100个水平度对于两只眼睛来说,这可能会上升。从2016年起,中央20度视野的面积约占HMD显示器的3.6%,预计2020年左右下降到2%[1357]。在此期间,显示器分辨率可能会提高一个数量级[8]。
由于显示器的像素在低视力区域具有巨大的优势,这为使用中心凹渲染减少工作量提供了机会[619,1358]。其想法是以高分辨率和高质量渲染眼睛所指向的区域,而在其他方面花费的精力较少。问题是眼睛会移动,因此知道要渲染的区域会发生变化。例如,当研究一个物体时,眼睛执行一系列称为扫视的快速移动,以每秒900度的速度快速移动,即在90 FPS的系统中每帧可能移动10度。精确的眼球跟踪硬件可能会通过在中央凹区域外执行较少的渲染工作来提供较大的性能提升,但此类传感器是一项技术挑战[8]。此外,在外围渲染“较大”像素往往会增加锯齿问题。通过尝试保持对比度并避免随时间发生较大变化,使这些区域在视觉上更容易接受,可以潜在地改善分辨率较低的外围区域的渲染【1357】。Stengel等人【1697年】讨论了以前的中心凹渲染方法,以减少着色器调用的数量,并展示了它们自己的方法。
对世界单视角有效的东西不一定对世界双视角有效。即使在立体声系统中,在单个固定屏幕上使用的技术与在随观众移动的屏幕上使用的技术也有很大的不同。在这里,我们讨论了可能在单屏上运行良好,但对VR和AR来说存在问题的特定算法。我们借鉴了Oculus、Valve、Epic Games、Microsoft等公司的专业知识。这些公司的研究继续被编入用户手册,并在博客中进行讨论,因此我们建议访问他们的网站,了解当前的最佳应用【1207,1311,802】。
正如前一节所强调的,供应商希望您了解他们的SDK和API并正确使用它们。视图非常关键,因此请遵循供应商提供的头部模型,并准确获取相机投影矩阵。应避免使用频闪灯等效果,因为闪烁会导致头痛和眼睛疲劳。在视野边缘附近闪烁会导致模拟器缺陷。闪烁效应和高频纹理(如细条纹)也会引发一些人的癫痫发作。
基于显示器的视频游戏通常使用平视显示器,上面覆盖着关于生命、弹药或剩余燃料的数据。然而,对于VR和AR而言,双目视觉意味着更靠近观看者的物体在两眼辐合之间有更大的偏移(第21.2.3节)。如果将HUD放置在双眼屏幕的同一部分,则感知提示是HUD必须远离,如第923页图21.4所示。然而,HUD是在所有东西前面绘制的。这种感知上的不匹配使得用户很难融合这两幅图像并理解他们所看到的内容,并且会导致不适【684,1089,1311】。将HUD内容切换到接近眼睛的深度渲染可以解决这一问题,但仍以屏幕不动产为代价。见图21.10。如果附近的墙比十字线更近,那么仍然存在深度冲突的风险,因为十字线图标仍在给定深度的顶部渲染。投射光线并找到给定方向上最近的曲面深度可以通过多种方式来调整该深度,可以直接使用该深度,也可以在需要时将其平滑地移近【1089,1679】。
图21.10。占主导地位的繁忙平视显示器。请注意,必须为每只眼睛移动HUD元素,以避免混淆深度提示。一个更好的解决方案是考虑将这些信息放入作为虚拟世界本身一部分的设备或显示器中,或者放在玩家的化身上,因为用户可以倾斜或转动头部【1311】。要在此处看到立体效果,请靠近并在图像之间垂直于页面放置一张小而硬的纸,以便一只眼睛可以看到每一张。(图片由Oculus VR,LLC提供)
凹凸贴图在某些情况下与任何立体查看系统的效果都很差,正如在平面上绘制的着色所示。它可以用于精细的表面细节和远处的物体,但对于表示更大几何形状且用户可以接近的法线贴图,这种错觉很快就会消失。
见图21.11。基本视差贴图的游动问题在立体中更为明显,但可以通过一个简单的校正因子来改善[1171]。在某些情况下,可能需要更昂贵的技术,如陡视差贴图、视差遮挡贴图(第6.8.1节)或位移贴图[1731],才能产生令人信服的效果。
图21.11。较小曲面特征(例如左侧和中间的两个纹理)的法线贴图可以在VR中正常工作。当在立体视图中查看时,表示相当大几何特征的凹凸纹理(如右侧的图像)近距离观察时将无法令人信服[1823]。
当用立体声观看时,广告牌和冒名顶替者有时无法令人信服,因为它们缺乏表面z深度。体积技术或网格可能更合适【1191,1802】。天空盒的大小需要使其呈现为“无限大”左右,即眼睛位置的差异不应影响其亮度。如果使用色调映射,则应将其平均应用于两个渲染图像,以避免眼睛疲劳[684]。屏幕空间环境遮挡和反射技术可能会产生不正确的立体差异【344】。类似地,后处理效果(如初轧或耀斑)的生成方式需要考虑每个初轧或耀斑的z深度使图像正确融合的眼睛视图。水下或热雾变形效果也需要再修改。屏幕空间反射技术产生的反射可能存在匹配问题,因此反射探头可能更有效[1802]。甚至镜面突出显示也可能需要修改,因为立体视觉可能会影响光泽材质的感知。两幅眼睛图像之间的高光位置可能存在很大差异。研究人员发现,改变这种差异可以让图像更容易融合,更具说服力。换言之,在计算光泽组件时,眼睛位置可能会彼此移动得更近一些。相反,图像之间可能无法察觉远处物体的高光差异,这可能导致共享着色计算[1781]。如果计算完成并存储在纹理空间中,则可以在眼睛图像之间共享阴影【1248】。
VR对显示技术的要求极高。例如,与使用水平视野为50度的显示器不同,VR显示器上的110度视野可能会使每只眼睛的1080×1200像素显示器产生约15像素/度的效果[1823]。从渲染图像到显示图像的变换也会使重新采样和正确过滤的过程复杂化。用户的头部不断移动,即使只是一点点,也会导致时间锯齿的增加。由于这些原因,高质量的抗混叠实际上是提高图像质量和融合的一项要求。虽然索尼至少有一个团队成功地使用了时间抗锯齿技术,但由于存在潜在的模糊,通常建议对[344]使用时间抗锯齿技术。他们发现两者之间存在权衡,但去除闪烁的像素比提供更清晰的图像更重要。然而,对于大多数VR应用程序,MSAA提供的更清晰的视觉效果是首选【344】。请注意,如果您负担得起的话,4×MSAA更好,8×更好,抖动超采样更好。MSAA的这种偏好不利于使用各种延迟渲染方法,对于每个像素的多个采样来说成本很高。
在VR显示器上,从阴影表面上缓慢变化的颜色(第23.6节)产生的条带可能特别明显。这种人造错觉可以通过加入一点抖动噪声来掩盖【1823】。
不应使用运动模糊效果,因为它们会使图像变得浑浊,超出由眼球运动产生的任何人造错觉。这种效果与以90 FPS速度运行的VR显示器的低持久性特性不符。因为我们的眼睛确实会快速地移动到广阔的视野中(扫视),所以应该避免使用景深技术。这种方法使场景外围的内容看起来模糊,没有真正的原因,并可能导致模拟器缺陷【18021878】。
图21.12。抖动。四个帧显示在一行中,CPU和GPU试图为每个帧计算一个图像。第一帧(以粉红色显示)的图像会及时计算,以将其发送给该帧的合成器。下一幅蓝色图像未及时完成,无法在第二帧中显示,因此必须再次显示第一幅图像。绿色的第三个图像再次显示为及时准备就绪,因此(现在已完成)第二幅图像将发送给第三帧的合成器。橙色的第四幅图像及时完成,因此显示出来。请注意,第三帧的渲染计算结果永远不会显示。(Oculus之后的插图【1311】。)
混合现实系统带来了额外的挑战,例如将类似的照明应用于虚拟对象,就像现实世界中存在的一样。在某些情况下,可以提前控制真实世界的照明并将其转换为虚拟照明。如果无法做到这一点,则可以使用各种灯光估计技术动态捕获和近似环境的照明条件。Kronander等人【942】深入调查了各种照明捕捉和表示方法。
即使在虚拟世界和现实世界之间有完美的跟踪和适当维护的通信,延迟仍然是一个问题。以45到120 FPS的速度生成图像需要有限的时间,这是一系列VR设备的更新速度【125】。
如果没有及时生成图像以发送到合成器并显示,则会出现丢弃的帧。对Oculus Rift的早期发射标题进行的检查表明,它们的帧下降了约5%[125]。掉落的帧会增加抖动的感觉,这是VR耳机中的一种涂抹和抚摸伪影,当眼睛相对于显示器移动时,这种伪影最为明显。见图21.12。如果像素在帧的持续时间内被照亮,则会在眼睛的视网膜上接收涂片。降低持久性,即在一帧期间显示器照亮像素的时间长度,可以减少涂抹。然而,它可能会导致笔划,如果帧之间有很大的变化,就会感知到多个单独的图像。Abrash【7】深入讨论抖动及其与显示技术的关系。
供应商提供的方法可以帮助最小化延迟和抖动影响。Oculus称之为时间扭曲和空间扭曲的一组技术,将生成的图像进行扭曲或修改,以更好地匹配用户的方向和位置。首先,假设我们没有丢弃帧,我们检测到用户正在旋转头部。我们使用检测到的旋转来预测每只眼睛的位置和方向。通过完美的预测,我们生成的图像完全符合需要。
换言之,用户正在旋转他们的头并且正在减速。为了这个场景我们的预测会超出预期,生成的图像会比显示时的位置稍微提前一点。除了速度之外,估计旋转加速度有助于改进预测[994,995]。
当框架掉落时,会发生更严重的情况。在这里,我们必须使用前一帧的图像,因为需要在屏幕上显示一些内容。根据我们对用户视图的最佳预测,我们可以修改此图像以近似丢失帧的图像。我们可以执行的一个操作是二维图像扭曲,Oculus称之为时间扭曲。它仅补偿头部姿势的旋转。这种扭曲操作是一种快速纠正措施,比什么都不做要好得多。Van Waveren【1857年】讨论了各种时间扭曲实现的权衡,包括那些在CPU和数字信号处理器(DSP)上运行的处理器,得出的结论是,GPU是迄今为止完成此任务最快的处理器。大多数GPU可以在不到半毫秒的时间内执行此图像扭曲过程[1471]。旋转先前显示的图像可能会导致显示图像的黑色边框在用户的周边视觉中变得可见。渲染大于当前帧所需的图像是避免此问题的一种方法。然而,实际上,这一边缘区域几乎是不可见的[228,1824,1857]。
除了速度之外,纯旋转扭曲的一个优点是场景中的其他元素都是一致的。用户实际上处于环境天空盒的中心(第13.3节),仅更改视图方向和方向。这项技术速度快,效果好。丢失帧已经够糟糕的了,但由于间歇性丢失帧而导致的可变和不可预测的延迟似乎会更快地导致模拟器缺陷,【591,311】。为了提供更平滑的帧速率,当检测到帧丢失时,Valve会启动其交错重投影系统,将渲染速率降低到45 FPS,并每隔一帧扭曲一次。同样,VR的一个版本在PLAYSTATION上,刷新率为120 Hz,其中以60 Hz的频率进行渲染,并进行重投影以填充交替帧【59】。
仅针对旋转进行校正并不总是足够的。即使用户不移动或改变位置,当头部旋转或倾斜时,眼睛也会改变位置。例如,当仅使用图像扭曲时,眼睛之间的距离似乎会变窄,因为新图像是使用指向不同方向的眼睛的眼睛分离生成的【1824】。这是一个很小的影响,但如果观察者附近有物体,或者观察者向下看纹理地平面,如果没有正确补偿位置变化,可能会导致用户迷失方向和生病。要调整位置变化,可以执行全三维重投影(第12.2节)。图像中的所有像素都有一个与其相关的深度,因此可以将该过程视为将这些像素投影到其在世界上的位置,移动眼睛位置,然后将这些点重新投影回屏幕。Oculus将此过程称为位置时间扭曲[62]。除了纯粹的消耗外,这样的过程还有几个缺点。一个问题是,当眼睛移动时,一些表面可能会进入或离开视线。这可能以不同的方式发生,例如,立方体的表面可能变得可见,或者视差可能导致前景中的对象相对于背景发生移动,从而隐藏或显示那里的细节。重投影算法试图识别不同深度的物体,并使用局部图像扭曲。填补发现的任何空白【1679年】。这样的技术可能会导致混乱的轨迹,扭曲会使远处的细节在对象经过它们之前时发生移动和动画。由于只知道一个曲面的深度,因此基本重投影无法处理透明度。例如,这种限制可能会影响粒子系统的外观[6521824]。
图像扭曲和重投影技术的一个问题是,碎片的颜色是根据旧位置计算的。我们可以改变这些碎片的位置和可见性,但任何镜面反射高光或反射都不会改变。掉落的帧可以显示这些曲面高光的抖动,即使曲面本身发生了完美的移动。即使没有任何头部移动,这些方法的基本版本也无法补偿场景中的对象移动或动画【62】。只有曲面的位置是已知的,而不是它们的速度。因此,对象看起来不会在帧之间自行移动外推图像。如第12.5节所述,可以在速度缓冲器中捕捉物体的运动。这样做可以让重投影技术也适应这种变化。
旋转和位置补偿技术通常在单独的异步过程中运行,作为防止帧丢失的一种形式。Valve调用此异步重投影,以及Oculus异步时间扭曲和异步空间扭曲。空间扭曲通过分析以前的帧来推断丢失的帧,同时考虑相机和头部平移以及动画和控制器移动。深度缓冲区未在空间扭曲中使用。除了正常渲染外,还可以同时独立计算外推图像。由于基于图像,此过程需要相当长的时间,这意味着如果无法及时完成渲染,通常可以使用重新投影的图像。因此,与其决定是继续尝试完成帧,还是使用时间扭曲或空间扭曲重投影,两者都已完成。如果帧未及时完成,则可以使用空间结果。硬件需求适中,这些扭曲技术主要是为了帮助能力较差的系统。Reed和Beeler【1471】讨论了GPU共享的不同方式,以及如何有效地使用异步扭曲,Hughes等人也是如此【783】。
旋转和定位技术是互补的,每种技术都有自己的改进。在观看远处的静态场景或图像时,旋转扭曲非常适合调节头部旋转。位置重投影适用于附近的动画对象【126】。方向的改变通常会比位置的改变造成更严重的配准问题,因此,即使仅仅旋转校正也能提供相当大的改进【1857年】。
我们在这里的讨论涉及这些补偿过程背后的基本思想。当然,关于这些方法的技术挑战和局限性还有更多的文章,我们请感兴趣的读者参考相关参考文献[62,125,126,228,1311,1824]。
虽然异步时间扭曲和空间扭曲技术有助于避免抖动,但保持质量的最佳建议是应用程序本身尽可能避免丢弃帧[591824]。即使没有抖动,我们也注意到用户在显示时的实际姿势可能与预测的姿势不同。因此,一种称为后期方向扭曲的技术可能有助于更好地匹配用户应该看到的内容。其思想是获取姿势并像往常一样生成帧,然后在帧中检索更新的姿势预测。如果此新姿势与原始姿势不同用于渲染场景的姿势,然后在此帧上执行旋转扭曲(时间扭曲)。由于翘曲通常需要不到半毫秒的时间,因此这种投资通常是值得的。实际上,这种技术通常是合成器本身的责任。
通过这个进程在一个单独的CPU线程上运行,使用一种称为延迟锁存的技术[147,1471]。此CPU线程定期将预测的姿势发送到GPU的专用缓冲区,GPU在扭曲图像之前的最后一刻获取最新设置。延迟锁定可用于直接向GPU提供所有头部姿势数据。这样做的限制是,此时应用程序无法使用每只眼睛的视图矩阵,因为只有GPU提供了此信息。AMD有一个改进的版本,称为“最新数据锁存器”,它允许GPU在需要这些数据的时候捕捉最新的姿势【1104】。
您可能已经注意到,在图21.12中,CPU和GPU有相当多的停机时间,因为直到完成合成器,CPU才开始处理。这是单CPU系统的简化视图,其中所有工作都发生在单个帧中。如第18.5节所述,大多数系统都有多个CPU,可以以多种方式保持工作。实际上,CPU通常处理碰撞检测、路径规划或其他任务,并为GPU准备数据以在下一帧中渲染。流水线完成了,GPU在上一帧中设置的CPU上工作【783】。为了有效,CPU和GPU每帧的工作时间都应该少于一帧。见图21.13。合成器通常使用一种方法来知道GPU何时完成。它被称为围栏,由应用程序作为命令发出,并在所有GPU调用完全执行之前发出信号。围栏对于了解GPU何时使用各种资源完成非常有用。
图中显示的GPU持续时间表示渲染图像。一旦合成器完成创建和显示最终帧,GPU就可以开始渲染下一帧。CPU需要等到合成完成后才能向GPU发出下一帧的命令。然而,如果我们等到图像显示出来,那么应用程序在CPU上生成新命令(由驱动程序解释)以及最终向GPU发出命令时就会花费时间。在此期间,GPU处于空闲状态,时间可能高达2 ms。Valve和Oculus通过提供名为start和自适应排行队列。这种技术可以在任何系统上实现。其目的是让GPU在处理完前一帧后立即开始工作,方法是对前一帧预计完成的时间进行计时,并在该时间之前发出命令。大多数VR API提供了一些隐式或显式机制,用于以常规的节奏释放应用程序以处理下一帧,并有足够的时间来最大化吞吐量。在这一节中,我们提供了一个简化的管道和这个缺口的视图,以了解这种优化的好处。详见Vlachos(1823)和Mah(1104)的用于深入讨论流水线和计时策略的演示文稿。
我们在这里结束对虚拟和增强现实系统的讨论。鉴于写作和出版之间的滞后,我们预计会出现任何数量的新技术,并取代此处介绍的技术。我们的主要目标是提供在这个快速发展的领域中涉及的渲染问题和解决方案。最近研究探索的一个迷人方向是使用光线投射进行渲染。例如,Hunt[790]讨论了这些可能性,并提供了一个开源CPU/GPU混合光线投射器,每秒可评估超过100亿条光线。光线投射直接解决了基于光栅化器的系统面临的许多问题,如宽视野和镜头失真,同时也可以很好地处理中心凹渲染。McGuire[1186]指出,在滚动之前,光线是如何在像素处投射的显示屏会显示它们,从而将系统该部分的延迟减少到几乎为零。这一点,加上许多其他研究举措,使他得出结论,我们未来将使用VR,但不称之为VR,因为它只是每个人的与计算机交互的接口。
Abrash的博客【5】中有一些关于虚拟现实显示、延迟、抖动和其他相关主题的有价值的文章。对于有效的应用程序设计和渲染技术,Oculus最佳实践网站[1311]和博客[994]提供了许多有用的信息,Epic Games的虚拟现实页面[1802]也是如此。您可能希望学习OpenXR作为跨平台虚拟现实开发的代表性API和体系结构。路德维希关于将Team Fortress 2转换为VR的案例研究【1089】涵盖了一系列用户体验问题和解决方案。
McGuire【11861187】概述了NVIDIA在VR和AR领域的研究工作。Weier等人【1864】提供了一份全面的最新报告,讨论了人类视觉感知以及如何在计算机图形学中利用其局限性。Patney[1358]于年组织的SIGGRAPH 2017课程包括与视觉感知相关的虚拟和增强现实研究演示。Vlachos的GDC演示文稿【1823、1824】讨论了高效渲染的具体策略,并给出了我们仅讨论的几种技术的更多细节,短暂地NVIDIA的GameWorks博客【1055】包含了一些有价值的文章,介绍了GPU对VR的改进以及如何更好地使用这些改进。Hughes等人【783】提供了一个深入的教程,介绍如何使用XPerf、ETW和GPUView工具来调整VR渲染系统,使其性能良好。Schmalstieg和Hollerer的新书《增强现实》(Augmented Reality)[1570]涵盖了与该领域相关的广泛概念、方法和技术。