概述

      基于PC的VR体验无疑面临着来自性能需求方面的挑战。鉴于标准PC游戏的性能目标被普遍认为应在1920*1080分辨率达到60帧速率,当前VR头显显示屏分辨率基本为双眼2160*1200,刷新率为90Hz。相较于1080p分辨率、60帧速率,这相当于降低约33%的帧时间填充原先125%的像素。此外,头显需要渲染器去产生比2160*1200更高分辨率的图像,以便用户看到的最终像素密度在图像被头显的光学畸变扭曲矫正后依然充足。图像扭曲矫正是头显光学畸变执行的后期处理,这一操作会花费一定的时间,因为它会消耗你的90HZ帧预算。因此,实际上,VR游戏需要在小于11毫秒时间内填充超过2160*1200个像素,才能够稳定在90HZ刷新率。
       相比普通的PC渲染,VR渲染对性能要求更高,应用性能不佳造成的后果也更加严重。在一个典型的PC游戏中,帧时间预算超标会导致屏幕撕裂和引起明显滞后,而在VR中,会严重到导致用户疲劳且晕头转向。这是由于,不达标的表现性能造成的低劣或不稳定的VR体验会对用户的感官造成不利影响,正如Oculus指出:“不管你的内容有多么吸引人,或是用户多么渴望去体验它,一旦模拟晕动症出现,人们都会想要立即停止体验。”
       VR体验经常会遭遇画面抖动,这是拖尾和频闪效应导致的画面细节丢失,可引起用户视觉疲劳,这也是模拟晕动症的症状之一。因此减少画面抖动对保持画面质量和用户舒适度来说是非常重要的。拥有90HZ刷新率显示屏的头显就比75HZ或60HZ的头显画面显示抖动现象少得多,但前提是运行的VR应用刷新率持续稳定在90HZ。如果一个头显配备90HZ刷新率的显示屏,但画面不能够被及时渲染,那么画面质量和用户体验舒适度将大打折扣。
       困扰VR体验的另一个潜在问题是延迟,从用户运动开始到相应画面显示到屏幕上所花的时间,或用户头部移动和显示屏画面刷新之间的延迟。过度的、无规律的延迟会使一些用户失去方向感并产生虚拟运动症。因此与现在用户大多数常用的75HZ或者60HZ刷新率设备相比,90hz刷新率的VR头显设备在降低延迟方面显得非常重要,当然前提条件是VR应用本身也满足帧率要求。稳定性很重要,一旦由于一个体验特殊场景或是耗时特效突然呈现,延迟跟随用户头部突然转动急剧增加,会导致非常不适的晕眩感产生。 
      头显运行时采用预测和其它先进技术来减少画面抖动和延迟。然而, 不稳定性能等造成的延迟突变会导致预测误差,或是延迟减小功能的不稳定。异步时间扭曲技术(ATW)只能矫正转动头部引起的画面抖动。帧速率不够的应用程序还会存在位移造成的抖动和物体动画误差。因此,Oculus等头显供应商仍然强烈建议应用程序提供稳定的90fps的性能:“最好、最具沉浸感和舒适度的体验会持续在90fps运行,开发人员应该以这一帧速率为目标。” 
      最近,Oculus引入了异步空间扭曲技术(ASW),试图解决帧率跌至90fps以下时出现的位移抖动和动画误差问题。然而,这可能会产生一些渲染误差,因为ASW必须推测缺失的数据并创建画面。ASW旨在为低于推荐参数配置的硬件提供优质的体验效果。“开发者需要在推荐参数系统上维持90fps的渲染。”
       该指南旨在帮助开发者明白,如何让使用UE4开发的VR应用在AMDGCN架构显卡PC上运行时始终维持在90fps性能。

基础知识
      与前文所述一致,Epic Games的Luis Cataldi也曾做出精辟总结,“在VR中,你必须保持稳定的帧速率。”这意味着在11毫秒内稳定的渲染超过2160*1200的像素。许多UE4特性是为1080p的60帧速率游戏设计的,并不需要过多的去渲染像素,并且有充足的像素周期供你支配。一些特性也许对90HZ的VR并不适用。相比于传统游戏,达到VR的性能指标是有难度的,会产生不同程度的难点和痛点。设计游戏和创建内容时需要牢记这些点,尽早的、频繁的测试你的内容表现性能,避免问题发现的太晚,返工以致开发周期延长。

