延迟的角度来看,VR 技术是一项最需要“人在环中(Human-In-Loop)”的应用。对于高质量的 VR 体验而言,最重要的是用户头部物理移动与 HMD 上实时刷新图像到达用户眼睛之间的延迟时间。人类的感官系统在一定范围内能感知到视觉和听觉中相对较小的延迟,但是当绝对延迟控制大约 20ms 以内的时候,这些延迟几乎就不可察觉了。目前互动式的 3D 系统造成的延迟要比这个数字高上几倍,但如果不断调试同一组硬件的话我们终究会满足要求。
——John Carmack
延迟问题是 Oculus VR 所面对的主要问题,当然这也是 VR 整体需要解决主要问题。延迟能够影响沉浸式体验,也能够造成玩家的呕吐和不适应,所以找出造成这一问题的所在和解决方法是十分重要的。
为什么会有延迟?
整个系统的延迟控制在 50ms 就会感觉相对不错,但还是能感觉到。当延迟低于 20ms,人就无法感知出来了,这可以说是 VR 最佳体验的标准。
信号传递有延迟
预测传感器数据可以被用于减缓一些系统延迟,但即使是最精准的人类头部移动模型,在用户实际使用的时候,还是会有预测不准的时候。
滤波和通讯所带来的延迟是持续存在的,但大多数传感器不同步的刷新会引入了一个可变延迟,或者说当渲染的帧率与传感器的刷新率不同的时候,也会造成延迟的不规律波动。
屏幕刷新有延迟
早期的 LCD 屏幕在画面滚动和变化的时候,因会有几十毫秒的残影而饱受诟病,但在过去二十年里,这一技术有了长足的进步。LCD 每一个像素点的转换时间取决于色彩变化的程度,一块优秀的面板的转换时间能控制在大约 10ms 之内,而为 3D 显示和游戏而优化过的显示器能减少一半左右的切换时间。
一些不常见的显示技术比 LCD 面板的刷新速度更高;OLED 子像素的刷新时间低于 1ms,而激光显示屏和 CRT 反应一样及时。
另一个不易察觉的延迟是:大多数显示器是逐行显示图像的,而显示器的图像是从计算机里读取的,但由于计算机自身的原因,会导致帧率为 60fps 显示器上,屏幕底部的画面要比顶部的刷新时间慢16ms 左右。
在静止的屏幕上,这根本算不上问题。然而在 HMD 里,因为源图像是即时渲染出的,但不同的部分显示在屏幕上的时间是不同的,所以它可能造成图像的左边或右边被裁剪掉;或转动头部时,图像出现晃动。这个效应在使用 LCD 屏幕的 HMD 上不易察觉,但在刷新更快的 OLED 屏幕的 HMD 上却更容易显现出来。
如何降低延迟?
双 GPU 立体渲染可降延迟
立体渲染降低延迟的一个诱人的解决方案是:将图形处理系统分拆成两个,并分别配备一个 GPU,每个 GPU 只需单独渲染一只眼睛的图像,这样可以达到最佳的性能表现和最低的延迟,其代价是要求设备能够管理两个相互独立的渲染内容的缓存。
但它的问题是如果设备无法维持两个 GPU 的缓存,设备的数据吞吐性能会下降,在缓存过载的情况下,还会导致帧率更严重地下降。
合理安排数据采样
大多数模拟输入的任务不直接依赖于用户的输入数据,换而言之,这一数据的输入对一帧的延迟并不敏感。如果在需要用户输入的数据时采样,而不是在一开始就离线缓存输入数据,则能减少总体的延迟。(这种方法被称之为 late frame scheduling,延迟帧调度)
late frame scheduling 也是一种解决方案,但其缺点在于它使得调度需求非常紧凑——通常情况下,late frame scheduling 需要一定的时间,并会造成电力浪费。不过如果你的帧率是由视频回扫决定的,而不是随机读取视频片段,那么通过图片驱动辅助确定目前需要扫描输出的准确位置,也会有助于降低延迟。
避免渲染全部重新编码
另一个与 late frame scheduling 一样,可以降低延迟的方法是:允许渲染编码根据底层的游戏编码,以及用户输入的最新样本,修正输入到渲染编码中的参数(这种方法称之为 View bypass)。对比用户前后输入样本,设备可以确定出哪一个是用户输入的变量。而变量可以被用于修正游戏提交给渲染编码的视觉矩阵。
这种变量处理的方式可以最小化处理的复杂程度,不过游戏中也经常会有无需用户输入的渲染场景,比如经典镜头的剪辑或者玩家死亡的情形。一个为 VR 而生的游戏应该是否应该避免这样的情形尚有争议,因为在 HMD 里一个无法响应的视角是会让人感到迷惑或者不快,但在传统游戏设定里会有很多这样的场景,这样的场景很常见。
合理安排每一帧的渲染时间
如果我们能知道渲染一帧具体需要花费多长时间,那么一些额外的延迟可以通过整个渲染任务的 late frame scheduling 来节省下来,但这显然不实际,因为渲染时间难以预估。但渲染好的图像后是可以往后安排处理任务的,并且能争取到一段可预测的时间,从而使得 late fram scheduling 更容易。(这一方法被称之为 time warp)
绘制出一副高质量的图像之后(使用过 View bypass),这幅图像不是直接呈现出来,而是让开发者继续抓取用户输入的最新的数据,生成更新的视觉参数,然后计算出与输入数据相匹配的已渲染图像需要变形成什么样,放置在什么位置。经过这一次转换之后,渲染变形后的图像能与与用户实际操作后应该看到的图像更相符
本文来源:不详 作者:佚名