参考
纹理压缩格式原理概述:
- 你所需要了解的几种纹理压缩格式原理
- Compressed GPU texture formats – a review and compute shader decoders – part 1
ETC1格式:ETC1压缩纹理格式详解
ETC1
将4x4像素(16RGB8位共384位,48字节)压缩为64位(8字节),压缩比6:1。
压缩后的格式:
- flipbit:1位(将4x4像素点横分还是竖分)
- diffbit:1位
- 当 diffbit 为 0 时:两个subblock的RGB均值都用4位表示(R4G4B4)
- 当 diffbit 为 1 时:subblock1的RGB均值为R5G5B5,subblock2的RGB均值为R3G3B3【这对subblock2的精度肯定并不友好】
- 两个subblock的RGB均值 baseColor :24位(R4G4B4 * 2 或 R5G5B5 + R3G3B3 )
- 每个subblock有一个行索引:2个subblock * 3位行索引 = 6位
- 每个像素有一个列索引:4x4像素 * 2位列索引 = 32位
一个解码索引表,所有贴图公用,所以不算进压缩位中
因此,4x4像素最终被压缩为
位数
=
f
l
i
p
b
i
t
+
d
i
f
f
b
i
t
+
b
a
s
e
C
o
l
o
r
+
行索引
+
列索引
=
1
+
1
+
24
+
6
+
32
=
64
位
位数 = flipbit + diffbit + baseColor + 行索引 + 列索引 \\ \quad\quad\quad = 1 + 1 + 24 + 6 + 32 = 64位
位数=flipbit+diffbit+baseColor+行索引+列索引=1+1+24+6+32=64位
格式编排:
- diffbit为0
- diffbit为1
解码过程:
f
o
r
(
i
=
[
0
,
3
]
,
j
=
[
0
,
3
]
)
{
b
l
o
c
k
I
n
d
e
x
=
像素
[
i
]
[
j
]
所在的块(
0
或
1
)
c
o
l
o
r
[
i
]
[
j
]
=
b
a
s
e
C
o
l
o
r
[
b
l
o
c
k
I
n
d
e
x
]
+
T
a
b
l
e
[
行索引
[
b
l
o
c
k
I
n
d
e
x
]
]
[
列索引
[
i
]
[
j
]
]
}
for(i=[0,3],j=[0,3])\{\\ \quad blockIndex = 像素[i][j]所在的块(0或1)\\ \quad color[i][j] = baseColor[blockIndex] + Table[\ 行索引[blockIndex]\ ] [\ 列索引[i][j]\ ]\\ \}
for(i=[0,3],j=[0,3]){blockIndex=像素[i][j]所在的块(0或1)color[i][j]=baseColor[blockIndex]+Table[ 行索引[blockIndex] ][ 列索引[i][j] ]}
编码过程:
ETC1的编码流程如下:
1、将图像划分为一系列 4X4 的子块。
2、对每个子块,尝试所有的编码可能性,取解码后和原block像素差值和最小的一种编码。
(1)是否flip,这个决定subblock如何划分
(2)每个subblock用哪一行差值表
(3)每个像素取哪一列的差值
注:决定好flip之后,颜色均值和是否能用diff方式已经确定,这个不用遍历。
3、合并所有子块编码。
不难看出,编码过程需要遍历所有可能性,其复杂度远大于解码,每一个 RGB 像素变成了一个精度较低的RGB均值和一个2位差值号,因此产生压缩。这种预测式表述自然本身就存在偏差,压缩损失亦来自于此。
Unity几种ETC纹理压缩格式:
- RGB ETC1 4 bit :4 bits/pixel,对RGB压缩比6:1,不支持Alpha,绝大部分安卓设备都支持。
- RGB ETC2 4 bit :4 bits/pixel,对RGB压缩比6:1。不支持Alpha,ETC2兼容ETC1,压缩质量可能更高,但对于色度变化大的块误差也更大,需要在OpenGL ES 3.0和OpenGL 4.3以上版本。
- RGBA ETC2 8bit :8 bits/pixel,对RGBA压缩比4:1。支持完全的透明通道,版本要求同上。
- RGB +1bit Alpha ETC2 4bit :4 bits/pixel。支持1bit的Alpha通道,也就是只支持镂空图,图片只有透明和不透明部分,没有中间的透明度。
EAC:核心原理与ETC相同,但它只用于单通道或双通道数据,OpenGL ES 3.0和OpenGL 4.3后的设备大部分支持,但由于安卓平台五花八门的兼容性,一般不建议用单双通道贴图。
DXT
一般用于Window平台
PVRTC
一般只被用于苹果
ASTC
https://niepp.github.io/2021/12/18/Compute-ASTC.html
https://docs.unity3d.com/Manual/class-TextureImporterOverride.html