Unity CPU优化卡顿
Posted 时光不染
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity CPU优化卡顿相关的知识,希望对你有一定的参考价值。
当我们打开一个包含大量数据的新场景或背包界面,往往会比较卡顿,因为你大概的时候要处理这样的数据↓
解决方案无非是缩小总数据量↓
排队(缩小单位时间内数据量)↓
场景1:打开背包等包含大量数据的界面(渲染模块)
场景2:场景切换等同一时间大量instantiate的场景(加载模块&分帧加载)
渲染模块(缩小数据量)
影响渲染效率的两个最基本的参数:DrawCall和Triangle
DrawCall
DrawCall是一个命令,发起方是CPU,接收方是GPU。这个命令仅仅会指向一个需要被渲染的图元列表,不会包含任何材质信息。
每次CPU准备数据并通知GPU的过程就称之为一个DrawCall。
降低Draw Call | 降低DrawCall主要的方式有动态合批、静态合批、GPU Instancing、SRP Batcher。批处理系统自动进行,我们只需注意批处理的规则。GPU Instancing是Shader开关,默认开启。 |
使用图集,尽量不使用实时光照和阴影效果 | |
游戏性能并非Draw Call越小越好。这是因为,决定渲染模块性能的除了Draw Call之外,还有用于传输渲染数据的总线带宽。当我们使用Draw Call Batching将同种材质的网格模型拼合在一起时,可能会造成同一时间需要传输的数据(Texture、VB/IB等大大增加,以至于造成带宽“堵塞”,在资源无法及时传输过去的情况下,GPU只能等待,从而反倒降低了游戏的运行帧率 |
还可以通过分块加载,无限列表等方法降低同时存在的数据量来降低DrawCall。
Triangle
Triangle(三角面)面片数越高会导致渲染的耗时越高。一般建议通过LOD工具减少场景中的面片数,进而降低渲染的开销。
需要说明的是,此处的面片数量并不是当前帧场景模型的面片数,而是当前帧所渲染的面片数,其数值不仅与模型面片数有关,也和渲染次数相关。例如:场景中的网格模型面片数为1万,而其使用的Shader拥有2个渲染Pass,或者有2个相机对其同时渲染,那么此处所显示的Triangle数值将为2万。
多线程渲染
开启多线程渲染后,主线程的渲染耗时就会有很明显下降(//todo未验证)加载模块(缩小数据量)
Instantiate的卡顿与三部分开销相关:相关资源加载、脚本组件的序列化和构造函数的执行,并且绝大部分原因均是相关资源加载导致。 资源加载是加载模块中最为耗时的部分,其CPU开销在Unity引擎中主要体现在Loading.UpdatePreloading和Loading.ReadObject两项中资源优化
纹理
纹理 | 分辨率 | 纹理资源的分辨率对加载性能影响较大,分辨率越高,其加载越为耗时。建议512x512 |
格式 | 纹理资源的格式对加载性能影响较大,使用 ASTC 或 ETC->android & PVRTC->ios | |
Mipmap | 开启Mipmap功能同样会增大一部分纹理大小,一般来说,其内存会增加至原始大小的1.33倍.开启Mipmap功能会导致资源加载更为耗时,且设备性能越差,其加载效率影响越大 |
ASTC格式纹理实践
3、严格检查纹理资源的Mipmap功能,特别注意UI纹理的Mipmap是否开启。在UI中,由于不存在元素相对于相机的位置不断变化的需求,一般情况下也不需要频繁缩放图片(特殊需求除外),所以对UI而言Mipmap的存在对性能提升其实是没有意义的。2D游戏或UI中,不建议开启Mipmap
网格
网格 | 数据量 | 资源的数据量对加载性能影响较大,面片数越多,其加载越为耗时。设备性能越差,其耗时差别越为明显 |
顶点属性 | 顶点属性的增加对内存和AssetBundle包体大小影响较大。对于加载效率影响较大,且顶点数越多,影响越大 | |
Read/Write | 关闭Read/Write功能会降低AssetBundle的物理大小,其降低量与资源本身数据量相关。同时,关闭Read/Write功能会大幅度降低网格资源的内存占用;关闭Read/Write功能会略微提升该资源的加载效率。 |
Shader
网格 | Shader资源的物理体积与内存占用虽然很小,但其加载耗时开销的CPU占用很高,这主要是因为Shader的解析CPU开销很高,成为了Shader资源加载的性能瓶颈 |
Mobile/Particles Additive在解析方面的耗时远小于Mobile/Diffuse、Mobile/Bumped Diffsue甚至Mobile/VertexLit | |
除Mobile/Particles Additive外,其他三个主流Shader在加载时均会造成明显的降帧,甚至卡顿。应尽可能避免在非切换场景时刻进行Shader的加载操作。 |
建议:
1、在保证渲染效果和项目需求的情况下,尽可能降低Shader的Keyword数量,以提升Shader的加载效率;
Prefab优化
不要在Awake和OnEnable里写太多逻辑 切换场景加载Prefabs时,如果挂载的脚本或AddComponent的脚本 Awake和OnEnable脚本里有另外10个Prefab的实例化。那么会等这10个Prefab全部加载完成才能完成当前prefabs加载显示。 可以在Start里实现类似需求,或分帧加载,分块加载预加载&分帧加载(排队)
通过AssetBundle 依赖关系打包将资源预先加载,将 Instantiate 的总体耗时拆分,平摊到之前帧进行执行(比如切换场景处等),从而让 Instantiate 实例化操作的局部耗时更加平滑以上是关于Unity CPU优化卡顿的主要内容,如果未能解决你的问题,请参考以下文章
Unity3D场景性能优化/渲染/卡顿/搭建优化 遮挡剔除/层消距离技术/LOD(多层次细节)
Unity3D场景性能优化/渲染/卡顿/搭建优化 遮挡剔除/层消距离技术/LOD(多层次细节)