如何有效提高Unity Gear VR游戏性能

http://www.vr186.com/vr_news/vr_technical_area/1093.html
html

好的,因此你决定用 Unity 来作一个 VR 游戏,并选定了三星 Gear vr 为你的目标平台。作好以后,打开应用,在设备上执行文件再容易不过 – 但有个问题,帧率实在过低。视野边上有闪烁的黑边出现,感受好像有谁往摄像机操做员的肚子上踢了几脚。你据说过保持稳定的帧率有多重要,如今你明白为何了 – 在虚拟现实中,任何低于每秒60帧的东西不只看起来很差,让人难受才是最糟糕的。你的高端上档台式机能把这个游戏运行到每秒1000帧,但机箱发出的声音像飞机引擎同样,并且……风扇发动时机箱好像真的升起来一点了!如今你要作的就是把你的大做针对移动芯片好好地优化一下。这个系列的文章针对的就是这个问题。缓存

第一部分: 运行环境以及高效率VR应用的一些特征

这并非关于 Gear vr 的一个优化大全,更像是一个快速入门吧。在这第一贴中咱们将先讨论下 Gear vr的硬件以及设计良好的移动 VR 应用的一些特色。以后将会着重讲述如何针对你的应用来提高表现。这篇文章主要针对 Unity,由于这是目前 Gear VR 开发中的主流引擎。可是,这些概念对于其它引擎来讲也是能够适用的。多线程

了解你的硬件

在把你的项目大卸八块寻找其低效之处以前,最好先花点时间思考下当下移动手机的一些表现特征。总的来讲,移动图形管线基于一个很快的 CPU ,经过一个很慢的总线和/或内容控制器来和一个很快的 GPU 链接,还须要一个形成不少开销的 OpenGL ES 驱动。Gear VR 在三星 Note4 和 S6 上运行。这两个产品线表明了几种不一样的硬件规格:并发

  • Note 4 的核心有两种。在北美和欧洲售卖的版本基于高通的骁龙芯片(SnapDragon 805),而在韩国和亚洲一些其它地区的基本都是三星本身的猎户座芯片(Exynos 5433)。骁龙芯片是四核 CPU 规格,而猎户座有八核,这两个核心分别对应两种 GPU: Adreno 420 以及 Mali-T760。
  • Note 4 又被最近的谷歌分红两种系统。分别是安卓 4.4.4 (KitKat) 和 Android 5 (Lollipop)。目前基本上世界上的猎户座的 Note4 都运行安卓5.0了(看来我给世界拖后腿了)。
  • S6 则都只有一种核心:Exynos 7420 (图形芯片是 Mali-T760M8)。还有另外一个版本的 S6,S6Edge,但它们除了外形不同之外里面都是同样的。
  • 全部的 S6 都是安卓5.0棒棒糖系统。

看起来好复杂是吧!没事,它们全部的性能和表现其实都很接近(除了一种情况,最下面的注意事项里会说),若是你能在某个设备上跑得不错,在其它上面应该也不会有生命问题。异步

和多数移动芯片同样,它们的 3D 图形表现方面的属性都比较稳定可靠。所以,这里有一些广泛的可能让你的项目跑得很差的缘由(按严重顺序排列):编辑器

  • 场景须要独立的渲染器(好比阴影和反射)(CPU/GPU开销)
  • 绑定 VBO 来进行绘制调用(CPU/驱动开销)
  • 透明,多通道渲染,每像素照明以及其它的像素效果(GPU/IO 开销)
  • 大型纹理加载,blits,以及各类类型的内存开销(IO/内存控制开销)
  • 蒙皮动画(CPU开销)
  • Unity 垃圾回收开销(CPU开销)

另外一方面来讲,这些设备有着比较大的内存,能够描画比较多的多边形。Note4 和 S6 都有着 2560×1440 的分辨率,但默认状况下咱们通常只渲染 1024×1024 的纹理分辨率来节约填充率。ide

了解你的VR环境

