纹理压缩目的

目的是让纹理以压缩的状态从CPU传输到GPU,以及以压缩的状态存在于显存中,这样可以减小带宽和减小显存;带宽过大会增大耗电量和影响性能;对于一个好的手机游戏,必须要满足不发热画面流畅两个基本要求。

纹理压缩为什么不适用PNG、jpg之类的算法

  • 简单说:GPU有时候仅需要整个图像的一小部分,此时解压缩整个图像在计算上是昂贵的,所以纹理采样器必须支持实时随机访问。
  • 具体点:传统的压缩类型,如JEPG或者PNG的压缩方案,旨在压缩或解压缩整个图像,他们可以实现非常好的压缩率和图像质量,但是它们在不解压整个图像的前提下,是不支持实时随机访问的。将2D纹理映射到模型上时,可能会以不可预测的顺序,从完整纹理图像中提取单个纹理像素,并非所有纹理元素都需要。例如,取决于模型的方向以及可能遮盖其一部分的任何其它对象。在最终图像中彼此相邻渲染的纹理,可能源自纹理的不同部分。当GPU仅需要整个图像的一小部分时,解压缩整个图像在计算上是昂贵的。当在常见的游戏贴图压缩算法中,实时压缩方案被设计为,对较大图像中的元素进行随机采样提供有效的解码,也就是支持压缩纹理的实时随机访问。

常用的压缩方式

有DXTC(Windows)、BC1-BC7、 ETC(1和2)、PVRTC(IOS)、ASTC等

DXTC(DirectX Texture Compress)

这种压缩方式主要用在PC端

BC1-BC7,主要用在Direct3D中
  1. BC1(DXGI_FORMAT_BC1_UNORM):该格式支持3个颜色通道,仅用1位(开/关)表示alpha分量。
  2. BC2(DXGI_FORMAT_BC2_UNORM):该格式支持3个颜色通道,仅用4位表示alpha分量。
  3. BC3(DXGI_FORMAT_BC3_UNORM):该格式支持3个颜色通道,以8位表示alpha分量。
  4. BC4(DXGI_FORMAT_BC4_UNORM):该格式支持1个颜色通道(例如,灰阶图像)。
  5. BC5(DXGI_FORMAT_BC5_UNORM):该格式支持两个颜色通道。
  6. BC6(DXGI_FORMAT_BC6_UF16):该格式用于压缩的HDR(高动态范围,high dynamic range)图像数据。
  7. BC7(DXGI_FORMAT_BC7_UNORM):该格式用于高质量的RGBA压缩。特别的有,这个格式可以显著地减少由于压缩法线贴图带来的错误。
ETC

分为ETC1 和ETC2

  • ETC1:OpenGL ES2.0版本及其以上支持,但是ETC1有个严重的缺点——就是不支持alpha通道,所以一般是把RGB和alpha分开压缩,最后在渲染时合并计算;支持所有iPhone。
  • ETC2:解决了ETC1不支持alpha通道的问题,OpenGL ES3.0版本机器以上支持, 支持iPhone 5S及以上。
    IOS不使用ETC的原因是,在压缩大小差不多的前提下,PVRTC表现会更好一些。
PVRTC

由于专利原因,一般用在ios设备上和部分支持PVRTC的安卓机器上, 尺寸要求为2的N次幂,必须是方形,至于为什么要有尺寸要求,是由具体的压缩算法决定的。

ASTC

安卓系统中,OpenGL ES 3.0级硬件上得到广泛支持;ios系统中,支持iPhone6及以上机型;现在大部分移动设备都能支持ASTC。

业界常用的压缩方案一:
  • 安卓:业界一般选择ETC1,因为它是OpenGL ES图形标准的一部分,并且被所有使用opengl2.0的Android设备所支持。但由于ETC1不带alpha通道,因此,带alpha通道的图需要将原贴图拆分通道,一分为二分别压缩,最后在渲染时合并计算。
  • IOS:业界一般使用pvrtc RGBA 4bits格式。
业界常用压缩方案二:
  • 安卓:ETC2,尺寸要求(能被4整除)舍弃部分低端设备市场。
  • IOS:PVRTC、ASTC(舍弃部分老ios设备)。
  • ASTC4\5\6三种压缩格式,目前来看,肉眼可见的差别都不明显,可以ASCT5起步,对于比较常见的UI,采用的是ASTC5的压缩格式,不太重要的UI,是ASTC6。