Android打包apk大小约:475M
查看打包日志:Console→Open Editor Log;
或者依赖第三方插件:build reports tool(在unity store里可以下载);
定位问题
经过排查后,发现项目中纹理占比很高(82.8%),而且美术说图片从tga换成了更小的png,包体理应会变小,但是替换后并没有变化,甚至还大了3M,就开始查一下是什么原因;
找了一张较大的贴图测试,在资源管理器中大小为0.7M,但是在Unity中却变成了5.3M,经查证后得出结论,图片进入unity后会根据一定格式进行压缩,导致两方大小不一致:
-
贴图导入unity后会自动设置成压缩格式,它会先判断贴图是否有透明通道。
-
Android:不带透明通道压缩成ETC1,带透明通道压缩成ETC2,不被4整除的回退到RGBA32
-
IOS: 不带透明通道压缩成RGB PVRTC,带透明通道压缩成RGBA PVRTC ,不是2的整数次幂回退到RGBA32
-
所以,最终编译入包的大小和图片本身格式、大小关系都不大,而是取决于限制分辨率下的信息复杂度。
经排查后发现,这个项目中纹理大多是RGB16、RGBA 16、RGB32、RGBA32、ETC、ETC 2格式压缩的,而且很多贴图的size用的都是2048、4096,这太浪费了,导致纹理占比这么大。
解决方案
一:压缩方式换成ASTC
找出影响较大的图片,将压缩格式改为ASTC。
ASTC是在OpenGL ES3.0出现后在2012年中产生的一种业界领先的纹理压缩格式,它的压缩分块从4x4到12x12最终可以压缩到每个像素占用1bit以下,压缩比例有多种可选。ASTC格式支持RGBA,且适用于2的幂次方长宽等比尺寸和无尺寸要求的NPOT(非2的幂次方)纹理。
经测试,最后使用的ASTC方式:
(1)法线贴图:4x4即可,避免丢失过多数据
(2)细节处的贴图:大部分6x6,并没发现明显失真;一小部分追求细节的图片用的4x4
(3)一般的贴图:选择6x6或8x8
(4)无关紧要,但是尺寸特别大的图:可以考虑8x8,10x10,12x12,不然打包出来太大
(5)Sprite(UI):6x6即可
适配机型
iOS
苹果从A8处理器开始支持 ASTC,iPhone6(包含)、iPad mini 4(包含)以上iOS设备支持,2014年的iPhone 5s及iPad mini 3以前的设备不支持。
安卓
安卓主流压缩格式正在从ETC2转向ASTC,Unity官方对ASTC格式支持的说明( 跳转官方文档 )中提到GPU对ASTC的支持情况:所有支持OpenGL ES 3.1和部分支持OpenGL ES 3.0的GPU(截止到2021年GooglePlay上统计的支持ASTC的设备已有77%,国内可能更高,个人角度看ASTC压缩格式是可以普及使用的。)
二:修改图片 Size
项目中贴图的size基本都是2048的,一张就好几兆
但实际上移动平台并不用这么大就可以,改成了1024,经测试后发现,大部分图片都可以,有几张模糊的再改成2048即可。
优化后打出的apk大小:352M,这只是针对较大的纹理做出的处理,如果统一优化一下效果会更好。
结论
- 尽量让美术出的图使用2的幂大小,以便于提高性能节省内存。否则平台或GPU不支持NPOT纹理带,Unity会对纹理进行缩放和填充已达到下一个2的幂的大小。
- 纹理压缩方式可根据情况,改用ASTC压缩。
- 减小 Max Size,视觉上可接受的结果的最低设置,可以更快的降低纹理内存。
- 对于法线贴图,ETC2 4bits的压缩效果比ASTC 5x5好;而有透明通道的贴图,ETC2 8 Bits比ASTC 4x4更优的情况,根据实际情况进行选择;
- 制作纹理图集 :将多个纹理放置到单个纹理中,可以减少绘制调用和加快渲染速度。使用 Unity 精灵图集 或第三方 Texture Packer 可以制作纹理图集。
- 关闭 Read/Write Enabled 选项 :如果启用,此选项在 CPU 和 GPU 可寻址内存中都会创建副本,纹理会占用双倍内存。大多数情况下,应保持此选项为禁用状态。如果要在运行时生成纹理,请通过 Texture2D.Apply 强制执行,并且传入设置为 true 的 makeNoLongerReadable。
- 禁用不必要的 Mip Map :对于在屏幕上大小保持不变的纹理(如 2D 精灵和 UI 图形),Mip Map 不是必需的,对于与摄像机的距离会变化的 3D 模型,请保留 Mip Map为启用状态。
相关资料:
unity 纹理压缩格式
ASTC纹理压缩格式详解
游戏中的纹理压缩格式