为什么需要性能优化?
性能优化的本质 : 慢与快的问题
性能优化流程
发现问题(什么平台,操作系统,情况,一般还是特殊)
定位身体(什么地方造成的?需要工具 Or 方法?)
研究问题(处理方案?性能优化前提条件?)
解决问题
影响性能的cpu,gpu,带宽,内存
优化思路:
空间换时间等
拼ui
取消勾选uiimage的射线检测
资源的设置和检查
AssetChecker工具使用
生成资源检测报告,根据检测报告去进行具体优化
静态资源优化
AudioSource
- 立体声道(ForceTOMono)
- 加载模式
- 平台对应压缩格式
优化后 :
apk大小从560下将到544
audio 包体 76下降了70
cpu占有 从2.5上升到了5%
是因为部分audio 使用stream模式加载
模型
优化原始导入模型文件
统一单位
模型中的 多余文件(摄像机 ,灯光,材质)
模型中纹理(不建议纹理随模型导出)Animationtype 设置
骨骼对应设置
model 的read/Write
优化后 :仅只有scene 场景内存从400降低到377.4
纹理
- 纹理的导入
纹理类型的设置
平台对应压缩格式
加载模式
纹理贴图大小(2的倍数)
alpha is Transparency(半透明,增加内存,alpha占1字节)
read/Write
纹理过滤 2.纹理图集
优点:静态合批 减少drawcall
减少碎纹理,通过压缩图集可以降低纹理内存和冗余
缺点:
美术需要合理规划,制作修改成本高 3.mipmap
逐级降低分辨率保存纹理副本,生成纹理Lod,根据像素在屏幕中占用纹理空间来选择mipmap级别进行采样
优点:
提高纹理采样性能gpu不需要远距离对对象进行纹理采样
纹理渲染质量:远距离下过采样导致的噪点问题
缺点:
造成额外的内存开销:mipmap纹理需要生成低分辨率副本
实际上 - 纹理图集利用率偏低,浪费内存
- 不合理的半透明纹理
- 不打图集的序列帧动画
- 大量重复纹理
- 内容相似贴图只是颜色信息变化
- 大量颜色渐变贴图不压缩,也不采用单像素宽度
优化后 :
apk 大小从544.6 变化到402.9
整体运行内存从1.36G 变化到1.21g
graphic& graphic Dirver 从0.98g 变化到0.77g
Texture 个数404 减少到359
内存从670 减少到 511.9
动画
优化查看原则:
看效果差异(与原始动画是否明显)
曲线数量(总曲线数量与各种曲线数量,常量曲线比重 大更好)
动画文件大小(通常都在1m以内 超过1m需要排查)
注意事项
1.Animationtype 设置
通用比人性节省30% cpu
2.动画压缩格式
unity资源
unity资源导入工作流
ToTd:暂时未理解
1.presets
2.AssetGraph
3.自己写工具
unity资源创建注意
1.减少空节点
2.嵌套预制体
性能优化
渲染优化
TODO: 暂时没有实际做过
- rameDebugger与XCode的GPU Frame Capture工具的使用
- SSao优化
TODD: 暂时未理解 - AA 渲染
- 后处理优化
渲染剔除
看不见的像素,网格,对象
unity 中的剔除:
像素剔除:摄像机平截头体剔除、Back-face Culling、EarlyZ、Pre-Z Pass
网格剔除:Layer Mask、可见距离剔除、Occlusion
灯光剔除:Tile-Based Deferred Rendering、Forward+
场景剔除:Additive Scene
用户扩展剔除:
场景数据结构:Octree、BSP Tree、Portal、Voxelization、SDF等
GPU Culling: Hi-Z Pass、 Temporal Reprojection CullingCluster、Tile-based Visible Buffer等
简化方案
Unity下的简化:
Quality Settings
通过烘焙光照简化实时光照
通过BoundingBox或替代体碰撞代替Mesh碰撞
通过Local Volume代替Global Volume
RayCast代替SphereCast、CapsuleCast等
纹理文字代替系统文字
Mesh LoD
Shader LoD
HLOD
通过Camer Override代替URP管线中的一些通用设置
各种OnDemand更新或分级设置接口
用户扩展简化:
场景简化数据结构
第三方LOD方案
Mesh Impostor
Animation LOD
骨骼LOD
2D寻路代替Navigation Mesh
扩展类似OnDemand接口
batching
哪些内容需要Batching
广义上讲:
资源Batching(Mesh、Texture、Shader参数、材质属性)
Draw call Batching (Static Batching、Dynamic Batching)
GPU Instancing(直接渲染、间接渲染、程序化间接渲染 )
Set Pass call Batching.( SRp Batching)
资源的Batching
Mesh:
Mesh.CombineMesh,合并静态网格对象
Submeshes->Single Mesh,合并材质与贴图,不同材质通过通道图标记
Texture:
AtlasTexture,通过纹理坐标映射多张贴图
TextureArray纹理数组
Shader变量与材质属性
Material Property Block(Build In管线)
Const buffer(SRP管线)
Draw caBatching:
Static Batching
StaticBatchingUtility.Combine
Static Batching限制
额外内存开销
64000个顶点限制
影响Culling剔除
Dynamic Batching限制
合批不超过900个顶点属性,(注意不是900个顶点)
除了渲染阴影对象外,相同材质,不同材质实例也不能合并
具有光照贴图的游戏对象如果有附加渲染器参数时,如果需要动态合批这些对象他们必须指向相同的光照贴图位置。
有多Shader Pass的游戏对象无法做动态合批
受多个光照影响的游戏对象,满足动态合批条件合批后,只会受一个光源的影响
延迟渲染下不支持动态合批
CPU开销可能会增大,需要测试开启使用
Gpuinstancing:
DrawMeshInstanced
DrawMeshInstancedIndirect
DrawMeshInstancedProcedural
Batching优化顺序
资源Batching >SRP Batching =Static Batching >GPU
Instancing>Dynamic Batching
Batching失败原因
内存优化
托管内存优化
Boxing Allocation装箱操作
String字符串拼接
闭包分配
避免使用Linq库
Unity中提供了NonAloc函数
如Physics.RayCastAl用Physics.RayCastAlINonAlloc代替
Unity.Object.FindobjectsOfType,
UnityEngine.Component.GetComponentsInParent,
UnityEngine.Component.GetComponentsinChild 等
成员变量访问方式
UnityEngine.Mesh.vertices=>UnityEngine.Mesh.GetVertices,
UnityEngine.Mesh.uv=> UnityEngine.Mesh.GetUV
UnityEngine.Renderer.sharedMaterials=> UnityEngine.Renderer.GetSharedMaterials
Unity.Input.touches=> Unity.Input.GeTouches等