关于unity:你所需要了解的几种纹理压缩格式原理

5次阅读

共计 5991 个字符,预计需要花费 15 分钟才能阅读完成。

本文基于材料收集,概括了几种纹理压缩格局的根本思维,心愿对于学习有所帮忙。

为什么咱们须要纹理压缩格局?

例如 R5G6B5、A4R4G4B4、A1R5G5B5、R8G8B8 或 A8R8G8B8 等未经压缩的图片格式,是可能被 GPU 间接读取的原生纹理格局。但在低端硬件设施或者说挪动平台下,有两个问题须要解决。

一个是 内存,例如 A8R8G8B8 格局中一个像素占 4 字节,如果是 512×512 分辨率内存就占用 512x512x4 B=1048576 B=1 MB,这种内存耗费在低端设施上根本无法承受。

另一个重要的是数据传输时的 带宽,带宽是发热的首恶,在渲染 3D 场景时,会有大量的贴图被传输到 GPU,若不限度,总线带宽很快就会成为瓶颈,手机秒变暖手宝,重大的还会影响渲染性能。

因而咱们须要一种内存占用既小又能被 GPU 读取的格局——压缩纹理格局。纹理压缩对应的算法是以某种模式的固定速率有损向量量化(Lossy Vector Quantization)将固定大小的像素块编码进固定大小的字节块中。

有损 示意对于渲染来说,有损压缩是能够承受的,个别抉择压缩格局时须要在纹理品质和文件大小上寻求一个均衡。

固定速率压缩 指的是什么呢?因为 GPU 须要可能高效的随机拜访一个像素,这意味着对任意像素,解码速度不该有太大的变动。因而,咱们常见的贴图压缩算法都是有损压缩。相同的例如 zip 则是一种可变速率压缩。

向量量化(Vector Quantization,VQ)是一种量化技术,将一组大量的点(向量)分成具备近似雷同数量的最靠近它们的点的组。每个组用它的质心点示意,因而存在数据误差,实用于有损压缩。放到纹理压缩中来了解,就例如将 4 ×4 块像素的色彩以 2 个基色来示意。

编码和解码速度:一般来说编码速度慢没关系,因为通常纹理压缩只须要在游戏打包时进行一次,对于用户运行时体验齐全没有影响。但解码速度必须足够快,而且基本上不能影响到渲染性能。

压缩比:通常以比特率或每像素的均匀比特数(bits per pixel,bpp)示意,常见的为 2~8bpp。个别 RGB 原生纹理的像素指 24 位,4bpp 示意每像素占 4 位,所以也能够认为 4bpp 示意压缩比为 6:1。

顺便一提,在 Unity 中,任何图片文件格式都存在一个导入过程,导入后的文件格式都是 Texture2D,在 Texture2D 的导入设置选项中须要针对不同平台设置纹理压缩格局。

为什么咱们不应用 png、jpg 这类常见的压缩格局?

只管像 jpg、png 的压缩率很高,但并不适宜纹理,次要问题是不反对像素的随机拜访,这对 GPU 相当不敌对,GPU 渲染时只应用须要的纹理局部,咱们总不可能为了拜访某个像素去解码整张纹理吧?不晓得程序,也不确定相邻的三角形是否在纹理上采样也相邻,很难有优化。这类格局更适宜下载传输以及缩小磁盘空间而应用。

常见纹理压缩格局
ETC
ETC(Ericsson Texture Compression)最后为挪动设施开发,现在它是安卓的规范压缩计划,ETC1 在 OpenGL 和 OpenGL ES 中都有反对。

其原理简略来说,是将 4 ×4 的像素块编码为 2 ×4 或 4 ×2 像素的两个块的办法,每个块指定一个基色,每个像素的色彩通过一个编码为绝对于这些基色偏移的灰度值确定。

具体来说,ETC1 每 4 ×4 像素块编码为 64 位的字节数据,每一个像素块又分为两个 2 ×4 子块(由一个“flip”位管制程度或竖直划分),每个子块蕴含一个 3 位的润饰表索引(modifier table index)和一个根本色彩值,这两个色彩值要么是 2 *R4G4B4 要么是 R5G5B5+R3G3B3(由一个“diff”位管制是哪一种)。

3 位的润饰表索引对应于 8 种润饰值:

