基于UE4的VR内容在AMD GCN架构上的性能优化指南
概述
基于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中,这会严重导致用户疲劳和晕头转向。正如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应用在AMD GCN架构显卡PC上运行时始终维持90fps性能。
基础知识
Epic Games的Luis Cataldi曾精辟总结:“在VR中,你必须保持稳定的帧速率。”这意味着要在11毫秒内稳定渲染超过2160×1200的像素。许多UE4特性是为1080p的60帧速率游戏设计的,不需要过多渲染像素,且有充足的像素周期可供支配。一些特性可能并不适用于90Hz的VR。与传统游戏相比,达到VR的性能指标存在难度,会产生不同程度的难点和痛点。在设计游戏和创建内容时,需要牢记这些要点,尽早且频繁地测试内容表现性能,避免问题发现过晚,导致返工和开发周期延长。
通过ini设置文件和工程设置禁用一些耗时的渲染特性
VR的高性能需求意味着需要禁用一些特性。可以在UE4编辑器中通过工程设置来禁用一些耗时的渲染特性。从主菜单进入项目设置,选择“编辑→项目设置→渲染”;或者通过工具栏面板,选择“设置→项目设置→渲染”(本文件的指导和说明针对虚幻引擎4.14版本,其他版本设置过程可能会有细微不同)。
总体而言,在配置项目渲染设置时,可采用Leszek Godlewski总结的以下原则:
- 如果一个特性对游戏并非必需,禁用它。
- 否则,若愿意接受质量折损,可以选择降低相关参数。
禁用分离半透明
Epic自家创作的VR项目,如Showdown VR demo及其VR模板,禁用了分离半透明特性以提升性能。在渲染设置的半透明选项里,通过清除复选框来禁用分离半透明。也可以在[ProjectDirectory]/Config/DefaultEngine.ini设置文件的[/Script/Engine.RendererSettings]代码块添加以下代码:
r.SeparateTranslucency=False
禁用耗时的后期处理
在渲染设置的默认设置部分,在视觉质量尚可维持的情况下,应尽可能多地禁用相对耗时的后期处理技术。Epic自家创作的VR项目,如Showdown VR 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文件自定义扩展设置来禁用这些特性。
在光晕特效方面,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建议使用反射探针来替代该特性,称其“更加廉价,遇到的问题也会少一点”。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]代码块内容拷贝至自己的项目中。可以在编辑器的新建项目对话框中创建模板。
通过ini设置文件和工程设置开启一些渲染特性
除了禁用或降低一些性能设置参数,还应适时开启特定的可增强性能的特性。
开启实例化立体渲染(ISR)
最近几个版本的UE4都有优化后的实例化立体渲染特性,这可以提高多数VR应用的CPU和GPU表现性能。在渲染设置的VR板块中(主菜单中选择“编辑→项目设置→渲染”,或在工具栏中选择“设置→项目设置→渲染”)开启ISR。
开启该设置后需要重启编辑器,Shader也会再次编译。如果从VR模板中拷贝了一些设定,ISR应该已经被启用,但仍需再次确认。ISR可以使用一个Drawcall命令去同时渲染双眼的物体,减少Drawcall可以降低引擎、显卡驱动和CPU的开销。ISR还会减少显卡状态的变化次数,使GPU执行更加高效。硬件实例化对顶点缓存也友好,能够减小顶点缓存的大小。因此,当场景足够复杂,非ISR渲染成为瓶颈时,ISR有望提升CPU和GPU的表现性能。但需注意,ISR利用的是硬件实例化,该特性与场景网格实例化不兼容(如树叶网格的实例化)。如果在场景中大量使用了网格实例化,即便启用ISR,对提升表现性能也帮助不大。
如果为Oculus Rift开发内容,考虑开启自适应像素密度
从4.13版本开始,UE4开始支持Oculus Rift的自适应像素密度功能。该特性可监控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特性,但针对其他头显并没有强制关闭,需要确保禁用该特性。)可添加以下代码行至[ProjectDirectory]/Config/DefaultEngine.ini文件的[/Script/Engine.RendererSettings]代码块:
r.FinishCurrentFrame=0
需要注意的是,Showdown自2014年被开发至今并没有禁用r.FinishCurrentFrame。如果使用Showdown工程开启VR项目,请确保禁用该特性。
其他性能建议
保持版本更新
在开发周期里,应尽可能保持UE4版本更新。许多优秀作品都与VR引擎息息相关,例如,4.13版本增加了对胶囊体阴影的VR支持、优化后的ISR、全新VR模板,以及Oculus Rift的自适应像素密度;4.14版本引进了全新针对VR的前向渲染并且支持MSAA。保持更新最新版本的UE4,以确保可以使用最新优化和改进特性。
控制drawcall和多边形数量
将渲染负载保持在合理水平以稳定达到90fps非常重要。适当且广泛地使用LOD也很必要,UE4的最近几个版本支持分层级的LOD。此外,UE4的合并工具可将数个静态网格结合为一个单一的draw call。使用stat SceneRendering在项目中留意draw call表现性能。
寻找其他可行性替代耗时的动态阴影
传统游戏中的许多动态阴影技术对VR来说都太耗时。需要为项目找到可替代的选择并实验其可行性。Showdown为角色使用了单一的圆点阴影,最近几个版本的引擎支持在VR中使用胶囊体阴影,也可以选择在动态物体中使用“SingleSample Shadow from Stationary 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延迟路径中一些可用的特性在前向渲染开启后并不适用。例如,依赖延迟g-buffer的屏幕空间技术不被支持,如SSR(屏幕空间反射)和SSAO(屏幕空间环境光遮蔽),但由于VR中性能消耗的原因,这些特性本就被推荐禁用。多数在前向渲染器中不被支持的特性都源于此(如某一特性太耗时,无论怎样都要被禁用)。未来更多这样的渲染特性将会被支持,4.14发布需知有对支持特性的详述,如果已经有了高于4.14的版本,请确保仔细阅读最新版本的发布需知。
前向渲染路径同时支持TAA和MSAA。如果想使用MSAA,由于MSAA对于多边形边缘有较好的抗锯齿效果,而对于高光闪烁锯齿则效果不佳,因此需要重新考虑美术素材的制作。可以参考4.14版本的Releasenote获得减少高光闪烁锯齿的技巧。另外,由于MSAA对多边形边缘锯齿的作用,应该更多地使用LOD,正如之前的章节所建议的。模型网格中的小三角形在MSAA开启时对GPU性能有更坏的影响,同时也会造成更多的锯齿,影响画面质量。