通过ini设置文件和工程设置禁用一些耗时的渲染特性
      VR的高性能需求意味着一些特性需要被禁用。你可以在UE4编辑器中通过工程设置来禁用一些耗时的渲染特性。从主菜单进入项目设置,选择编辑→项目设置→渲染。或者通过工具栏面板,选择设置→项目设置→渲染(这份文件里的指导和说明针对虚幻引擎4.14版本,其他版本设置过程可能会有些许不同)。
 
总的来说,在配置你的项目渲染设置时,可采用Leszek Godlewski总结的以下原则:
 
1.    如果一个特性对你做的游戏来说不是必须,禁用它。
2.    否则,如果你愿意接受质量折损,可以选择把相关参数降低。
 
该部分将针对基于UE4开发的VR应用的项目设置部分给出具体建议。 
禁用分离半透明
      Epic自家创作的VR项目比如ShowdownVR demo以及其VR模板禁用了分离半透明特性以提升性能。在渲染设置的半透明选项里通过清除复选框(如下图所示)以禁用分离半透明。

基于UE4的VR内容在AMD GCN架构上的性能优化指南

或者,在你的[ProjectDirectory]/Config/DefaultEngine.ini设置文件的
[/Script/Engine.RendererSettings]代码块添加以下代码。
r.SeparateTranslucency=False

禁用耗时的后期处理
      在渲染设置的默认设置部分,视觉质量尚可维持的情况下,尽可能多的禁用相对耗时的后期处理技术。
基于UE4的VR内容在AMD GCN架构上的性能优化指南

      Epic自家创作的VR项目比如ShowdownVR demo及其VR模板禁用了屏幕空间环境光遮蔽(SSAO),自动曝光处理(上面截图里的Auto Exposure),动态模糊和透镜光晕。
 
如上图所示,禁用环境光遮蔽,自动曝光,动态模糊和透镜光晕,你的
[ProjectDirectory]/Config/DefaultEngine.ini设置文件中的[/Script/Engine.RendererSettings]代码块应该修改为以下:

r.DefaultFeature.AmbientOcclusion=False
r.DefaultFeature.AmbientOcclusionStaticFraction=False
r.DefaultFeature.AutoExposure=False
r.DefaultFeature.AutoExposure.Method=1
r.DefaultFeature.MotionBlur=False
r.DefaultFeature.LensFlare=False 
亦或是,你可以通过修改[ProjectDirectory]/Config/DefaultScalability.ini文件自定义扩展设置来禁用这些特性。
基于UE4的VR内容在AMD GCN架构上的性能优化指南

       光晕特效方面,Showdown及UE4的VR模板启用了高光特性,但将质量设定减少为1,并全程强制启用了优化的模糊算法。在你的[ProjectDirectory]/Config/DefaultScalability.ini文件的4个PostProcessQuality代码块(如上)添加以下代码:
r.BloomQuality=1
r.FastBlurThreshold=0
 
自定义扩展设置者可参考虚幻引擎扩展参考(Scalability Reference)获取更多信息。                                                                  
优化半透明物体的光照设置
      Showdown 及UE4的VR模板修改了半透明物体的一些默认光照设置以提升性能。可通过修改项目中的[ProjectDirectory]/Config/DefaultScalability.ini文件自定义扩展设置以禁用半透明体积模糊,减小光照体积的大小。

[EffectsQuality@0]
r.TranslucencyVolumeBlur=0
r.TranslucencyLightingVolumeDim=4
[EffectsQuality@1]
r.TranslucencyVolumeBlur=0
r.TranslucencyLightingVolumeDim=4
[EffectsQuality@2]
r.TranslucencyVolumeBlur=0
r.TranslucencyLightingVolumeDim=4
[EffectsQuality@3]
r.TranslucencyVolumeBlur=0
r.TranslucencyLightingVolumeDim=4