VR 渲染让硬件的表现受到最严苛的考验,由于每一帧都必须给双眼绘制共两次。在 Unity 4.6.4p3 和 5.0.1p1 里,意味着每一个绘制调用都被执行了两次,每一个网格被绘制了两次,每一个纹理被装订了两次。此外还有少许的开销被分配给了最终的畸变和时间穿越(2ms的预算)上。虽然咱们期待将来硬件的表现以及程序的流程会愈来愈好,但目前就是得每帧画两次。这意味着相较于普通的游戏,VR 游戏的开销要多几乎一倍。函数

而基于这些特性,如下是一些比较靠谱的 Gear VR 应用渲染目标。性能

提高unity gear vr游戏性能2
这一帧大概有30000个多边形和40个绘制调用

  • 每帧 50 – 100 个绘制调用
  • 每帧 50k – 100k 个多边形
  • 纹理贴图越少越好(但每一个能够很大)
  • 脚本执行时间在 1 ~ 3 毫秒之内 (Unity Update())

注意这些不是硬性规范,只是咱们的经验之谈。测试

另外注意 Oculus Mobile SDK 还引进了一个给 CPU 和 GPU 节流降频的 API 来控制热量和电池消耗(查阅使用样例 OVRModeParams.cs)这些方式让你能够选择对于在某个场景下,控制 CPU 和 GPU 的开销。比方说,若是在绘制调用的提交上出了问题,你让 CPU 升频(同时让 GPU 降频)可能能提高总体的帧率。若是你忽视这些作法,你的应用可能会被迫运行在降频的环境下,所以你最好多花点时间在这上面。

最后,Gear VR 也拥有 Oculus 的异步时间穿越(Asynchronous TimeWarp)技术。TimeWarp 能在程序变慢时基于最近的头部姿态信息来获得接下来的帧画面。它经过头部信息来扭曲上一帧的画面,能帮助你即使在偶尔丢失几帧时也能有流畅的体验,但绝对不是一个让你把应用随意运行在60帧每秒如下的借口。若是你左右摇摆脑壳时能看到眼角黑色的色块,就说明你的游戏已经慢到 TimeWarp 没有足够的帧画面来填补这些黑色空白了。

为性能表现而设计

作出表现良好的应用就是为了表现良好而去设计,而这意味着围绕移动 GPU 的一些特性来设计你的美术资源。

准备事项

在开始以前,先确保你的 Unity 项目的设定都已经为最高表现设定好了。特别的,是肯定以下值的设定:

  • 静态批处理(Static batching)
  • 动态批处理(Dynamic batching)
  • GPU 蒙皮(GPU skinning)
  • 多线程渲染(Multithreaded Rendering)
  • 默认方向到地平左边(Default Orientation to Landscape Left)

批处理

如今咱们知道的是,通常来讲绘制调用数量是 Gear VR 应用中最占用资源的方面,那么优化的第一步就是在艺术层面上作出一些设计,让程序在最终实现时调用越少的绘制命令越好。一个绘制调用就是对 GPU 的一个命令,让它绘制一个网格或者网格的一部分。而这个命令最占用资源的部分实际上是网格的选择自己。每一次当程序决定绘制一个新网格时,网格在被提交给 GPU 以前必须先被驱动进行处理。着色器必须被弹回,可能会发生一些格式的转化等等;而这些过程在每次一个新的网格被选中后都会发生,并占用了最大的开销。

但这也一样意味着,每次一个网格(或者更具体一点,一个顶点缓冲区对象VBO)被选中后,只须要占用这一次开销,就能使用屡次。只要没有新的网格(或者纹理、着色器)被选中,当前状态会一直存在于驱动缓存中并能够进行反复使用。为了利用这个特性,咱们能够将多个网格整合进一个大的顶点阵列中,并经过 VBO 进行单独绘制。咱们付出一次选择的代价后,就能够从这个对象内包含的多个网格进行调用而不会提升系统开销。这个方式被称做为批处理(Batching),比起为每个不一样的网格建立 VBO 要快得多,也是针对绘制调用进行优化的基础。

