1.动画资源的Compression
可以看一下动画曲线保存方式,总得来说,Optimal就是让Unity自动选择最优的曲线表达方式,从而占用最小的存储空间。
2.动画资源的精度过高
如何降低动画文件的浮点数精度,不过这里的后处理操作是修改导入后的资源,fbx本身没有修改,在编辑器运行时可能会生效,但是实际打包出来效果如何不知道。为什么修改资源不改fbx的话是无效的?主要还是因为修改后的资源是放在本地的library里,是一个本地化的操作,其他人在导入的时候还是按照fbx资源进行生成GameObject的(包括关闭Unity重新打开之后)。
3.双声道的音频
音频源文件为双声道且没有开启Force To Mono。在Android设备上,双声道音频意义不大,但是会占用双倍内存,建议使用单声道。音频优化技巧
4.包含空纹理采样的材质
我们在编写Shader时,会声明一些贴图进行计算。但在使用该Shader创建Material实例时,可能并不需要这些纹理,或者因为疏忽忘记对材质添加纹理,那么Unity会为材质赋予一个默认的“纹理”。这个情况虽然不会对计算结果和显示效果造成影响,但是Unity依然会对它进行相关的计算,从而产生性能上的消耗。
删除或注释掉相关的纹理声明,从而避免Unity进行不必要的计算,减轻GPU的压力;同时也能对那些原本预定添加纹理的材质进行判断,进一步优化材质的结构。
1 2 |
//shader内使用: _DistortMap("DistortMap", 2D) = "white" {} |
5.包含相同纹理采样的材质
在Unity中,纹理(Texture)和材质(Material)不是“一对一”的关系,一个材质内可以包含多个纹理,只需要在相应的Shader中进行声明即可。
在实际开发过程中,或是因为疏忽,或是因为特殊的计算需求,开发团队可能会在材质内对同一个纹理进行多次引用,或者说在多个“槽位”上放置同一个纹理,如图所示:
当然这种情况不是普遍现象,如果有特殊需求,要对同一个纹理进行不同方式地采样运算,或者采集不同的部分,那么对该纹理使用多个不同的引用,也无大碍,不会浪费运算资源;但是如果因为疏忽而对同一纹理进行了多次相同运算,那无疑会增加没有必要的GPU压力。
6.包含纯色纹理采样的材质
上图中的纯色纹理其实可以使用一个Color来替代,从而避免实体纹理造成的内存占用,减轻GPU对纹理进行采样的开销,以更高效的处理方式达到同等效果。
1 |
_Color("MyColor", Color) = (1, 0.5, 0.2, 1) |
7.包含无用纹理采样的材质
材质上冗余贴图怎么办?
旧的Shader使用过的texture引用会被保留在序列化信息中(不只是material,所有的Unity序列化之后的物体都有这个特性,包括GameObject),这是Unity有意的设计,为了避免编辑器下切换Shader再换回来时需要重新配置的麻烦。而Unity在打包时确实会对材质进行深度检查,把当前Shader没有使用的texture依赖都去除,因此通常情况下打包旧的引用也不会导致包体变大。
但旧的引用在Editor下还存在一个问题:AssetDatabase.GetDependencies接口返回的引用会包括旧的引用,它不会进行深度检测来进行剔除。右键资源Select Dependencies调用的是这个接口,所以也会显示旧的引用,如下图:
pic2和pic3是当前Shader2没有引用的。
所以使用GetDependencies这个接口实现一些功能的话,可能由于旧引用导致意外的问题。解决方法是,使用EditorUtility.CollectDependencies这个接口可以返回剔除旧引用的结果。
此外,如果Mat和Pic1,Pic2,Pic3分配别单独打了一个AB包,那么打出的mat.manifest文件中会显示旧的Texture引用,这就是AssetBundle打包的一个不太合理的地方了,还没有调研新的Addressable系统是否做了改进。
8.模型的顶点色/切线/法线信息
在一些建模软件中导出的模型可能会带有顶点的颜色/法线/切线属性,在Unity中即表现为Mesh的Colors/
Tangent/Normal属性。有些Shader可以使用这些属性进行运算与着色,如Sprites Shader。然而大多数Shader都选择忽略这些属性(Unity标准着色器就不使用这些属性)。在这种情况下,如果Mesh带有这些属性,那么对其本身而言没有实际意义,却会对内存、物理体积和加载性能造成影响。
前面在动画精度里我们已经知道,Unity内使用的GameObject都是根据FBX模型文件生成到Library目录下的临时资源。而模型的顶点色、法线和切线数据都是存放在FBX文件中的,我们只修改生成后的文件肯定治标不治本,但是还好AutoDesk提供了相关SDK可以修改FBX文件:如何修改FBX文件
还有一个要注意的是即使FBX内没有了法线和切线信息,Unity有可能还是会自动为模型生成一套法线和切线信息,具体的设置就在模型的ImportSetting内
9.开启Read/Write的模型
Read/Write 选项启用后,将会允许从脚本来访问网格数据,同时会产生网格数据的副本,占用额外内存,等同于一个网格数据会有接近2倍的内存消耗。对于需要使用StaticBatchingUtility.Combine进行合批的Mesh,以及部分Unity版本中粒子系统里使用到的Mesh,仍需要开启Mesh的Read/Write选项。
关于Read/Write选项
10.shader变体
11.图片优化:透明通道、纯色纹理、纹理的Read/Write选项、尺寸过大的纹理、透明区域过多的纹理
透明通道、纹理的Read/Write选项
尺寸过大的纹理、纯色纹理
透明区域过多的纹理:贴图中alpha为0的区域占比过大,建议减少贴图大小以充分运用贴图区域。