禁用屏幕空间反射(SSR) 
      屏幕空间反射也算一个耗时的特性,并且在VR中可能遭遇一系列问题,特别是当反射画面与用户在真实世界中的经验不一致的时候。Epic建议使用反射探针来替代该特性,“更加cheap,遇到的问题也会少一点。”UE4的VR模板禁用了SSR。可将以下代码行添加到上文所述4个EffectsQuality代码块里以禁用SSR。
r.SSR.Quality=0
考虑禁用其他feature
      一些潜在耗时的特性也可以被禁用。整体原则就是,如果禁用一个特性对你的项目没有影响,那就禁用它,如果禁用了一个特性后你的项目无法继续,那就考虑看看降低相关质量参数设定。如Showdown及UE4 VR模板就禁用了镜头色散和景深。如果你也想这样,可将以下代码添加至你的[ProjectDirectory]/Config/DefaultScalability.ini文件的4个PostProcessQuality 代码块。
r.SceneColorFringeQuality=0
r.DepthOfFieldQuality=0

使用VR模板开始你的性能配置
      想要在上述性能设置基础上获取先行一步的优势,你可以使用VR模板创建一个新的项目,然后从模板项目的Config目录中将DefaultScalability.ini文件拷贝至你自己的项目中,同样地,你可以从模板项目的DefaultEngine.ini引擎中将[/Script/Engine.RendererSettings]代码块内容拷贝至你自己的项目中。可以如下图所示,在编辑器的新建项目对话框中创建模板。

基于UE4的VR内容在AMD GCN架构上的性能优化指南

通过ini设置文件和工程设置开启一些渲染特性

      除了禁用或是降低一些性能设置参数,你也应该适时地开启特定的可增强性能的特性。
开启实例化立体渲染(ISR)
      最近几个版本的UE4都有优化后的实例化立体渲染特性,这可以提高多数VR应用的CPU和GPU表现性能。在渲染设置的VR板块中(主菜单中选择编辑→项目设置→渲染,或是工具栏中选择设置→项目设置→渲染),如下图所示开启ISR。

基于UE4的VR内容在AMD GCN架构上的性能优化指南

      你需要重启编辑器这一设置才会生效,shader也会再次编译。如果你从VR模板中拷贝了一些设定,ISR应该已经被启用(但仍需再次确认)。ISR可以使用一个Drawcall命令去同时渲染双眼的物体。Drawcall的减少可以降低引擎、显卡驱动和CPU的开销。ISR还会减少显卡状态的变化次数,使得GPU执行更加高效。硬件实例化同时对于顶点缓存也是友好的,能够减小顶点缓存的大小。因此,当你的场景足够复杂以至于非ISR渲染成为瓶颈时,ISR有望可提升CPU和GPU的表现性能。但是请注意,ISR利用的是硬件实例化,该特性与场景网格实例化不兼容(如树叶网格的实例化)。如果你在场景中大量使用了网格实例化,ISR即便启用也不会对提升表现性能有多大帮助。
如果为OculusRift开发内容,考虑开启自适应像素密度
      从4.13版本开始,UE4开始支持OculusRift的自适应像素密度功能。该特性可监控GPU表现性能,并可在帧速率极限、GPU利用超过安全值时按比例减小渲染目标的分辨率。这可以帮助维持更加稳定的帧速率。按比例减少了像素数量,从而减少了这些帧的性能消耗,避免丢帧。启用该特性,可将下面代码添加至你的[ProjectDirectory]/Config/DefaultEngine.ini文件[Oculus.Settings]代码块中(没有[Oculus.Settings]代码块的情况下需要新建)。
PixelDensityMin=0.5
bPixelDensityAdaptive=true
       PixelDensityMin决定了最多可以按比例降低多少渲染目标分辨率。默认值是0.5,意味着分辨率在每个方向可以降低一半。实验证明这样可以在用户不易察觉的情况下维持稳定的分辨率。 
仔细确认已禁用不必要的耗时特性

      该部分讨论的特性在最近几个版本的UE4里已经被默认禁用,但请再次确认,因为不经意启用这些特性会明显降低表现性能。 