单个 VBO 中的全部网格必须享有一样的材质,才能进行批处理的整合:一样的纹理、着色器以及着色器参数。为了更高效地在 Unity 中利用批处理,咱们还得更进一步:对象必须有一样的材质对象指针。为此,这里有一些参考规则:

提高unity gear vr游戏性能3
纹理集合/图谱

  • 纹理集合(Macrotexture / Texture Atlases):经过将尽量多的模型映射到少数几个大的纹理集合中来达到尽量少的纹理数量。
  • 静态旗帜(Static Flag): 将全部不会移动的对象在 Unity 的 Inspector 中标记为静态。
  • 材质访问:当心访问 Renderer.material。这个操做会复制材质并返回给你复件,致使对象被排除在批处理以外(由于材质指针变成独特的了)。请使用 Renderer.sharedMaterial。
  • 确保批处理是开启的:在玩家设定(看下面)中确保静态批处理和动态批处理都被开启了。

Unity 提供两种将网格批处理的方式:静态批处理和动态批处理。

静态批处理

一旦你把某个网格标记成静态,这意味着你告诉 Unity 这个对象永远不会移动、变形或者缩放等。Unity 会基于这一点来自动将全部享用一样材质的网格整合成一个大的。在某些状况下,这将是很好的优化;不只减小了绘制调用数量,Unity 也把变形操做变成了顶点的位置选择,这样在运行时就不须要变形了。在一个场景内,越多的部分能被标记成静态越好。要记得只有一样材质的才能被整合在一块儿哦!

但须要注意的是,静态批处理生成了新的一个大网格,有可能致使最终的应用容量变得很大。通常来讲对于 Gear VR 开发者问题不大,但若是你的应用里有不少不一样场景,每一个场景都有不少静态网格,那么最终占用可能就会比较大。因此另外一个选项就是在运行时使用StaticBatchingUtility.Combine来生成批处理网格,而不会让你的应用变得太大(但你得付出一个一次性的 CPU 大量开销以及必定的内存占用的代价)。

最终,当心你的 Unity 版本,确认是否支持静态批处理(看最后的注意事项)。

动态批处理

只要共享一样的材料,Unity 也能把那些并无标记为静态的网格进行批处理。只要你把动态批处理选项打开,剩下的基本就不太用管了。对每帧都进行批处理会对计算性能形成一些开销,但通常来讲对于总体性能表现老是会有提高。

批处理的其它问题

固然,还有其它一些状况也要当心。好比给物体绘制阴影啦,其它须要给物体转换状态的多通道着色器(Multi-pass shader)啦,都会让批处理出现问题。多通道着色会让网格被提交屡次,针对 Gear VR 时务必要当心处理。逐像素光照(Per-pixel lighting)也有着相似的效果:使用 Unity4 里默认的扩散着色器(Diffuse Shader),网格会在每次被光线接触时从新提交一次,很快会把你的绘制调用数和多边形数耗光。若是你须要逐像素光照,能够试着在质量设置窗口中的并发光照总数设置为一。最近的光线会被逐像素渲染,而周遭的光线会经过球面调和函数(Spherical Harmonics)来计算得出。更好的方式是放弃逐像素光照,采用光照探针。另外要注意的是批处理不支持蒙皮网格。透明对象必需要按某种顺序来进行绘制因此很难被进行恰当的批处理。

不过,你仍是能够在编辑器中测试、调校批处理的。不管是在 Unity Profiler (Unity Pro 才有) 仍是游戏窗口的统计栏中,都能显示当前有多少绘制调用被下达了,多少被经过批处理节省了。若是你围绕着很小数量的纹理来组织你的几何图形,那么确保不要实例化你的材质,并把静态物体都标记上静态的旗帜,这样整个场景通常来讲就比较节能环保绿色高效了。

透明,Alpha Test 以及重复绘制(Overdraw)

