cover_image

Unity3D 引擎的性能优化实践

胡春源 之家技术
2022年10月26日 10:00

关注“之家技术”,获取更多技术干货

图片

总篇175篇 2022年第50篇


 背景 

Unity 优化涵盖范围大,涉及知识面广,随着功能不断增长,需要优化的内容也在增多。在VI销冠神器的几次迭代中发现项目的各项性能指标都存在偏差,所以开始着手进行项目的优化工作。

本篇文章以浅显易懂的角度介绍一下 Unity 优化和VI销冠神器的优化经验。

 

 1.渲染流程 

本节主要是为不熟悉画面渲染的读者讲解一下渲染的流程,并讲解一下 CPU/GPU 和内存在渲染中的职责。

图片

渲染管线主要分为三大阶段应用阶段/几何阶段/光栅化阶段,这里将各个阶段简单讲解:


1.1

应用阶段

这个阶段主要在 CPU 中,从 CPU 中整理好渲染数据,并将数据发送给 GPU。


1.2

几何阶段

通过对输入的渲染图元进行处理,这一阶段将会输出屏幕空间的二维顶点坐标,深度值等信息并传递给下一阶段。


1.3

光栅化阶段

将点线面等几何概念实体化成像素,这一阶段会使用上一阶段传递的数据渲染出最终的图像。

图片

此图中很浅显的标识了 3Dmesh 和 2Dtexture 之间的关系。

3Dmesh 提供定点数据进去 screen space 空间绘制之后转换为片段着色器中填充,而后再由 TEXTER 根据坐标填充颜色,最后渲染到显示器上。

 

 2.名词解释 


2.1

Drawcall

Drawcall是CPU对底层图形绘制接⼝的调⽤命令GPU执⾏渲染操作,渲染流程采⽤流⽔线实现,CPU和GPU并⾏⼯作,它们之间通过命令缓冲区连接,CPU向其中发送渲染命令,GPU接收并执⾏对应的渲染命令。


2.2

合批

动态合批与静态合批其本质是将多次绘制请求,在允许的条件下进行合并处理,减少CPU对GPU绘制请求的次数,达到提高性能的目的。


2.3

图集

图集是将很多零碎的2D小图整合成一张大图,方便unity渲染合批,降低渲染消耗。

 

 3.优化概述 

了解完 CPU/GPU/内存的职责之后就可以对每一个模块进行优化了。Unity 性能优化细节较多,每一个功能点都可以单独写一篇文章。

这里先了解一下 Unity 大致有哪些优化分类和优化点:

图片

模块

优化点

CPU

 

渲染  

物体顶点和图像的绘制

降低 DrawCall  批处理 合并图集

 压缩资源

动画  

物体动画/骨骼动画

物理  

物理计算,重力和碰撞

 UI

UI 的绘制和响应事件

合批  动静分离

粒子  

粒子的生命周期和绘制

IO

文件的操作和读取

GC

内存的回收和释放

场景/资源的加载/卸载

代码 

代码的调用次数和调用耗时

GPU

    

填充率

像素的复杂度

几何复杂度

GPU 显存带宽

减少顶点数量,简化计算复杂度

 压缩图片/Mipmap,以适应显存带宽

         LOD/ 遮挡剔除/光照贴图等

内存

 

模型/纹理

尺寸

格式

Read & Write

规范好模型面数,纹理尺寸和格式

网络资源

Bundle

图片

数据

管理好网络加载和释放

托管堆

高频率调用

string 拼接

部分 UnityAPI

内存

避免一次性堆内存的过大分配

避免不必要的内存开销

 

其他

包体优化点

使用 AssetBundle 管理资源
压缩贴图

 发热优化点

 CPU/GPU 占用率过高
 相机功能
帧率较高

 代码优化点

高耗时代码
高调用代码
复杂/耦合的代码逻辑 代码逻辑在我看来也算优化
的一部分 
减少代码耦合可以在很多方面帮助性能优化


 4.工具/方法论 

工欲善其事,必先利其器。选择好的工具和方法论可以事半功倍,这里整理一下我平时使用的工具和总结出的方法论。

 

4.1

工具

• Profiler UnityEditor 性能分析工具

• UPR 官方性能分析工具

• UWA 第三方性能分析工具

• Memprofile 内存检查工具


► 其他还有一些移动端和 PC 调试工具:

• mali Graphic debugger

• snapdragon profile

• ADB & AndroidStudio

• Xcode GPU Frame Caputre

 

4.2

方法论


► 量化

•  优化前先记录一下性能数据,在优化后做一下对比,并量化你的优化收益。