确保禁用HZB遮挡剔除
      不要使用分层z-buffer(HZB)系统进行场景能见度测试(如遮挡剔除)。相反,启用默认的遮挡剔除排序系统。对典型的VR应用来说,创建HZB会造成不必要的GPU花销。(注意屏幕空间环境光遮蔽(SSAO)和屏幕空间反射(SSR)同样会创建HZB,即使HZB遮挡剔除系统被禁用。这也是在VR应用中禁用SSAO和SSR的另一个原因。)HZB也应该已经被默认关闭,但如果你想要确保禁用,添加以下代码行到你的[ProjectDirectory]/Config/DefaultEngine.ini文件的[/Script/Engine.RendererSettings]代码块。
r.HZBOcclusion=0
确保禁用legacy FinishCurrentFrame 特性(强制完成当前帧)
      你必须确保r.FinishCurrentFrame参数被设置为0。这是改善延迟的一个过时的特性,但不再对当前HMD运行有助,并且明显的损害应用的性能表现。你必须禁用该特性。这非常重要。它将损耗你的90HZ帧率预算的25%甚至更多,并且没有丝毫效果上的益处。(最近几个版本的UE4对Oculus Rift强制关闭了r.FinishCurrentFrame特性。然而,针对其他头显并没有强制关闭,你需要确保禁用该特性,因为它引起的后果实在是有些可怕。) r.FinishCurrentFrame应该已经被默认关闭,但为了更加保险,添加以下代码行至你的[ProjectDirectory]/Config/DefaultEngine.ini文件的[/Script/Engine.RendererSettings]代码块。
r.FinishCurrentFrame=0
       请注意,Showdown自2014年被开发至今并没有禁用r.FinishCurrentFrame。如果你使用Showdown工程开启你的VR项目,请确保禁用r.FinishCurrentFrame。

其他性能建议

保持版本更新
      在开发周期里请尽可能保持你的UE4版本更新。许多优秀作品都与VR引擎息息相关。例如,4.13版本就增加了对胶囊体阴影的VR支持,优化后的ISR,全新VR模板,以及OculusRift的自适应像素密度。4.14版本引进了全新针对VR的前向渲染并且支持MSAA。保持更新最新版本的UE4以确保你可以使用最新优化和改进特性。
控制drawcall和多边形数量
      将你的渲染负载保持在一个合理的水平以稳定达到90fps是非常重要的。LOD的适当和广泛使用也很必要。UE4的最近几个版本支持分层级的LOD。此外,UE4的合并工具可将数个静态网格结合为一个单一的draw call。使用stat SceneRendering在你的项目中留意draw call表现性能。

寻找其他可行性替代耗时的动态阴影 
      传统游戏中的许多动态阴影技术对VR来说都太耗时了。要为自己的项目找到可替代的选择并实验这些选择的可行性。Showdown为角色使用了单一的圆点阴影。最近几个版本的引擎支持在VR中使用胶囊体阴影。你可以选择在动态物体中使用“SingleSample Shadow fromStationary Light”选项。
避免使用tessellation 
      传统的法线贴图在VR中可能看起来很没有立体感。你可能会被建议使用tessellation作为法线贴图的替代选择。然而,tessellation会明显损害性能。因此,应该为法线贴图探索更多的替代选择,如视差贴图。
优化反射 
      尽管你已经通过禁用SSR开始优化反射,其余的可由你支配的反射特性必须被小心使用以维持表现性能。如前文所述,环境反射特性(如反射探针)需要替代SSR启用。在为当前帧渲染环境反射时,如果所有的反射捕捉形状是一个单一的类型(如都是球面反射或者立方体烦色和),GPU将会执行一个优化后的Shader。始终使用一个单一的捕捉形状将确保该优化手段奏效。UE4的最近几个版本支持VR中的平面反射。想达到理想的表现性能,你还需要使用ShowOnlyActors数组去有选择性的渲染尽可能少的物体的反射。剩下的就交给相对便宜的反射环境系统吧。