如上所说起,移动芯片通常都是“填充率瓶颈”,意味着像素填充多是一帧中占用开销最大的地方。减小填充开销的关键就在于尽可能让每个像素只被绘制一次。多通道着色器,逐像素光照效果(好比 Unity 的默认高光着色器)还有透明对象等都须要对像素进行屡次渲染。太多的话,就会影响总线。

做为最佳实践的标准之一,你能够在质量设置(Quality Settings)中试着限制像素光照数(Pixel Light Count)为一。若是超过了一,你也要确保本身知道是哪部分的问题以及其形成的开销。一样,尽可能让透明的物体小。这里的开销由碰到的像素决定,所以你接触到的像素越少,这帧渲染的速度就越快。当心那些透明的粒子效果,好比烟雾等,其涉及到的像素数量可能会超过你的预期。

此外还要注意你不该该在移动设备上去使用 alpha test 着色器,好比 Unity 的镂空着色器(Cutout Shader)。那些 Alpha Test 的操做(以及 clip(),或者片断着色器里的显式丢弃), 会强制目前多数移动 GPU 撤销那些硬件优化,让其运行变得极慢。在管线中丢弃片断也常常会致使各类丑陋的反锯齿,所以仍是请用不透明几何或者 Alpha to coverage 来作镂空。

性能节流

在你能可靠测试你的场景以前,你须要确保 CPU 和 GPU 的节流设置已经设定好了。由于 VR 游戏已经把手机的性能压榨到了极致,所以你须要好好掌握 CPU 和 GPU 之间的平衡。若是你的游戏瓶颈在 CPU,那么你能够为 GPU 降频来让 CPU 全速运转。若是你的应用瓶颈在于 GPU 那你就反过来。若是你的应用效率很是高,那么你能够把 CPU 和 GPU 都降频来下降耗电和温度。能够在 CPU 和 GPU 移动 SDK 文档讲述电源管理的章节“Power Management” 来查看更多关于 CPU 和 GPU 的节流设置方面的信息。

比较重要的一个地方是在作这类性能测试前必须先选定一个 CPU 和 GPU 的节流配置。若是这些具体的数值没有被成功初始化,你的应用会被默认运行在降频的环境下。因为多数 Gear VR 的应用都会被 CPU 那边的驱动开销(好比绘制调用提交数目)所限制,所以通常来讲对于频率的设定会更有利 CPU 一些。你能够在 OVRModeParams.cs 中找到一个关于如何初始化节流目标的例子,也能够直接复制粘贴到一个在游戏开始时执行的脚本里来检验效果。

注意事项

这几天是你在考量本身应用性能表现时应当注意的:

  • 运行在 Lolipop 下骁龙805核心的 Note4 比起其它全部版本的 Note4 都要慢;貌似图形驱动关于提交绘制调用这一块有了退步。若是某些游戏在绘制调用这一块已经到底了那么有可能会发现新的瓶颈(最多可能达增长20%的响应时间),足够让常规的管线停顿并致使帧率降低。咱们正努力和三星以及高通共通解决这个问题。运行安卓 4.4 的骁龙805 Note4 以及猎户座 Note4 和 S6 设备皆不受此影响。
  • 尽管为 CPU 和 GPU 进行降频节流能极大下降手机的热量,那些开销大的应用在长时间的使用过程当中依然可能让手机过热。在这种状况发生时,手机会发出警告,而后动态下降处理器的频率,通常都会致使应用帧率低到不可用的地步。若是你在作性能测试时碰到了这种状况,请关闭应用并让手机休息个至少五分钟再继续测试。
  • Unity 4 免费版不支持静态批处理以及 Unity Profiler。可是 Unity 5 我的版支持这些。
  • S6 不支持各向异性纹理过滤 。

目前基本就这么多了。在下一贴,咱们将讨论如何针对真实世界各类性能表现下降的问题来排错。

如若需了解更多关于在 Unity 移动 VR 应用开发方面的优化问题,请在咱们的 Unity Integration guide里查看“最佳实践指南:移动端”这一节。

Via:Oculus 翻译来源:VRerse元代码

相关文章
相关标签/搜索