总图像存储大小 = width * height * bpp
1.要注意根据平台选择支持的纹理压缩格式。
如果采用一个不支持的纹理压缩格式,U3D会自动将其转换成RGBA32或RGB24格式,并且转换前的那部分内存也会保留。将消耗更多解压时间、内存。
项目中遇见的例子:在windows下,一些不是2的幂次方的纹理,在unity3d中查看的话,会多一些大小, 尺寸的改变在可接受的范围之内,但在mac下查看的时候,一个原先20k的图片,在windows下是120k左右,而在mac下,达到了1.2M。当然如果你是2的幂次方的话,unity会压缩成pvrtc格式4bits模式,会比原先小很多
所有设备对RGB 16BITS/ARGB 16BITS/RGB A16BITS/RGB 24BITS/ARGB 32BITS等支持都很好,只是这些格式算是非压缩格式,对内存消耗和渲染消耗非常不友好。
2. Unity总是自动对导入的文件进行后处理
因此,在编辑器中导入多层的PSD文件或TIFF文件,将被自动转换为JPG,在编辑器文件大小方面没有任何的区别,也不会对游戏造成影响。
纹理格式 使用 png 或 tga 时,不用转成ios 硬件支持的 PVRTC 格式,因为 Unity 在发布时会帮你自动转。
3. Generate Mip Maps 属性
开启Mipmaps可以使远离相机的物体使用较小的纹理版本,这样渲染时,显存带宽压力比较小,同时避免显示效果产生噪点(pix fight)。
使用 mipmap 存储会使运行时贴图大小变成1.33倍。
4. Read/Write Enabled 属性
开启Read/Write Enable属性,将允许从脚本(GetPixels,SetPixels和其他Texture2D函数)访问/写入纹理数据,
但,内存中会额外存储一份贴图数据,会使运行时贴图大小翻倍。所以默认关闭这个属性,在需要的时候开启。
5.Non Power of 2 属性
GUI使用非二次方纹理最好。
除GUI之外的纹理,unity推荐纹理的宽高要为2的幂次方,不然不会被压缩,它将被转化为一个非压缩的RGBA32位格式,这会占用更多的显存,并且大大降低加载速度。
对于非二次幂纹理,解决方案是
1.多个图片打成图集,只要图集为二次幂即可,通过不同UV采样来使用。
2. 在导入时在导入设置中高级纹理类型使用Non Power of 2(非二次方)选项设置缩放。Unity将按需缩放纹理,然后就可以压缩它了。
如果纹理大小不是2的幂,Non Power of 2 属性将定义在导入时的缩放行为:
- None 无
纹理将被填充到下一个较大的2的幂大小以便与GUI纹理组件使用。
- To nearest 到最近的
纹理在导入时将被缩放到最近的幂大小。例如257x511纹理将成为256x512。请注意,PVRTC格式要求纹理是正方形(宽度与高度相等),因此最终大小将变换到512x512,主要用于iPhone,iPod touch和iPad。
- To larger 到较大的
纹理在导入时将被缩放到下一个较大的幂大小。例如257x511纹理将成为512x512。
- To smaller 到较小的
纹理在导入时将被缩放到下一个较小的幂大小。例如257x511纹理将成为256x256。
6.检查 Alpha 值
如果纹理的 alpha 通道均为 1 ,则用 RGB 的 24 位纹理来代替 RGBA 的 32 位纹理。(据说Unity 内部会进行自动检测,我不确定)
7.Texture Packing 与mipmap
上文说了,可以通过多个图片打成图集,只要图集为二次幂即可压缩内存。
同时,只要每个材质使用的同样的shader, 根据 Unity 的 static batching 的特性,还可以减少draw call。
但要注意一个问题, 如果图集开启mipmap,那就是一定要将场景中距离相近的实体纹理进行拼合,否则,拼合后很可能会增加每帧渲染所需的纹理大小,加大内存带宽的负担。
这也就是为什么会出现“ DrawCall 降了,渲染速度也变慢了”的原因。
8.调整图集的大小
通过9宫格、部分缩小后Unity里在拉大等方式,来减少图集大小。
比如:(主要调整了两个小元素)就省了一半的内存。
优化前:
优化后:
9. 通过减色的方式减少图片大小。
很多UI其实使用的色彩很少,或者色彩不是渐变,用不到256色。
这类图片就可以进行减色压缩,可以在PS中操作:
10.分离透明通道
对于新安卓机型,则直接使用RGB Compressed ETC1 压缩。
对于较老的安卓机型,如果无法使用RGB Compressed ETC1 压缩,采取手动分离alpha 通道,再分别对两张贴图压缩。
其实现在机型基本都支持了,这个解决办法过时了,只是记录下来,作为留念。。
分离透明通道的原因:不止可以减少运行内存,还可以减少文件大小。
1.安卓的压缩ETC1不支持贴图的Alpha通道,但是ETC1 能够兼容广大的安卓设备,而ETC2以上的格式压缩虽然支持含Alpha通道的图片,但是支持的机型比ETC1少。
2.将Alpha通道信息拆分出来单独存储后,也有益于iOS平台上PVRTC压缩格式的表现效果
3.Alpha通道图大部分是不透明或者透明,基本是01,而 Alpha是 8位, 拆分A以后可以压缩透明贴图为1位,单独的压缩率非常高。
4.剩余下RGB通道,在Adroid平台使用ETC1压缩,在Ios平台使用PVRT压缩,均可以减至4bits
这样,我们把 RGBA的32bits压缩成了5bits
未使用ETC1压缩前的内存占用大小1024*1024的png图占用10.7M( 包含了Editor中的内存占用,以及mip map内存占用 )。
使用ETC1压缩后,场景图片一张大小只有1.3MB,加上通道图2.6M。几乎是用来的1/4。
甚至文件的大小也小了1/4。