纹理压缩目的
目的是让纹理以压缩的状态从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中
- BC1(DXGI_FORMAT_BC1_UNORM):该格式支持3个颜色通道,仅用1位(开/关)表示alpha分量。
- BC2(DXGI_FORMAT_BC2_UNORM):该格式支持3个颜色通道,仅用4位表示alpha分量。
- BC3(DXGI_FORMAT_BC3_UNORM):该格式支持3个颜色通道,以8位表示alpha分量。
- BC4(DXGI_FORMAT_BC4_UNORM):该格式支持1个颜色通道(例如,灰阶图像)。
- BC5(DXGI_FORMAT_BC5_UNORM):该格式支持两个颜色通道。
- BC6(DXGI_FORMAT_BC6_UF16):该格式用于压缩的HDR(高动态范围,high dynamic range)图像数据。
- 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。