纹理压缩是为了解决内存、带宽问题,专为在计算机图形渲染系统中存储纹理而使用的图像压缩技术。
常见纹理格式(黄色为常用格式)
压缩比算法:https://www.cnblogs.com/bylle/p/12212823.html
公式
像素大小 = 16-bytes / 分块宽高 * 8-bit;
压缩率 = 原始像素大小(32-bit) / 像素块大小;
图像大小 = 原始图片大小 / 压缩率;
假设一张4MB的1024*1024原始图片:
块宽高 |
像素大小(bits) |
压缩率 |
压缩后图片大小 |
4*4 |
8 |
4 |
1MB |
5*5 |
5.12 |
6.25 |
655KB |
8*8 |
2 |
16 |
256KB |
10*10 |
1.28 |
25 |
163KB |
12*12 |
0.89 |
35.95 |
113.93KB |
DXTC纹理压缩格式来源于S3公司提出的S3TC算法,基本思想是把4x4的像素块压缩成一个64或128位的数据块,优点创建了一个固定大小且独立编码片段,没有共享查找表或其他依赖关系,简化了解码过程。
参考链接:DXT纹理压缩-CSDN博客
个人理解:简单来说就是有两个极端颜色C0,C1,
,通过类似线性插值或者别的插值方式算出若干个颜色值C2、C3等。然后通过索引表进行颜色组合
,譬如C0对应01,C1对应00,C2对应10,C3对应11,然后进行填充。
二区和三区Tile的前八个分区集
二区Tile的BC6H/BC7块解码的简化例子
ETC(爱立信纹理压缩)格式最初是为了在移动设备中使用而开发的。今天,它是基于Android的设备的标准压缩方案。ETC1格式通过和WEBGL_compressed_texture_etc1扩展在OpenGL ES和WebGL中被支持。自OpenGL 4.3以来,ETC1和ETC2规范是OpenGL核心配置文件的一部分。
该压缩方案的第一个版本PACKMAN于2004年推出。后来,在2005年提出了名为iPACKMAN的增强版。这个版本更被称为ETC1,被广泛用于移动设备。这个压缩方案的后续发展导致了2007年ETC2格式的出现。
PACKMAN的核心思想
ETC压缩的主要思想是基于一个众所周知的色彩感知事实,即人眼对亮度而不是色度更敏感。因此,每个子块中只存储一种基色(ETC1/ETC2包括两个子块),但亮度信息是以每个顶点为基础存储的。亮度偏移是由一个单一的整数值来设定的,它被加到所有的颜色成分上。一个子块内只有四个不同的亮度偏移,所以只有四种不同的颜色可用。这些颜色可以被看作是一个局部调色板。
如果一个压缩块所占的位数与总线宽度相同,那么就可以避免流水线停顿,从而简化了硬件实现。由于移动设备在内存大小和总线宽度方面受到严格限制,因此考虑在PACKMAN中使用2x4瓦片。结果是,压缩块只占用32位。因此,压缩级别为4bpp,与BC1的压缩级别相当。
一个块中只存储一种RGB444基色。其他颜色是通过改变文本的亮度获得的。虽然基本思路与BC1相去甚远,但解码过程却非常相似。首先,四色局部调色板被恢复。然后,索引表被用来从这个调色板中挑选颜色见下图。然而,由于块的大小较小,只有4位用于指定亮度变化和调色板中的三种额外颜色。因此,这4位被用来对预定的亮度集之一进行编码。
PACKMAN块解码示例
Index |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
Luminance 00 |
2 |
4 |
6 |
12 |
8 |
19 |
28 |
42 |
Luminance 01 |
8 |
12 |
31 |
34 |
50 |
47 |
80 |
127 |
Luminance 10 |
-2 |
-4 |
-6 |
-12 |
-8 |
-19 |
-28 |
-42 |
Luminance 11 |
-8 |
-12 |
-31 |
-34 |
-50 |
-47 |
-80 |
-127 |
用于PACKMAN的亮度编码本的前半部分
显然,表的下半部分是上半部分的negation ,简化了解码器。亮度集8-15(未在表中显示)等于0-7集的缩放系数为2。表中的数值是通过从随机数值开始,然后通过最小化测试图像(3)的误差来优化它们。
单一的低精度(RGB444)基色是PACKMAN的主要质量限制因素。这个问题在ETC1中得到了解决。
ETC1 Tile的大小为4x4,它由两个子块组成,就像PACKMAN块一样。这些子块可以垂直或水平排列。这为Tile内的基础颜色选择提供了更大的灵活性。通过引入差分块类型来提高精度,其中第一个子块的基色以RGB555的精度存储,第二个基色则存储3位差分。一个块,其中两个基色都直接以RGB444格式存储,被称为个体。
为了给块型编码保留空间,亮度编码簿被减少到8组,因此索引大小(图中的T0和T1)下降到3比特。很明显,编码本中的数值也被重新计算了(见表)。 这就释放了2个比特。其中一个 "diff "指定了块类型,另一个 "flip "指定了子块的垂直或水平排列。
ETC2是ETC1的扩展,支持了Alpha通道的压缩,硬件要求OpenGL ES 3.0和OpenGL 4.3以上;
PVRTC (PowerVR Texture Compression)由Imagination公司专为PowerVR显卡核心设计,由于专利原因一般它只被用于苹果的设备,仅Iphone、Ipad和部分PowerVR的安卓机支持。这可能是这几种压缩格式中最不公开的技术。
PVRTC不同于DXT和ETC这类基于块的算法,而将整张纹理分为了高频信号和低频信号,低频信号由两张低分辨率的图像A和B表示,这两张图在两个维度上都缩小了4倍,高频信号则是全分辨率但低精度的调制图像M,M记录了每个像素混合的权重。要解码时,A和B图像经过双线性插值(bilinearly)宽高放大4倍,然后与M图上的权重进行混合。
PVRTC 4-bpp模式下,每4x4像素占一个64位数据块,2-bpp模式下每8x4像素会有一个64位数据块。两者大同小异,我们仅说4-bpp模式。
4-bpp模式下,A和B图缩小后都只保存一个颜色值,如下图所示,A图比B图少1位,但两张图都可以选择以RGB或ARGB的方式存储(最高位决定为哪种),A色可以用RGB554或ARGB3443格式编码,B色可以用RGB555或ARGB3444格式编码。
在解码时,为了解码任意像素,必须读取4个相邻的PVRTC块,使用这4个块来解码一个5x5块。
使用双线性过滤来对A和B图进行扩大,然后A和B图根据M图与“Mode”位进行混合,这里的"Mode"位为1时,M图中10值像素被看作是开启了"punch-through alpha",alpha通道会被强制清零,这种神奇的操作是为了兼容旧应用程序,具体就不说了。
单从4bpp模式来看,PVRTC和BC、ETC非常相似,都有两个颜色值,但基本思想却是不同的。
Unity几种PVRTC的纹理压缩格式:
苹果的所有移动设备都支持PVRTC。
PVRTC2质量比PVRTC更高,而且支持NPOT(非2次幂纹理),是PVRTC的升级版,。
PVRTC和PVRTC2都支持4-bpp和2-bpp的ARGB格式。
RGB PVRTC 4 bit :4 bits/pixel,对RGB压缩比6:1,安卓设备需要PowerVR Series 5以上。
RGBA PVRTC 4 bit :4 bits/pixel,对RGBA压缩比8:1,3位Alpha值,设备同上。
RGB PVRTC 2 bit :2 bits/pixel,对RGB压缩比6:1,安卓和IOS设备需要PowerVR Series 5X以上。
RGBA PVRTC 2 bit :2 bits/pixel,对RGBA压缩比8:1,3位Alpha值,设备同上。
ASTC(自适应可扩展纹理压缩)是由ARM和AMD联合开发的,并在2012年提出。格式规范被Khronos联盟批准并在OpenGL中采用。适当的OpenGL和OpenGL ES扩展被称为KHR_texture_compression_astc_hdr 。从Mali-T628和Mali-T678开始,所有ARM图形核心都有ASTC硬件支持。专利属于ARM。然而,ASTC是完全开放和免版税的格式。
一个新的压缩方案是在考虑了所有这些要求后开发的。ASTC格式有一个固定大小的128位块。然而,对于2D纹理来说,编码的Tile尺寸从4x4到12x12 texels不等,对于3D纹理来说,从3x3x3到6x6x6不等。所有支持的Tile尺寸和相应的比特率可以在上表中找到。增量 "一栏显示,比特率可以以非常细的步骤扩展。在ASTC规范中,Tile尺寸也被称为块足迹。
ASTC是我们文章中描述的最灵活的格式,因为它也支持LDR、HDR、2D和3D纹理,最多有4个组件。它甚至支持低于1bpp的比特率。
从概念上讲,ASTC与S3TC/BC7类似:一个压缩块中最多存储四个端点对和插值权重,只支持预定义的分区,特定的分区由分区ID指定,也存储在一个块中。在弱相关的情况下,独立的索引表被存储在该通道中。每个独立的编码被称为一个平面。
也许,最主要和最有趣的ASTC创新是用小数位对整数值进行编码的技术,称为BISE。同时,BISE可以在硬件中有效实现。
参考链接:ASTC纹理压缩格式详解
画质比较
RGBA > ASTC 4×4 > ASTC 6×6 > ETC2 ≈ ETC1
PC:
① 低质量使用DXT1格式不支持A通道,使用DXT5格式支持A通道;
② 高质量使用BC7格式,支持A通道;
安卓:
① 低质量使用ETC1格式,但不支持A通道;
② 低质量使用ETC2格式,支持A通道,需要在OpenGL ES 3.0/OpenGL 4.3以上版本;
③ 高质量使用ASTC格式,需要在Android 5.0/OpenGL ES 3.1以上版本;
IOS:
① 高质量使用ASTC格式,需要Iphone6以上版本;
② 低质量使用PVRTC2格式,支持Iphone6以下版本;
英伟达和Unity官方对于不同类型贴图给出了不同的压缩方案建议:
Using ASTC Texture Compression for Game Assets | NVIDIA Developer
Unity - Manual: Recommended, default, and supported texture formats, by platform
参考链接:
http://sv-journal.org/2014-1/06/en/index.php?lang=en#5-1
你所需要了解的几种纹理压缩格式原理 - 知乎
ASTC纹理压缩格式详解 - 知乎
Using ASTC Texture Compression for Game Assets | NVIDIA Developer
Unity - Manual: Recommended, default, and supported texture formats, by platform