•  防止做负优化。


► 隔离法

•  隔离可疑区域和代码,然后比较,逐步排查,缩小问题范围。


► 对比法

•  记录数据,用正常数据和性能变化之后的数据进行对比,定位问题。


► 项目前期的规范确定

•  需要适配的机型,参考按照手机/显卡使用率,给定一个最低配置。

•  模型面数,材质大小和格式。

•  尽早使用 AssestBundle 管理资源。

•  Unity 版本与各个 SDK 版本。

•  逻辑层架构与底层通用功能。


► 经验

•  让正确的程序快,比让快的程序正确更简单,所以应该先进行功能迭代,再进行优化。

•  图形学第一定律:如果它看上去是对的,那么它就是对的,可以用一些技巧让画面正确,从而达到优化的目的。

 

 5.数科产品 VI 销冠神器 

性能优化介绍


5.1

产品介绍

VI 销冠神器,作为辅销工具解决经销商在售卖场景中的痛点,利用 AR 虚拟现实技术打造辅销工具,高效支持产品售卖,满足厂商定制需求。


5.2

问题回顾

在多次迭代中产品和客户反馈了以下几个问题:

1. AR 功能识别率低,扩展性不足;

2.包体过大;

3.帧率低;

4.发热量大;

5.内存占用过高。

 

由于我刚接手销冠项目,对项目的熟悉程度不足,所以决定先做一些投入时间少、优化收益大的、比较宽泛的优化,等之后再做一些需要投入更多时间精力的、比较细碎优化。

针对反馈的问题我做了以下工作:


5.3

AR 优化

► 问题分析:

我分析了一下 AR 功能性能指标差主要是由以下几个原因导致的:

1. 代码耦合严重;

2. 实车绑定和平面识别速度过慢;

3. 实车绑定训练文件过大;

4. 安卓 iOS 代码写在一个类里面耦合严重;

5. 扫车和扫平面同时创建内存占用较多。

 

► 优化过程:

项目中使用 2 个场景用来区分 EasyAR 和 Vuforia减少到 1 个场景,安卓和 iOS 在自己的类里实现逻辑,初始化时判断平台,通过继承实现每个端的相关逻辑,可以处理一些复杂情况。比如安卓平台的 Vuforia 和 EasyAR 切换 和 iOS 平台的扫描车和地面切换的问题。

通过异步和更改加载时机来解决扫平面和扫车的内存峰值,配置了一个 Editor 环境下模拟 AR 环境的设置,可以很方便在 Editor 环境下复现问题,省下经常打包到手机上的时间,训练模型优化 模型减面后重新训练一版,在不降低识别精度的情况下减少包体大小。

图片

► 优化结论:

1. 降低了 28mb 的包体大小;

2. 提高了平面和实车的识别率和稳定性;

3. 降低了代码耦合,解决了遗留的 bug;

4. 配置了 Editor 模拟环境,提高了开发效率和 Debug 效率。

 

5.4

贴图优化


► 问题分析:

在项目中发现有一些材质的图片尺寸较大,而且一张图片重复导入了多次。

 

► 优化过程:

跟美术人员反馈后,在他们新制作的材质包中做了优化,使用了新的 shader,用更低的内存占用实现了更好的效果。

图片
图片
图片

 ► 优化结论:

1. 在提高美术效果的同时降低渲染压力;

2. 降低发热,提高项目的稳定性;

3. 降低 200m 左右的内存占用,实现了更好的美术效果。

 

5.5

内存优化


► 问题分析:

接手项目是 AR 加载时内存峰值 iPhone7Plus 会经常崩溃,并且打开 WebView 的时候也会超出内存限制引发项目崩溃并且项目发热严重,帧率不稳定。

经过细致排查发现主要是因为:

1. 各个模块加载时的资源抢占;

2. 多张 4k 材质贴图未压缩 渲染数据包过大;

3. 精细的模型和过高的帧率。

 

► 优化过程:

解耦各个模块的依赖,错开初始化时机,降低内存峰值;使用新的材质实现方式,用更小的图片实现更好的美术效果;给美术提供减面思路,并适度降低帧率。

 

► 优化结论:

1. 减少内存峰值;

2. 减少总内存占用 200m 左右。

 

5.6

发热优化


► 问题分析:

销冠项目发热部分是来源于

1. 摄像头的发热量;

2. CPU/GPU 占用过高;

3. 渲染次数多;

4. 渲染数据大;

5. 帧率高。

 

发热量优化一般要做到两点:

降低渲染次数和降低每次渲染的数据大小。

 

► 优化过程:

设置项目帧率至 45 帧,默认 Unity 不限制帧率,一般会跑满手机全部性能,较高的帧率会带来大量发热;降低渲染次数 UI 图片打成图集降低 drawcall;压缩材质图片 项目中用到了一些过大的材质图片,已反馈给模型制作方进行材质图片压缩。

 

► 优化结论:

1. CPU 温度从 65 度降到 55 度;

2. 发热开始时间明显延后。

 

5.7

包体优化


► 问题分析:

接手销冠项目时包体大小为 210mb

图片

这里的包体大小用安卓的 apk 大小来举例销冠项目包体占用的大头有:

1. AR  Vuforia 和 EasyAR 的 SDK 都会占用 20mb 左右的包体大小.Vuforia 的训练文件又会占用了 50mb 共计 90mb;

2. 打包到本地的材质贴图和模型 共计 90mb;

3. UI 图片 15mb 左右;

4. Unity 引擎和代码逻辑 20mb 左右。

 

► 优化过程:

剔除项目无用图片资源 212m→206m,Vuforia 训练模型减面 206m→170m,本地美术资源上传网络 按需下载 170m→80m。

 

► 优化结论:

包体从 210MB 降低到 80MB。


 

 6.总结 

随着工作经验的不断增长,发现优化和架构才是程序员的核心竞争力。在初中级程序期,我也烦恼过为什么要去了解那么多底层和算法知识。

现在看来,这些知识都是前人无数次迭代和试错总结出来的。在学习的同时也掌握了一套自己的经验,在之后的工作中写出更健壮和高效的代码。

 销冠项目只做了部分优化,还有很多细节可以继续优化。目前销冠项目由其他同事负责维护,现在我所在的全息项目也到了要优化的阶段。未来提升方向是在不牺牲画面效果的同时提升程序性能,着重资源管理和 Shader 的开发。


限于作者水平,难免会有疏漏和错误,欢迎指正,共同交流。


优质文章分享


关于优化已经有很多非常好的文章,这里推荐一些:

[1] Unity 性能优化总结—CPU篇  

https://zhuanlan.zhihu.com/p/21913747

[2] Unity 优化之 GPU 优化

https://zhuanlan.zhihu.com/p/47056964

[3] Unity 游戏中,在做性能优化时怎么准确判断是内存、CPU、GPU 瓶颈呢?

https://www.zhihu.com/question/522171023

[4] Unity 移动端游戏性能优化简谱之 常见游戏内存控制  

https://blog.uwa4d.com/archives/EDU_Performance2.html

[5]如何定位游戏发热问题 

https://blog.uwa4d.com/archives/TechSharing_300.html

[6] Unity 移动端游戏性能优化简谱之前言 

https://blog.uwa4d.com/archives/EDU_Performance.html

[7] Unity 官方 Profiler 文档 

https://docs.unity3d.com/cn/current/Manual/ProfilerMemory.html

[8] C#代码优化:拯救你的 CPU 耗时 

https://zhuanlan.zhihu.com/p/348544667

[9] 基础且直白的 Unity 渲染

https://zhuanlan.zhihu.com/p/457706826

 

UWA 性能优化系列:

[1] Unity 性能优化系列—渲染模块 

https://blog.uwa4d.com/archives/UWA_ReportModule1.html

[2] Unity 性能优化系列—加载与资源管理 

https://blog.uwa4d.com/archives/UWA_ReportModule2.html

[3] 粒子系统优化——如何优化你的技能特效 

https://blog.uwa4d.com/archives/UWA_ReportModule3.html

[4] Unity 性能优化系列—Lua代码优化 

https://blog.uwa4d.com/archives/UWA_ReportModule4.html

[5] Unity 性能优化系列 — 资源内存泄漏 

https://blog.uwa4d.com/archives/UWA_ReportModule5.html

[6] Unity 性能优化 — 动画模块 

https://blog.uwa4d.com/archives/UWA_ReportModule6.html

[7] Unity 性能优化 — 物理模块 

https://blog.uwa4d.com/archives/UWA_ReportModule7.html

[8] Unity 性能优化 — UI模块 

https://blog.uwa4d.com/archives/UWA_ReportModule8.html

作者简介

图片


 胡春源 

 主机厂事业部-创新项目团队。

 2022年2月入职汽车之家,先后负责VI销冠神器和全息仓的架构、优化、功能开发等工作。现在主要负责全息仓的架构和功能的相关工作。


图片

阅读更多:


▼ 关注「之家技术」,获取更多技术干货 

图片



修改于2022年11月01日
继续滑动看下一个
之家技术
向上滑动看下一个