调节屏幕占比 
      头显厂商都希望渲染出来的图片比显示屏上呈现出来的画面拥有更高分辨率,这样像素密度在图像扭曲后依然会充足。分辨率由r.ScreenPercentage(在UE4的最近几个版本里,为Oculus Rift开发内容时,你不一定非要调节屏幕占比,因为在Oculus运行时,引擎会获取渲染对象的默认分辨率。其他头显还是需要依赖r.ScreenPercentage。当然你也可以通过其更改Rift的默认值)控制。初值通常为r.ScreenPercentage=130。你或许想更改这一值,使其大于100,又尽可能低,还不能太低(避免使用户看到显示屏上呈现的画面太模糊)。找到一个平衡点,在画质仍可被接受的条件下调至最低值,这意味着你已经将渲染像素的数量最小化。一旦你选定了一个值,你可以将其添加至DefaultEngine.ini文件的渲染器设置,使其成为一个项目设置。
 前向渲染

      如前文所述,4.14版本通过支持MSAA为VR引进了全新的前向渲染器。一些开发者和用户认为在VR中观看时,时域抗锯齿会看起来太模糊。然而,与时域抗锯齿相比,MSAA(多重采样抗锯齿)对UE4的延迟渲染管线来说是一个不可行的选择,因为MSAA会造成延迟渲染的GBuffer带宽剧烈增加。前向渲染更加自然的支持MSAA并且允许更加清晰的图像被传递至头显。如果你更改了屏幕占比,你会发现你可以通过MSAA使用一个低的(快的)屏幕占比,获得与时域抗锯齿的更大屏幕占比等同质量的最终输出图像。
       至于表现性能,Epic报告指出前向渲染相比延迟渲染有22%的性能提升。AMD自己的评测显示在GCN架构硬件获取了高达27%的性能。请注意,前向和延迟渲染之间的后期图像处理过程并没有改变,这也意味着单纯的帧渲染时间减少会比27%更多,当在测试前向渲染和延迟渲染每个渲染环节的具体差异时(如prepass, basepass,阴影和照明,半透明,雾),AMD观察到UE4前向渲染的表现性能优于延迟渲染。
       一些性能的提升是由于前向渲染允许了一些延迟渲染难以支持的优化。尤其是,“除非材质选择了参加高质量反射的选项,只有最近的反射捕获可以在没有矫正视差的情况下被应用,雾效果可以按照每顶点计算,平面反射只能被应用在启用该特性的材质中。”然而,前向路径被期望在AMD GCN 硬件架构上更快,并且高于额外per-material优化。因此我们强烈建议UE4开发者使用4.14或以上版本并在你们的VR项目中使用前向渲染器。
       在渲染设置的前向渲染中启用前向渲染器(主菜单中选择编辑→项目设置→渲染,或从工具栏选择设置→项目设置→渲染)。你也许还想设置顶点雾(Vertex Fogging)为不透明,这应该被默认设置为开启。
基于UE4的VR内容在AMD GCN架构上的性能优化指南       请注意UE4延迟路径中一些可用的特性在前向渲染开启后并不适用。举个例子,依赖延迟g-buffer的屏幕空间技术不被支持,如SSR(屏幕空间反射)和SSAO(屏幕空间环境光遮蔽)。但请记得由于VR中性能消耗的原因,被推荐的最优方法本就要求禁用这些特性。多数在前向渲染器中不被支持的特性都归咎于此(如某一特性太耗时以至于无论怎样都要被禁用)。未来更多这样的渲染特性将会被支持。4.14发布需知有对支持特性的详述,如果你在阅读本文时已经有了高于4.14的版本,请确保仔细阅读最新版本的发布需知。
       前向渲染路径同时支持TAA和MSAA。如果你想使用MSAA,由于MSAA对于多边形边缘有较好的抗锯齿效果而对于高光闪烁锯齿则效果不佳,因此请注意美术素材也需要相应的被重新考率制作。可以参考4.14版本的Releasenote获得减少高光闪烁锯齿的技巧。注意,由于MSAA对多边形边缘锯齿的作用,因此LOD应该被更多的使用,正如之前的章节建议的一样。模型网格中的小三角形在MSAA开启时对GPU性能有着更加坏的影响,同时也会造成更加多的锯齿,影响画面质量。