这样一个子块由 1 个根本色彩值和 4 个润饰值能够确定出 4 种新的色彩值:

color0 = base_color + RGB(modifier0, modifier0, modifier0)
color1 = base_color + RGB(modifier1, modifier1, modifier1)
color2 = base_color + RGB(modifier2, modifier2, modifier2)
color3 = base_color + RGB(modifier3, modifier3, modifier3)

最终的色彩就是从这 4 个色彩值中选出。其原理就是另外 32 位数据中蕴含 16 个 2 位选择器数据,每个像素的色彩都依据 2 位选择器的值从这 4 种中选出。

ETC1 编码方式直观图如下:

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
原名 S3TC(S3 Texture Compression),由 S3 Graphics 开发的一种与组块无关的有损压缩算法,也叫 DXTn 或 DXTC(DirectX Texture),是块截断编码(Block Truncation Coding)的一种改良。因为版权专利个别用于 Windows 平台。

其原理简略来说,是由一对低精度的“基色”来形容一个 4 ×4 的 RGB 像素块,并容许每个像素在这些基色之间指定一个插值。S3TC 有多种变体,每种都是为特定类型的图像数据设计,但它们都是将 4 ×4 的像素块转换为 64 位或 128 位的数据。

BC1(Block Compression)是最小的一种变体,也是转换比最高的一种,在不须要高精度也不须要 a 值时能够应用。它将 4 ×4 个像素作为一个块(block)存储 64 位数据,其中包含两个 16 位 RGB 值(R5G6B5,人眼对绿色更敏感)$color_0$ 和 $color_1$,和 16 个 2 位选择器值,一个像素最终的色彩值由 $color_0$、$color_1$ 和对应的 2 位选择器值决定。混合公式如下:

它的工作形式直观图如下:

PS:BC1 的信息失落次要集中在比拟细的边界上,可进步分辨率来解决,高宽放大 41%(1.41*1.41=1.9881),这样整个纹理差不多是以前的 2 倍,但总的压缩率还能放弃为 3:1。另一个损失是 24 位 RGB 转为了 16 位色彩,看上去差异不大,但对于渐变色带来说就有一些细微差别了。

PPS:在 Unity 2017 中新增了基于 Crunch 库的改进版 DXT 算法,占用磁盘空间更小,解压速度更快,然而相应的图像品质不如 DXT 那么好。

BC2 在 BC1 的根底上反对了 a 值。它将 4 ×4 共 16 个像素存储为 128 位数据,其中包含 64 位 a 通道(每像素 4 位)和 64 位色彩通道,色彩和 DXT1 统一,即两个 16 位 RGB 值和 16 个 2 位索引表 x。它的透明度只有 4 位共 16 种数值,相比 DXT5 有些性能根本没人用。DXT2 和 DXT3 的差异在于是否是预乘过的色彩。

BC3 在 BC2 的根底上改良了 a 值算法。BC3 将 4 ×4 共 16 个像素存储为 128 位数据,其中包含 64 位 a 通道(两个 8 位 a 值和一个 4 ×4 的 3 位索引表)和 64 位色彩通道,色彩和 DXT1 一样,即两个 16 位 RGB 值和 16 个 2 位索引表 x。因为 a 值采纳了和色彩一样相似的块压缩算法,所以数值范畴更广,BC 是比拟常见的。

BC4 和 BC5 在 D3D10 中可用,只能存储一个 / 两个色彩通道。

BC6H 和 BC7 在 D3D11 中可用。BC6H 是一个不带 a 值的 HDR 格局,它将 4 ×4 共 16 个像素存储为 128 位数据,其中包含两个 48 位的 RGB 值(16:16:16),每个色彩重量都是带符号浮点值(1 个符号位 + 5 个指数位 + 10 个尾数位),以及 16 个 2 位索引表。

BC7 相比其它有点非凡,尽管它也是将 4 ×4 共 16 个像素存储为 128 位数据,但它的最低无效位为 Mode 位,(最低无效位即最低的非 0 位)依据不同模式,色彩值的存储格局不同,是否有 a 值或 a 值的存储格局也不尽相同,是一种比拟灵便的存储格局,但这也意味着解码所带来更多的耗费。

PVRTC
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 模式下,每 4 ×4 像素占一个 64 位数据块,2-bpp 模式下每 8 ×4 像素会有一个 64 位数据块。两者大同小异,咱们仅说 4 -bpp 模式。

