转自uwa学堂 https://edu.uwa4d.com/lesson-detail/84/143/0
1 | 纹理格式的选择
界面打开慢可分为首次打开慢和再次打开慢,首次打开慢一般是由于需要加载过多的UI资源。而再次打开慢就是程序不合理造成的了。首次界面打开加载的资源(如:贴图)会被缓存在内存中,这样再次打开界面由于内存中已经有了资源(如:贴图)所以会更快。作为界面优化,我们应当尽可能地让首次打开得更快。
图片是否都进行了有效压缩,Android平台下不带透明通道优先使用ETC1,而带透明通道的优先使用ETC2,如果显示质量无法达到要求还可以使用RGBA16,最后才使用RGBA32,总体来说正确使用优先顺序是ETC1>ETC2->RGBA16->RGBA32,另外针对Android平台Unity还实现了一套Crunched压缩方式,比如RGBA Crunched ETC2压缩格式,会先用ETC2进行压缩,然后再用Crunched压缩一遍。虽然运行时逻辑上需要再额外解压缩一遍,但是由于Crunched压缩会让贴图大小更小,加载的时间会比单纯加载ETC2快很多。总体来说RGBA Crunched ETC2会比ETC2加载更快,而且包体会更小。
IOS平台下优先使用PVRTC,其次使用ASTC。不带透明通道可以使用ASTC 5X5(表示每个压缩块的大小是5 X 5=25),带透明通道可以使用 ASTC 4X4(表示每个压缩块的大小是4 X 4=16) 。如果显示质量无法达到要求还可以使用RGBA16,最后才使用RGBA32,总体来说正确的使用优先级顺序是PVRTC>ASTC->RGBA16->RGBA32。
以一张1024X1024的贴图为例:
RGBA32 Bit:表示每个像素占用32位4字节,内存大小 1024 X 1024 X 4 = 4M
RGBA16 Bit:表示每个像素占用16位2字节,内存大小 1024 X 1024 X 2= 2M
RGB ETC1 4Bit: 表示每个像素占用4位0.5字节,内存大小 1024 X 1024 X 0.5= 0.5M
RGBA ETC2 8Bit: 表示每个像素占用8位1字节,内存大小 1024 X 1024 X 1= 1M
RGBA PVRTC 4Bit: 表示每个像素占用4位0.5字节,内存大小 1024 X 1024 X 0.5= 0.5M
RGBA ASTC 4X4 : 表示每个像素占用8位1字节,内存大小 1024 X 1024 X 1= 1M
很显然占用内存越小的贴图,加载速度肯定就越快,那么打开这样的界面无疑也就越快了。不过ETC2和ASTC虽然对半透明的效果支持得很好,但是它对贴图的尺寸有一些限制。ETC1、ETC2以及ASTC 4X4 要求图片宽和高可以不相等但是必须被4整除,例如512X1024 4X16(突然想起以前有个美术妹子问我被4整除的图片尺寸是什么?我无奈地告诉她打开计算器用你做的图片的宽和高分别除以4,只要出现了小数就表示没有被4整除 - - !)。 IOS的PVRTC压缩格式要求图片的宽高必须相等并且是2的整数次幂,例如512X512,如果是512X1024那么就无法压缩了。另外ETC2和ASTC 对硬件也有一些限制,ETC2只支持OpenGL ES 3.0以上的Android手机(大概2013年以后的手机都支持)ASTC只支持苹果A8以后的设备,iPhone 6 及以上的手机(大概2014年以后的手机都支持)。今天已经2019年了,我个人觉得没必要为了支持这些4、5 年以前的设备让开发变得非常麻烦。
正确地在Unity中设置压缩贴图,如图1-1所示。点开Default页面,Compression选择压缩格式,Use Crunch Compression表示是否开启二次Crunch压缩,表示它会自动对Android平台和IOS平台自动选择压缩格式。
1-1 压缩贴图
如图1-2所示,Android平台被自动选择了RGB Crunched ETC压缩格式,因为这张图是不带透明通道的,如果有透明通道Unity会设置成 RGBA Crunched ETC2,看来Unity还是挺聪明的。
1-2 Android压缩格式
如图1-3所示,IOS平台被自动选择了RGB Compressed PVRTC 4 Bits,我们知道PVRTC压缩的效果是比较差的,尤其是有透明通道的UI几乎是无法接受的。
1-3 IOS压缩格式
自动设置的压缩格式有时可能无法灵活的满足需求,最好可以在自动设置后的基础上又可以灵活地修改。如图1-4所示,勾选Override for IOS后(任意平台都可以这样覆盖它的设置)Format处选择一个需要的贴图压缩格式即可。
1-4 IOS修改压缩格式
实际游戏中可能有很多图片,每个都手动设置确实太费劲了,如下代码所示,我们可以通过自动化的方式批量设置每个贴图的压缩格式。
Using UnityEditor;
public class TextureImport : AssetPostprocessor
{
void OnPreprocessTexture()
{
//判断贴图导出的路径,设置正确的压缩格式
if (assetPath.Contains("Assets"))
{
TextureImporter textureImporter = AssetImporter.GetAtPath(assetPath) as TextureImporter;
//设置各平台的压缩格式
TextureImporterPlatformSettings settings = new TextureImporterPlatformSettings();
settings.overridden = true;
settings.name = "iPhone";
settings.format = TextureImporterFormat.ASTC_RGBA_4x4;
textureImporter.SetPlatformTextureSettings(settings);
}
}
}