1. Profiling
最最总要的一部分。判断清除主次再进行优化
1.1 性能报告
- 根据第三方性能的自动化测试报告确定性能瓶颈
1.2 引擎自带工具:
- Unity Profiler 关键函数都有打桩(stub), 在时间上连续,可以排查性能峰值相关问题
- Unreal Profiler
- Magic Sniffer
1.3 IDE:(CPU、 网络,一般是快照)
- Visual Studio性能探查器
- Xcode Instuments
- Android Profiler
- Android Systrace(需要打桩)
1.4 渲染分析工具:
- Xcode
- RenderDoc
- Visual Studio Graphics Diagnostics
- Nvidia NSight (其中metal和Dx11可以pixel debugging)
2. 资源优化
2.1 纹理
2.1.1 纹理尺寸
- 美术资源使用合理的纹理大小
- RT、shadowmap使用合理的分辨率(trade off)
- 了解设备支持的最大尺寸 (大部分支持4096x4096)
- NPOT vs POT
- ios PVRTC 只支持NPOT,而且是方图
- 某些硬件只支持NPOT(纹理寻址、MIPMAP, 移位操作比(除法/乘法)快)
- 资源检查管线
2.1.2 纹理通道
- 灰度图、高度图、掩码图,16位图、8位图
- 纹理压缩也是减少纹理通道的手段(GPU直接支持,可以减少包体、内存、显存)
- 纹理压缩格式:
- Window(DirectX) -> DDS,
- Android -> ETC1(Alpha通道需要分开), ETC2
- IOS -> PVRTC 压缩一般需要白名单,某些资源需要不压缩(压缩带来透明通道精度损失)
2.1.3 纹理复用
- 共享图库(尽量使用通用控件,达到复用)
- 九宫切图
- 复合纹理(翻转、镜像、顶点偏移)
2.2 UI
2.2.1 图集
- 图集应该关闭Mipmap
- 减少30%纹理大小
- 图集应该合理规划
- 一个界面尽量只引用自己的图集和共享图集
2.2.2 UI层次
- 合批条件:
- 绘制顺序连续
- 材质相同
- 应该避免:
- 引用很多别的图集
- 自身图集和公共图集相互穿插
- 文本穿插在sprite之间(极限优化的话,文字可以考虑做到sprite上,但是影响本地化)
- 使用Mask(一个mask至少增加两个DC)
- 频繁增删元素导致canvas更新,可能引起重新提交顶点
2.3 字体
2.3.1 尽量使用sdf字体
sdf字体优势: - 高质量缩放,增大字号无需额外纹理 - 描边、glow、文字阴影在shader里就能实现,且质量很高
2.4 模型(包括动画)
- 模型减面(不可见面片剔除、低模)
- 顶点属性剔除、浮点精度降低
- LOD
- static batch, dynamic batch
- GPU instancing(大量同种模型)
- GPU skinning
2.5 场景
- static batch
- light map烘培
2.6 粒子
性能杀手(CPU + GPU):
- 每帧计算量大。涉及发射器/效果器/曲线插值等,耗费CPU性能。
- 频繁操作内存。粒子在生命周期里,实例持续不断地创建/删除,即便有缓存机制下,依然避免不了内存的频繁读取和碎片化。
- 每帧更新数据到GPU。从Lock顶点Buffer到写入数据到GPU,会引发线程等待,也加重CPU到GPU带宽的负担。
- 增加大量Draw Calls。粒子特效通常五花八样,使用很多材质,导致引擎无法合批优化,大量增加绘制次数。
- 导致Overdraw(过绘制)。粒子一般会开启Alpha Blend,在同屏粒子多的情况下,会造成严重的Overdraw。
优化方法:
- 优化粒子属性:关闭阴影、光照。不透明的粒子关闭alpha blend
- 禁用高级粒子特性:粒子碰撞器、模型粒子
- 制定美术规范:限定粒子个数、贴图尺寸、材质个数等
- 使用bookflip(序列帧动画)
- 使用GPU 粒子(Unity: Vfx Graph, UE:Niagara)
3. CPU优化
- 缓存计算结果
- 预处理(空间换时间)
- 分帧处理卡顿
- 多线程
- 文件IO
- 网络IO
- 骨骼动画
- 渲染指令提交
- 音视频解码
- 加密解密
- 性能敏感逻辑考虑写到native层
- 使用GPU(compute shader)
4. 渲染优化
渲染性能消耗点:
- DrawCall
- OverDraw
- 带宽负载(CPU到GPU的传输能力)
- 显存
- GPU计算量(片元数目、shader复杂度)
优化方法:
- 合批,减少DrawCall
- 减少Overdraw:禁用Alpha Test,少用Alpha Blend
- 多线程渲染:硬件级:Vulcan/Metal,软件级:依赖引擎架构
- 减少片元数目:软件阶段剔除(视锥剔除、遮挡剔除)、硬件阶段剔除(视口裁剪、背面剔除、early-Z优化)、慎用MSAA
- 画质分级
- 优化Shader
- 降低浮点精度
- 避免discard fragment
- 能在Vertex中计算的不要放到Fragment;能在CPU算到uniform中的不要放到vertex中算
- 像素光照改为顶点光照
- 矢量计算与标量计算尽量分开进行
- 考虑预生成LUT(Look Up Table)
- shader分级(LOD)
- 避免循环和分支(考虑手动loop unrolling)
5. 内存优化
- 内存池
- 对象池
- GC控制
6. 网络优化
- 合理使用字段
- 更高效的压缩
- 多线程处理网络IO