4-bpp 模式下,A 和 B 图放大后都只保留一个色彩值,如下图所示,A 图比 B 图少 1 位,但两张图都能够抉择以 RGB 或 ARGB 的形式存储(最高位决定为哪种),A 色能够用 RGB554 或 ARGB3443 格局编码,B 色能够用 RGB555 或 ARGB3444 格局编码。

在解码时,为了解码任意像素,必须读取 4 个相邻的 PVRTC 块,应用这 4 个块来解码一个 5 ×5 块。

应用双线性过滤来对 A 和 B 图进行扩充,而后 A 和 B 图依据 M 图与“Mode”位进行混合,这里的 ”Mode” 位为 1 时,M 图中 10 值像素被看作是开启了“punch-through alpha”,Alpha 通道会被强制清零,这种神奇的操作是为了兼容旧应用程序,具体就不说了。

单从 4 -bpp 模式来看,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
ASTC(Adaptive Scalable Texture Compression),由 ARM 和 AMD 联合开发,2012 年公布,是较新的一种压缩格局,惟一一个不受专利权影响的压缩格局。ASTC 在压缩率、图像品质、品种上都挺不错的,也正在逐渐代替前三种,最大的毛病可能就是兼容性还不够欠缺和解码工夫较长,但以当初挪动端的发展趋势来看,GPU 计算能力越来越难成为瓶颈,因而十分有心愿在当前能成为对立的压缩格局。

ASTC 也是一种基于块的有损压缩算法,它很像 BC7,不同的是块中像素数量可变,它的特点有很多:

  • 较高的灵活性:反对 1 - 4 重量的贴图
  • 压缩率 / 品质灵便可变:依据不同图片会抉择不同压缩率级别的算法
  • 反对 2D/3D 贴图
  • 跨平台:iOS、安卓、PC
  • 同时反对 LDR 和 HDR:BC6H 尽管反对 HDR 但不反对 Alpha 通道

ASTC 格局的块为固定大小的 128 位。2D 纹理编码中,它从 4 ×4 到 12×12 像素都有,对应的压缩比从 3:1 到 27:1。所有反对的块和比特率如下:

Increment 列示意压缩比的增量,这也示意 ASTC 的比特率能够在小数级变动,这种技术称为 BISE(Bounded Integer Sequence Encoding)。

ASTC 的压缩非常复杂,分了很多可变的配置数据,也不打算再深入研究了。

但要留神的是只管纹理能够被编码为 1 - 4 通道图像,然而解码后的值总是以 RGBA 格局输入。在 LDR sRGB 模式下,色彩值以 8 位整数的模式返回,而如果是 HDR 则将以 16 位浮点数的模式返回。

《ASTC 纹理压缩格局》对 ASTC 做了具体的测试,十分倡议去看看。

总结

整顿了下网上的材料,以 2020 年市场上的挪动设施反对来看:

  • 安卓:用 ETC2 没有什么问题;至于 ASTC 在 Android 5.0/OpenGL ES 3.1 后反对,市场大部分机型都反对(98.5%),能够思考抉择,但毕竟是安卓,要做好解决兼容性的心里筹备。
  • iOS:在 iPhone6 以上(蕴含)都反对 ASTC,6 以下能够抉择 PVRTC2。

最初,所有压缩格局的简要形容如下,灰色框示意曾经过期了或根本不必了。


参考起源:

TEXTURE COMPRESSION TECHNIQUES

Recommended, default, and supported texture compression formats, by platform

Another Milestone for ASTC Texture Compression

ASTC does it

《ASTC 纹理压缩格局》

《挪动平台纹理压缩格局抉择》

Why use crunch compression?

Crunch compression of ETC textures

ETC1 Compressed Texture Image Formats

Texture compression on mobile demystified

Texture compression using low-frequency signal modulation


这是侑虎科技第 1187 篇文章,感激作者蕾芙丽 Reverie 供稿。欢送转发分享,未经作者受权请勿转载。如果您有任何独到的见解或者发现也欢送分割咱们,一起探讨。(QQ 群:793972859)

作者主页:https://www.zhihu.com/people/…

再次感激蕾芙丽 Reverie 的分享,如果您有任何独到的见解或者发现也欢送分割咱们,一起探讨。(QQ 群:793972859)

正文完
 0