UWA问答 | 博客 | 游戏及VR应用性能优化记录分享 | 侑虎科技 - VR
今年6月，小米VR一体机正式发布，国内小米商城开售仅4分钟全部备货就被抢购一空。用户市场的狂热让更多开发者加入到小米VR平台，UWA也在今年和小米VR携手，开始为众多小米VR开发者提供高效快捷的性能优化支持。 UWA性能诊断与分析报告对VR项目性能中的几个关键指标均做了详细的检测，总体包括CPU性能占用、GC调用、渲染模块、物理模块、动画模块、粒子系统、UI模块、加载模块等。其他还包括内存管理、资源管理、代码效率、GPU性能、重要参数解析、硬件参数解析、项目运行日志等详尽的分析模块。 总体性能趋势 内存管理模块 设备温度趋势图 每个模块所检测的问题，UWA基于对引擎的了解和多年的行业服务经验，对每一个性能模块的数据给出合理的评定，即可提供有针对性的解决方案。 内存趋势对照游戏场景查找问题 同时，UWA中一些高级检测功能如重要参数解析、代码效率等，筛选出了CPU占用最高，堆内存分配最大的函数等重要性能相关的信息，免去了逐帧检测的大量人力和时间成本，让开发事半功倍。 自动筛选重要性能相关信息 截至目前，UWA平台已经可以支持Oculus Rift、Google Cardboard、Gear VR、DPVR、HTC Vive、小米VR一体机等全球主流VR设备的内容性能检测与优化，希望能帮助广大VR开发者制作更多优秀的VR内容。 点击查看演示Demo
本期聚集话题：如何优化WaitForGPU、如何用DrawMeshInstanced给每个物体指定不同的颜色、Unity导入模型时选项Swap UVs的作用、角色换装模型合并问题... 这是第110篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题，建议阅读时间15分钟，认真读完必有收获。 UWA 问答社区：answer.uwa4d.com UWA QQ群：793972859（仅限技术交流） 渲染 Q：最近做一个VR的Demo，使用Unity 5.6.3版本开发，发现当近距离观察模型细节的时候突然就变得特别卡顿，帧率从95FPS降到了45FPS，如下图： 图示为正常距离观察模型没有问题，帧率正常。 图示为近处观察模型时，帧率下降严重，VR.WaitForGPU占比很高。 想请教大神，为什么近距离观察会导致VR.WaitForGPU这一项升高呢？ UWA：估计是ALU的问题使得GPU压力过大，其根本原因还是模型上Fragment Shader的指令集过高，从而导致渲染的Pixel数量越大，其GPU开销就越高，类似于我们在UWA Day 2018上关于Standard Shader的屏占实验。在低端设备上，屏占超过20%，其GPU耗时就已经超过20ms。 WaitForGPU过高，说明此时GPU是性能瓶颈。对此，建议题主检测下自己的情况是否如此。 该回答由UWA提供，欢迎大家转至社区进行进一步交流： https://answer.uwa4d.com/question/5ae9759532493548fbd32c2e 制作 Q：Unity官方的描述如下：Swap UV channels in your Meshes. Use this option if your diffuse Texture uses UVs from the lightmap. Unity supports up to eight UV channels but not all 3D modeling applications export more than two. 不过我不太理解该描述，我自己尝试时，无论是否使用了Lightmap，这个选项勾选或不勾感觉模型都没有什么变化。请问在什么情况下需要勾选呢？它交换UV通道的意义是什么？ UWA：之前的document里的描述： Swap UV：Use this if lightmapped objects pick up the wrong UV channels. This will swap your primary and secondary UV channels. 现在的描述里有：Use this option if your diffuse Texture uses UVs from the lightmap. 以及可以看一下这个帖子里关于这个选项的讨论：https://forum.unity.com/threads/poll-is-swap-uvs-mesh-import-setting-useful-for-anyone.173468 看起来像是Lightmapped模型出现贴图混乱的时候才用的，，例如从某些建模软件（例如blender）导入的带多个uv通道的模型。 该回答由UWA提供，欢迎大家转至社区进行进一步交流： https://answer.uwa4d.com/question/5ae9b63b6b104d27ac3aac4c 渲染 Q：用DrawMeshInstanced这个API来渲染多个物体的时候，应该怎么给每个物体指定不同的颜色？这个接口的参数里面有个MaterialPropertyBlock，但却不是数组，不能指定多个颜色。 UWA：如果不是通过这个接口，而是放置物体在场景里，那么确实可以给每个物体指定不同颜色属性的MaterialPropertyBlock来实现。 但如果用这个接口，那么只能指定一个MaterialPropertyBlock，所以可以尝试指定一个数组，比如SetFloatArray，然后在Shader里通过数组里的值来取（或者计算）各自对应的值，作为颜色。 该回答由UWA提供，欢迎大家转至社区进行进一步交流： https://answer.uwa4d.com/question/5af0191b0e95a527a7a81cd3 制作 Q：大家熟悉模型合并或角色换装吗？当使用两次合并后，第二次合并后的UV不对，有什么办法解决吗？ 比如，我们A（aMat），B(bMat)，C(cMat)，D(dMat)四个部件： 1)第一次使用CombineMesh(coms, true , false)合并 A、B、C网格(combineMesh1)并且整合材质 atlasMat。 2)第二次使用CombineMesh(coms , false , false)合并combineMesh1 ,D 网格（combineMesh2）并且移动材质到同一个Renderer。 最后ABCD被全部整合到combineMesh2，Renderer的材质变成2个（atlasMat + dMat)。我现在的问题是，dMat的UV显示不正常，请问会是什么问题呢？ 如果Mesh只有一个，多个Material会有问题。 另外，显示不正常是因为一套UV对应了两套贴图。 要么把D Mesh的UV改到UV1（UV2、UV3、UV4）上，但是需要改dMat的Shader，而且会增加DrawCall。 要么连同dMat的贴图一起合并到atlasMat上。 感谢凯奥斯@UWA问答社区提供了回答，欢迎大家转至社区进行进一步交流： https://answer.uwa4d.com/question/5ae2987a095683490075263c 粒子系统 Q：我用的是Unity 2017.1.3版本，特效人员在粒子系统上使用了trails模块，然后为了形成拖尾要使用world space，结果在游戏中发现整个粒子包围盒计算出了问题，导致剔除操作时出错。而且是离原点越远偏差越大，特效在原点就没偏差。请问有没有解决的方案？ UWA：我找了一个采用CullingGroup的方案，你看看是否满足要求。解决思路是用CullingGroup的可见性来裁剪粒子系统，具体做法如下： 1）在粒子系统的坐标位置放置一个CullingGroup，并设置其好包围球的半径； 2）利用CullingGroup的可见性以及onStateChanged事件来更新粒子系统的可见性。 该回答由UWA提供，欢迎大家转至社区进行进一步交流： https://answer.uwa4d.com/question/5adf13d13dba2a108c7e32f4 今天的分享就到这里。当然，生有涯而知无涯。在漫漫的开发周期中，您看到的这些问题也许都只是冰山一角，我们早已在UWA问答网站（answer.uwa4d.com）上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入，也许你的方法恰能解别人的燃眉之急；而他山之“石”，也能攻你之“玉”。 官网：www.uwa4d.com 官方技术博客：blog.uwa4d.com 官方问答社区：answer.uwa4d.com 官方技术QQ群：793972859（仅限技术交流） 本文封面图来自网络
今天，我们求知若渴、虚心若愚（附技术PPT）
春暖花开的三四月，侑虎科技的技术小伙伴穿枝拂叶，走过了漕河泾、张江高科、天地软件园，近日又前往了充满小资格调的艺术与科学湾。在这里，技术开放日《性能优化、进无止境》正在举行。 沿袭我们一向真诚开放的风格，大家随性而坐，对各自项目开发的经验和疑问各抒己见、畅所欲言。现场更是汇集了不少远道而来的开发者朋友：西山居、广州简悦、成都好玩一二三、北京盖娅、上海巨人等知名厂家，大家求知若渴的精神，让小编我想起了那么一句话：学而时习之，不亦说乎？有朋自远方来，不亦乐乎？也许是对本次活动最好的诠释了。 游戏和VR应用性能诊断与分析 性能优化几乎是所有游戏和VR项目研发过程中的必经之路，用户的需求和项目的要求总在不停地增长，同屏人数、屏幕特效和场景复杂度永远在向着“榨干”硬件的趋势逼近。内存泄露，资源冗余，代码性能低效，崩溃无法定位...这些优化“杀手”如何巧妙规避？活动现场，侑虎科技CEO张鑫围绕着CPU、GPU、内存等几大优化模块，为大家一一道来优化之路。 （点此可以下载完整技术PPT哦） Unity引擎的沉浸式VR介绍与VR案例性能数据精讲 作为国内为数不多的VR游戏之一，上海星为棋研发的VR游戏《Space Agent》已经登录Gear VR平台。在此，侑虎科技张强现场对该款游戏的性能数据进行深度剖析，让大家对Gear VR游戏的运行性能有了更为深刻的认知。 《六龙争霸》性能数据精讲 由祖龙娱乐研发、腾讯代理的MMO国战手游能在畅销榜上历时长久而经典不衰，除了精细的画质、丰富的任务策划，当然还离不开杰出的性能。不少开发朋友也因此慕名而来。同样，我们工程师在现场剖析了其性能数据，让更多的开发团队了解到一款性能优秀的移动MMORPG游戏在各个模块上应该做到怎样的程度。 新功能即将来袭 活动最后，我们也给到访者公布了小小的彩蛋：资源检测服务近期上线！该功能旨在帮助研发团队高效检测资源文件的创建是否合理，包括具体资源信息检索、冗余资源检测等。 如下图所示，小编先给大家来个惊鸿一瞥！ 那些年，我们走过的技术开放日... 这一次，我们在张江、在漕河泾、在天地软件园，在艺术与科学湾......下一次，我们在哪里？请等待我们的到访，跟着侑虎科技的小伙伴一起来求知若渴、虚心若愚。 Stay Hungry，Stay Foolish！
目前，在全国范围之内已经有了1200多家VR的体验点在使用大朋VR的头盔。对于这些大朋头盔的内容开发商，UWA就能帮其高效定位问题瓶颈。 和手游测试一样，开发者只需要在工程中集成UWA的测评SDK，上传至官网，即可在48小时内收到测评报告。 以下是DeePoon的官方案例，通过UWA测评以后的数据展现如下: UWA报告对项目性能中的几个关键指标均做了详细的检测，包括CPU性能开销、GC调用、渲染模块性能、动画模块性能、粒子模块性能、内存占用等。 下图中我们可以看到，在分析与建议一栏，UWA基于对引擎的了解和多年的行业服务经验，对每一个测试模块的数据给出合理的评定，即刻提供有针对性的解决方案。 同时，UWA中一些高级检测功能如重要参数解析、代码效率等，筛选出了CPU占用最高，堆内存分配最大的函数等重要性能相关的信息，免去了逐帧检测的大量人力和时间成本，让开发事半功倍。 限时邀请 除了CPU性能、内存，VR优化的注意点有哪些，并如何针对性地优化？如果您也有这样的疑问，可直接扫描下方二维码，即可加入项目查看，这里有更为详细的测评数据为您解答！（需要登录UWA账号） 目前，UWA支持的主流VR发布平台有Oculus Rift, Google Cardboard, Gear VR和DeePoon。关于更多VR平台的支持，我们也欢迎VR设备厂商提出合作意向。 近期活动 如何规避性能项目运行卡顿的问题？内存泄露、资源冗余如何定位？代码质量影响整体性能如何改良？ 4月9日上海，我们延续性能优化的主题，搭配国民级手游《六龙争霸》性能数据深度剖析，使大家对游戏/VR应用的运行性能有更为深刻的认知。 活动详情请戳下图↓
这也许是，全球第一篇VR游戏的深度性能测评报告
今天我们为大家带来由上海星为棋研发的VR游戏《Space Agent》的性能测评分析报告。作为国内为数不多的VR游戏之一，该游戏目前已经登录Gear VR平台。 这是一款性能优秀的飞行模拟类VR游戏，同时其游戏运行时也具有相当不错的舒适感。在我们真机测试的十几分钟内，并没有感到任何的“晕动”症状（Motion Sickness）。在此，我们将对该款游戏的性能数据进行深度剖析，希望通过这篇文章可以让大家对Gear VR游戏的运行性能有更为深刻的认知，并对大家的VR项目研发有所帮助。 CPU性能 该游戏在CPU占用方面的性能非常不错，下图为该游戏在三星S6上的CPU占用情况，可以看出，在三星S6上运行的33751帧中，超过10ms的帧数占比为17%，超过16ms的帧数占比为1%。 其整体CPU性能的优秀表现与其各个模块的合理使用是分不开的。下面，我们就详细剖析一下其CPU性能方面的亮点之处。 1. 渲染模块 该游戏在三星S6设备上运行时的渲染模块CPU开销如下图所示。通过统计，半透明物体渲染的CPU消耗均值为1.6 ms，主要集中在0.7~6.1ms范围内（5%~95%）。不透明物体渲染的CPU消耗均值为1.0 ms，主要集中在0.5~1.4ms范围内（5%~95%）。Draw Call峰值为153，且主要集中在65~125范围内（5%~95%）。 由上图可知，游戏渲染的相关参数基本均控制在合理范围之内。当然，美中不足的是，游戏场景中的三角面片数量较大，峰值为236100，该值稍高。对于Gear VR平台，一般我们建议将其控制在20万面片以内。同时，半透明渲染耗时存在瞬间增高的情况，如下图所示。对其进行进一步分析，发现其瞬间增高的情况均为粒子系统渲染所致，且主要在主UI界面出现处。这样，研发团队在后续过程中，对主UI界面处的粒子系统进行进一步的控制，即可大大降低粒子系统的渲染开销，从而进一步提升渲染性能。 如果你发现了自己的项目中，半透明渲染存在较高的性能开销，那么你需要进一步分析以下两种情况： （1）场景中是否存在半透明较多的GameObject，比如树叶、花草、UI界面等； （2）查看粒子系统的渲染开销。一般来说，半透明渲染的性能开销，无外乎这两种情况。 如果你的项目也遇到了场景网格面片数较高的情况。我们建议可以尝试一些网格资源简化的工具，比如Asset Store上的SimpleLOD插件，可以通过我们之前的文章《好插件让你事半功倍》查看其详细的功能介绍。 2. GC调用 在测试过程中，GC的调用频率很低。游戏在三星S6上运行33000+帧时，共检测到GC调用5次，平均6750帧/次。 GC调用频率如此之低，主要得益于函数的堆内存的少量分配。下图即为游戏运行过程中，其函数的具体堆内存分配情况。 重要提示：尽最大可能降低函数堆内存的分配，然后你会发现，GC将离你的项目越来越远！ 3. 动画模块 该游戏在三星S6设备上运行时的动画模块CPU开销如下图所示。通过统计，动画模块总体的CPU占用均值为0.6 ms，主要集中在0.4~0.7ms范围内（5%~95%），该值处于合理范围之内（一般建议在3ms以下）。 4. UI模块 该游戏在三星S6设备上运行时的UI模块CPU开销如下图所示。通过统计，UI模块总体的CPU占用均值为0.4 ms，主要集中在0.1~0.5ms范围内（5%~95%），为该值处于合理范围之内（一般建议在3 ms以下）。同时，累积堆内存分配总量为71.5KB，该值很低，说明游戏运行过程中UI界面的操作并没有引起UI网格的重建。 内存模块 《Space Agent》在内存上的表现同样突出，如下图所示。总内存峰值为127MB，Mono堆内存峰值为7.3MB，且内存的升降较为一致。 1. Mono堆内存 从上图可知，该游戏的总体Mono堆内存控制得很好，在33751帧中，Mono的堆内存峰值仅为 7.3MB。该值属于合理范围之内（<40MB）。 2. 资源内存 经过统计，该游戏的纹理资源数量峰值为139个，内存占用峰值6.5MB。内存占用之所以可以做到如此之小，得益于游戏中大量使用了ASTC格式的纹理资源。ASTC技术为ARM Mali的高端GPU所硬件支持的“自适应可伸缩纹理压缩技术”，不仅支持HDR，同时也支持3D纹理。该纹理格式可以在保证视觉质量的前提下，达到更大的纹理压缩比。在Space Agent所使用的全部纹理资源中，ASTC格式纹理有116个，Alpha8格式纹理有8个，ARGB32和RGBA32格式资源数共有15个。 重要提示：目前支持的Gear VR的主流设备为三星Note5、三星S6和S6 Edge。这些机器目前均使用Mali GPU，所以对于专注于Gear VR平台的VR游戏团队可尝试尽可能使用ASTC纹理格式。当然，如果需要支持过多的移动VR设备，ETC2也是不错的选择。 3. 其他资源的内存占用情况如下： Mesh资源稍大： UWA建议尽可能控制在20MB以内。建议尝试通过一些网格资源简化的工具来对场景网格进行进一步简化。 同时，我们也看到网格资源中存在19个网格拥有Color属性，72个资源拥有Tangent属性。一般来说，仅有较为复杂的Shader才会使用这些属性，所以研发团队需要对拥有这些顶点属性的资源进行进一步检测，明确其是否确实需要。 重要提示：多余的顶点属性可能会在Draw Call Batching时为你带来大量不必要的内存占用，拥有不同顶点属性的网格资源，一般不建议拼合成一个网格。 AnimationClip资源： 以上则为《Space Agent》在CPU性能和内存管理方面的具体使用情况。优秀的CPU性能，较低的总体内存和堆内存分配，以及合理的资源使用，足以说明该研发团队具备非常深厚的技术功底和对于引擎相当优秀的把控能力。 设备温度 设备温度是我们在分析VR应用性能数据中非常看重的一块。不同于移动游戏，目前的Gear VR（或移动VR）方面，设备的发热量是一个相当难缠的问题。每秒60帧的CPU更新频率、工作量几乎翻倍的Graphics Pipeline（虽然Unreal和Unity都已经将Culling、Shadowmap的计算，但Draw Call、底层Graphics API Call和State切换等等均基本为2倍），让即便是高端如三星S6的手机，也可以在短时间内迅速升温。手游中的发热量也是一个大家头疼的问题，但与移动VR相比，简直是“小巫见大巫”。下图为《Space Agent》在测试过程中，三星S6的设备温度变化情况。可以看出在测试的十分钟过程中，设备温度上升了8度（36度~44度）。对此，强烈建议正在Gear VR设备上进行应用开发的团队时刻注意设备的温度升温情况。 为什么我们要如此关注设备温度？ 因为现在的移动设备在温度高于一定值之后，出于保护等原因，硬件设备会自动降频，下图则为硬件设备温度过高后，运行频率从60fps被强制降为30fps。这将极大地影响VR应用的体验感受。 如何延缓设备升温呢？ 来使用 UWA 吧，根据测评分析报告定位性能瓶颈。然后根据我们的分析和建议，优化你能优化的一切！ 以上则为该项目在性能方面的具体数据分析。在我们测评过的项目中，这些方面也是绝大多数VR研发团队遇到的共性问题。希望以上的讲解对大家的相关问题有所帮助。 最后，非常感谢《Space Agent》研发团队对 UWA 的认可和支持。感谢他们乐于将项目性能数据与大家一起分享，让更多的VR研发团队了解到一款性能优秀的移动VR游戏在各个模块上应该做到怎样的程度。同时，也希望更多的开发团队可以与我们一起来分享他们的性能数据，让更多的VR游戏/应用开发者受益！
移动游戏中，场景切换偶尔卡顿、粒子播放稍作停留......隔着与屏幕十几厘米的距离，手游上的这些性能问题或许还能让大部分玩家勉强接受，但VR的目标是赋予玩家在一个亦幻亦真的世界中几近真实的感受。在这过程中，任何的晕眩不适感都可能使得整个产品的体验变差，于是几乎翻了三倍的帧率以及一些更高的性能标准往往让产品的优化之路遥遥无期。 UWA是什么 作为游戏和VR应用性能诊断与优化工具，UWA通过真人真机对项目进行测试，提供详尽的性能分析测评报告。该报告既能从宏观上分析项目运行时的整体趋势，又能深入剖析内存占用和具体资源的使用情况，详细诊断用户代码在项目运行时的效率，帮助研发团队高效定位问题根源，及时对瓶颈问题进行修复。 一、优化简单不盲目 我们以一个VR开源项目《Unity Chan》在Oculus Rift上的表现为例，通过UWA测评以后数据展现如下： 可以看到，UWA报告对项目性能中的几个关键指标均做了详细的检测，包括CPU性能开销、GC调用频率、渲染模块、动画模块、内存占用等。 在分析与建议一栏中，UWA基于对引擎的了解和多年的行业服务经验，对每一个测试模块的数据给出合理的评定，即刻提供有针对性的解决方案。 例如在上述Demo的动画模块功能中，我们对 MeshSkinning.Update的CPU消耗均值和 Animation.Update/Animator.Update作出评估的同时，也提出以下建议： 研发团队在尽可能保证动画效果的同时，需要对模型的网格进行简化，建议研发团队尝试使用Unity Asset Store中的>SimpleLOD插件来对骨骼蒙皮网格进行简化； （如果Animation.Update耗时较高）建议研发团队尽可能使用Mecanim动画系统，而非旧版Animation动画系统。一般来说，>Mecanim动画系统的运行效率相较于旧版动画系统要优秀很多； （如果Animator.Update耗时较高）建议研发团队对于每个角色尽可能开启“Optimize GameObject”选项（Rig->Optimize >GameObject），开启该选项，引擎将会极大地降低Mecanim动画系统和MeshSkinning.Update的开销。 这些实在的建议能帮助开发者高效定位问题瓶颈。另外，UWA中一些高级检测功能如重要参数解析、代码效率等，筛选出了CPU占用最高，堆内存分配最大的函数等重要性能相关的信息，免去了逐帧检测的大量人力和时间成本，让开发事半功倍，项目性能更上一层楼。 二、让技术围绕内容跑 在UWA推出后，我们也惊喜地收到了一些制作精良的VR作品。测试之余，我们不禁感慨开发者的想法是取之不竭的金矿，对于VR的未来，我们寄予厚望。 UWA希望通过为开发者高效解决技术难题，慢慢拉近 Virtuality与 Reality的距离。 当然，VR领域同大家熟知的游戏领域大不相同，更多的参数需要探索、定制和重新衡量，比如运动加速度、相机转速、深度变化等等，这些都对VR体验的舒适度产生很大的影响。在后续的研发中，我们也会不断更新UWA的测评机制，为VR内容开发提供更有针对性的考量。 目前，UWA支持的主流VR发布平台有Oculus Rift, Google Cardboard, Gear VR。关于其他VR平台的支持，我们也欢迎VR设备厂商提出合作意向。