介绍
要弄明白这些问题,首先要简单解释一下贴图压缩格式的基础概念。
为了让贴图在手机中运行时占用尽可能少的内存,需要设置贴图的压缩格式,目前 Unity 支持的主要压缩格式有:android 上的 ETC/ETC2,iOS 上的 PVRTC,以及未来可能会使用的 ASTC。这几个压缩格式有自己的特点:
-
ETC:不支持透明通道,被所有 android 设备支持 -
ETC2:支持透明通道,Android 设备的 GPU 必须支持 OpenGL es 3.0 才可以使用,对于不支持的设备,会以未压缩的形式存在内存中,占用更多内存 -
PVRTC:所有苹果设备都可以使用,要求压缩纹理长宽相等,且是 2 的幂次(POT,Power of 2) -
ASTC:高质量低内存占用,未来可能普遍使用的压缩格式,现在有一部分机型不支持
一般来说,目前 Unity 的手机游戏 android 上非透明贴图会使用 RGB Compressed ETC 4bits,透明贴图可以使用 RGBA Compressed ETC2 8bit,iOS 非透明贴图使用 RGB Compressed PVRTC 4bits,透明贴图使用 RGBA Compressed PVRTC 4bits。
这里的 bits 概念的意思为:每个像素占用的比特数,举个例子,RGB Compressed PVRTC 4bits 格式的 1024x1024 的贴图,其在内存中占用的大小 = 1024x1024x4 (比特) = 4M (比特) = 0.5M (字节)。 1bit = 1/8 Byte
我们可以看到,在 iOS 上,非透明贴图和透明贴图都是 4bpp(4bits per pixel)的,多了透明通道还是一样的大小,自然 4bpp 的透明贴图压缩出来效果就会变差,而实机上看确实也是惨不忍睹。这是第一个问题的答案。
一些古早的 android 机,由于不支持 OpenGL es 3.0,因此 RGBA Compressed ETC2 8bit 的贴图一般会以 RGBA 32bits 的格式存在于内存中,这样内存占用就会达到原来的 4 倍,在老机器低内存的情况下系统杀掉也不足为奇了。这是第二个问题的答案。当然,需要说明的是,现在不支持 OpenGL es 3.0 的机器的市场占有率已经相当低了(低于 1%),大多数情况下可以考虑无视。
更多的贴图压缩格式相关内容可以参考这里:https://zhuanlan.zhihu.com/p/113366420
项目使用
目前我们项目android是使用ETC2,因为绝大多数手机已经支持OpenGL ES3.0。但是图片要求4的倍数。
IOS上使用ASTC格式。虽然PVRTC占内存更小,但是要求宽高一样,并且是POT图片。
大小计算
以一个1024*1024图片为例: RGBA32 一个像素就是32位 (每一个通道占用8位),而我们知道 8位 = 1字节,即1位 = 1/8字节 1024B = 1kb 1024 * 1024 = 1Mb 1024 * 1024 * 32 *(1/8) = 4M
ETC2 8bit 一个像素占用的8位, 就是1个字节,1024字节1024字节=1M 10241024 * 8 / 8 = 1M
4 * 4 block 意思是宽4和高4的一个像素块占1个block块 1 block = 16字节 表明一像素就是1字节 1024*1024的图片就是1M
|