翻译: https://www.oculus.com/blog/asynchronous-timewarp/
异步时间扭曲(Asynchronous Timewarp 时间扭曲,即调整时长)调查
关于作者:迈克尔·安东诺夫,他是Oculus的首席软件工程师,领导SDK团队,在来Oculus之前,他是Scaleform的CTO,在那里他领导硬件加速Flash矢量图形引擎项目,这个引擎被用到上百个视频游戏中,在他的职业生涯里,他主要关注复杂的多线程体系结构,计算机图形学,编程语言设计领域。
导言: 异步时间扭曲(Asynchronous Timewarp简称ATW)是一种生成中间帧的技术,当游戏不能保持足够帧率的时候,ATW能产生中间帧,从而有效减少游戏画面的抖动,但是,ATW不是灵丹妙药,有一定局限性(局限性在后面介绍),开发人员也应该意识到。
简介: 近一年来,围绕着ATW这项技术已经有了许多令人兴奋的进展,ATW技术让虚拟现实设备保持较低帧率运行看到了希望,在虚拟现实穿戴设备中应用ATW,人为地填充中间帧,即使在帧率下降的情况下,也不会使渲染质量有显著的下降。
在Gear VR(三星的一款虚拟现实穿戴设备)中,ATW是其重要组成部分,并积累了宝贵的经验, 但是很不幸,经验表明,在PC机上ATW通过位置跟踪方法来解决虚拟现实系统抖动问题是有限的和有技术挑战的,就像Oculus Rift(虚拟现实眼镜)一样。在一些情况下,在虚拟现实中应用ATW后的效果和由跳帧引起的抖动效果一样糟糕。
在这篇博客中,我们分析了这些限制和导致特殊困难的原因,您将看到,ATW有时是有用的,但是还不能让虚拟现实引擎满帧运行,没有达到完美体验的程度。
时间扭曲(Timewarp),异步时间扭曲(Asynchronous Timewarp),和抖动(Judder)的概念:
时间扭曲是一种图像帧修正的技术,在使用虚拟现实眼睛设备时,由于头部运动过快,而造场景渲染的延迟,即头已经转过去了,但是图像还没有渲染出来,或者渲染的是上一帧的图像, 时间扭曲它通过扭曲一副被送往显示器之前图像,来解决这个延迟问题。 最基础的时间扭曲是基于方向的扭曲,这种只纠正了头部的转动变化姿势,这种扭曲对于2D图像是有优势的,它合并一副变形图像不需要花费太多系统资源。对于复杂的场景,它可以用较少的计算生成一个新的图像帧。
异步时间扭曲是指在一个线程(称为ATW线程)中进行处理,这个线程和渲染线程平行运行(异步),在每次同步之前,ATW线程根据渲染线程的最后一帧生成一个新的帧。
抖动和其具体细节在迈克尔·亚伯拉什的一篇文章中有详细介绍(参见我翻译的Ramblings in Value Time.)
在虚拟现实设备中,为了正确在虚拟世界里呈现一个人们的感知,必须要在显示器上的定时更新图像,然而,如果渲染时间太长,一帧就会丢失了,产生的结果就是抖动,这是由于新的一帧图像还没有被渲染出来,显示器显示了上一帧的图像,如果一帧图像被两次渲染就会产生下面结果,如图:
这里,眼睛转向左侧,这时图像又被渲染一次,图像落在视网膜的不同部分,导致双影抖动。
当然,双影并不是唯一的结果,如果同样的帧显示三次,就会产生三重影,以此类推。
基于方向的时间扭曲可以解决上午位置重影抖动问题,如果游戏渲染帧没有和头部运动达成同步, 时间扭曲可以介入并产生一个图像替代还没有被渲染出来的帧。 自从最后一帧被渲染,通过扭曲最后一帧来反馈头部运动, 所以相比原始的帧加入ATW显示会减少抖动,如果不加ATW不知道会发生什么事情。
在某些情况下,简单的渲染扭曲处理可以工作的很好,这种技术已经在Gear VR 中实现了,当游戏不能满足帧率的时候ATW就会自动填充帧,这使得帧很平滑,但有许多细不太明显的小瑕疵,因为 GearVR 缺乏位置跟踪,并且避开了近场对象。下面将讨论的许多瑕疵应该怎样减少或避免。
这也就是说,为什么说相比ATW在Gear VR而言,ATW在PC是更有意义和更有挑战性的,让我从Oculus Rift’s 所支持的位置跟踪开始探讨。
位置抖动(Positional Judder):
位置抖动是最明显的用基于方向的时间扭曲带来瑕疵之一,在使用虚拟现实设备时,当头部移动了, 如果在ATW产生图像帧时只考虑了旋转分量,那么任何头部平移分量都将被忽略了。这就意味着当你的头部从一边移动到另一边时,甚至是旋转你的头并且你的转动眼睛,你讲看见离你很近的物体会有多个图像的抖动,这种效果是非常明显的,在临近场空间中,比如下面的这个潜艇截图。
近场对象多重抖动的图像示例。
那么,这种影响有多严重?
这个颤抖的程度取决于玩家的运动方式,如果你保持你的头部相对静止并且只看风景,这种颤动将并不显著,可以忽略不计。
注意:上述现象在Gear VR 中是非常常见的, 它没有包含位置跟踪, 然而,头部模型产生虚拟的旋转,所以当用Gear VR 在半速率玩游戏的时候, 你仍然可以观察到近场物体的抖动。
如果看远处物体, 头部运动不太可能引起明显抖动。 在这种情况下。ATW可以使你自由的看中远处场景,并且没有明显的抖动。
换句话说, 如果你离场景非常的近,当你头部移动的时候,位置抖动将会相当明显,就像没有ATW一样,这种抖动也会出现在当你近距离看带纹理的地面的时候,这个场景离你非常近并没有产生中间帧, 由此产生的感觉是一个让人望而生畏,不稳定的世界, 让人非常迷茫和不舒服。
位置扭曲(Positional Timewarp):
解决位置颤抖的一个可能的方法是实现全位置扭曲,它应用平移和旋转两个分量来修正原始帧,位置扭曲,位置扭曲需要考虑原始帧的深度信息,由不同的量替代图像的一部分。 然而,这样产生的中间帧会使物体边缘不闭合,由于没有原始帧中的数据,会导致中间帧某些区域不能被覆盖。
此外,位置扭曲代价更高, 不容易处理半透明,处理反走样比较麻烦。位置扭曲并不能解决下面要讨论的情形。
运动的物体和动画:
使用ATW时,动画或者移动的物体引起另外一个瑕疵, 因为一个新的图像是只是根据原始图像生成的,原始图像上并没有物体的运动信息, 对于所有ATW产生的中间帧都好像是被冻结了一样,这个伪影表现为这些移动的物体,即抖动的多幅图像。
场景中移动物体产生的抖动效果。
这个伪影的影响取决于场景中物体数量,投影面积,运动速度,如果数量或大小的物体很小或不快,多个图像可能不是特别明显,然而,当移动物体或动画覆盖屏幕很大一部分,那将令人不安的。
此外,帧率比,即游戏帧率和显示设备刷新率的比值会对运动的抖动效果造成影响,根据我们的经验,ATW应该允许在一个固定的帧率区间内,例如,对于90赫兹的刷新率,我们应该在45赫兹区间使用ATW, 这将导致图像增加一倍,但在视网膜的双图像的相对位置将保持稳定,渲染在一个中间帧率,比如65赫兹,这将导致在视网膜上的图像数目和位置不断变化,这是一个糟糕的中间帧。
镜面反射:
计算镜面反射需考虑眼睛的方向, 或摄像机的方向, 由此生成一个图片。
由于眼睛或头部运动,镜面反射不再是正确的,这可能导致镜面反射抖动。
像镜面高光和反射依赖于眼睛位置一样,还有许多其他依赖于眼睛位置的着色技巧也有类似的问题, 例如,视差贴图和浮雕纹理映射将有类似的效果。
实现:
实现ATW是有挑战性的,主要有两个原因:
1: 它需要GPU硬件支持合理的抢占粒度。
2: 它要求操作系统和驱动程序支持使GPU抢占。
让我们从抢占粒度开始,在90赫兹,帧之间的间隔大约是11ms(1/90),这意味着为了使ATW有机生成一帧,它必须能够抢占渲染线程并且运行时间少于11ms,然而11ms实际上不够好,如果ATW在一帧时间区间内任意随机点开始运行,那么起潜伏期(执行和帧扫描之间的时间)也将随机, 我们需要确保我们不跳跃任何游戏渲染的帧。
我们真的期望ATW运行一直非常的短,短到在视频卡产生新的一帧之前结束,刚好有足够的时间来完成中间帧的生成,缺少自定义的同步ATW中断例程,我们可以获得高优先级抢占粒度和调度, 在最长2ms或更少的时间内。
原来,对现在的图形卡和驱动实现来说,2ms抢占是一个艰巨的任务,虽然许多GPU支持有限的形式的抢占,但执行存在显著差异。
1: 一些显卡实现厂商和驱动程序允许抢占任一批处理或回执调用粒度,虽然有帮助,但不是十分完美(举一个极端的例子,一个复杂的并包含很多绘制指令着色器可以很容易在10ms完成)。
2: 其他显卡实现厂商和驱动程序允许抢占计算着色器, 但需要特定扩展来支持。
如果抢占操作不是很快,则ATW将无法抢在画面同步之前生成中间帧。 这样,最后一帧将会再显示,将导致抖动,这意味着一个正确的实现应该能够抢占和恢复任意渲染操作,和管线状态。 理论上讲,甚至三角抢占(triangle-granularity) 不够好,因为我们不知道一个复杂着色器执行将花多长时间。 我们正与GPU制造商来实现更好的抢占,但是在这之前确实要因为这个问题花费一定时间。
另外一方面是操作系统对抢占的支持,在Windows8之前,Windiows显示驱动模型(WDDM)支持使用“批处理队列”粒度的有限抢占,对于内奸的图形驱动程序,很不幸,图形驱动程序趋向于大批量渲染效率, 导致支持ATW太粗糙。
对于Windows8,改善了WDDM1.2支持更细的抢占粒度,然而,这些抢占模式不被图形驱动程序普遍支持,渲染管线将在Windows 10 或 DirectX12中得到显著提升。 这为开发人员提供了较低级别的渲染控制,这是一个好消息, 但直到Windows10变为主流之前,我们还是没有标准的方式来支持渲染抢占, 造成的结果是,ATW需要特定显卡驱动的扩展。