纹理压缩
颜色通道
RGBA32代表四个通道总32bit,每个通道占8bit
RGBA16,每个通道占4bit
纹理压缩格式
JPG:一种有损压缩不透明图片格式
PNG:一种无损压缩透明图片格式
Unity导入图片格式后,都会先转化成纹理格式。只有纹理格式才能被GPU解压和使用。
纹理压缩格式的选择
Unity纹理详解:
Unity - Manual: Recommended, default, and supported texture formats, by platform (unity3d.com)
Unity提供Crunched DXT和Crunched ETC纹理格式,它们在原来的纹理压缩格式的基础上又使用Crunch压缩了一遍(也就是下面的BC6,BC7)。
PC建议使用二次压缩。在一张贴图的导入设置面板中的Default选项卡中,勾选“Use Crunch Compression”。Android和iOS选择ASTC。
如果是某些不得不清晰显示的大图,建议选择不压缩RGBA32等。而某些时候有些大图不需要清晰显示,但是又不是2的整数次幂的样式,可以单独打一张图集。
PC端
对于具有DirectX 11或更好级别GPU的设备,在保证支持BC7和BC6H格式的情况下,建议选择的压缩格式为:RGB Texture-DXT1,4 bits/像素。RGBA Texture-BC7(质量更高,压缩速度较慢)或DXT5(压缩速度更快),均为8bits/像素。HDR Texture-BC6H,8bits/像素。如果您需要在PC上支持DirectX 10类GPU(2010年之前的NVIDIA GPU,2009年之前的AMD,2012年之前的Intel),则首选DXT5而不是BC7,因为这些GPU既不支持BC7也不支持BC6H。
iOS和TVOS
对于使用A8芯片(2014)或更高版本的苹果设备,ASTC是RGB和RGBA纹理的推荐纹理格式。此格式允许您在纹理质量和粒度级别的大小之间进行选择:从8bits/像素(4x4块大小)一直到0.89bits/像素,(12x12块大小)。如果需要对旧设备的支持,或者你想要额外的Crunch压缩,那么苹果设备从A7芯片(2013)开始支持ETC/ETC2格式。对于更旧的设备,PVRTC是要使用的格式。在iOS上
可以在“Player Setting”中配置默认纹理格式,PVRTC为您提供尽可能广泛的兼容性。ASTC是首选,但在A7设备(第一个支持Metal的设备)上不受支持,并且将在运行时解包。
Android
Android上的纹理格式支持很复杂。您可能需要构建具有不同子目标的多个应用程序版本。
您可以在Player Setting中选择默认格式。您的选项是ASTC、ETC2和ETC(ETC1表示RGB,ETC2表示RGBA)。
对于LDR RGB和RGBA纹理,大多数支持OpenGL ES 3.1或Vulkan的现代Android GPU也支持ASTC格式,包括:自Adreno 4xx/Snapdragon 415(2015)以来的高通GPU、自Mali T624(2012)以来的ARM GPU、自Tegra K1(2014)以来的NVIDIA GPU、自GX6250(2014)起的PowerVR GPU。
如果您需要对旧设备的支持,或者需要额外的Crunch压缩,那么所有运行Vulkan或OpenGL ES 3.0的GPU都支持ETC2格式。生成的图像质量相当高,并且它支持一到四个分量的纹理数据。OpenGL ES 2设备不支持ETC2格式,因此Unity在运行时将纹理解压缩为ETC2回退指定的格式。对于更旧的设备,通常只有ETC格式可用。缺点是没有直接的alpha通道支持。ETC2(RGBA模式)所占的内存是ETC1的一倍,ETC2还有RGB模式,和ETC1区别不大。
对于Sprite,Unity通过将纹理拆分为两个ETC1纹理来提供使用ETC1压缩的选项:一个用于RGB,一个用于alpha。若要启用此功能,请在导入Sprite Atlas时为纹理启用Android特定的“Split Alpha Channel”选项,精灵着色器对两个纹理进行采样,并将它们组合为最终结果。
对于HDR纹理,ASTC HDR是Android设备上唯一可用的压缩格式。ASTC HDR需要Vulkan或GL_KHR_texture_compression_ASTC_HDR支持。ASTC是最灵活的格式。如果设备不支持ASTC HDR,则纹理将在运行时解压缩为RGB9e5或RGBA Half,具体取决于alpha通道的使用情况。
对于不支持ASTC HDR的设备,所有运行Vulkan、Metal或OpenGL ES 3.0的设备都支持RGB9e5,这适用于没有alpha通道的纹理。如果需要alpha通道或更广泛的支持,请使用RGBA Half。这占用的内存是RGB9e5的两倍。
纹理大小计算
以RGBA32为例,它每个像素占32bit,也就是4byte,一个1024像素 x 1024像素大小的图片,占用的大小就是1024 x 1024 x 4 = 4MB。
以ASTC 4x4 blocks为例,它指的是每4 x 4像素的一块区域占16byte(整个区域内使用优化算法显示颜色),换算下来每个像素占1byte,一个1024像素 x 1024像素大小的图片,占用的大小就是1024 x 1024 x 1 = 1MB。
纹理图片要求
ETC
ETC要求纹理图片的宽和高都是4的倍数,并且宽高都是2的整数次幂,也就是POT Texture
PVRTC
PVRTC要求纹理图片宽高都是2的整数次幂,也就是POT Texture,并且宽和高要相同
图片分离通道
上面讲过,如果使用Android时必需使用ETC1来压缩透明纹理,Unity会把纹理分成两张图,一张颜色信息一张透明度信息。
要想这样使用,需要先打开Project Settings——Graphic,然后将“Always Included Shaders——Size”指定为7,添加一个“UI/DefaultETC1”Shader。这样UI中使用ETC1来压缩的透明纹理就不会出问题。
然后再在相应纹理的导入设置中,下面选项卡选择安卓图标,然后勾选“Override for Android”,在format中选一个ETC的格式,就会出现“Split Alpha Channel”,勾选然后Apply即可分离。
在现代手机机型大部分已经支持ETC2和ASTC了,并不需要这样分离UI了。