一、压缩纹理
1996年,斯坦福大学Andrew Beers、Maneesh Agrawala和Navin Chaddha发表了一篇论文《Rendering from Compressed Texture》,提出了一种基于GPU的纹理压缩方法,GPU可以从该类型压缩纹理中直接采样并进行渲染,这种改进是巨大的进步:
- 节省内存
- 纹理在内存中是以压缩格式存在,不仅减小了文件大小,而且减小内存占用。
- 减少传输,提升带宽
压缩技术 | 图片压缩技术 | 纹理压缩技术 |
---|---|---|
解压速度(解压速度) | 不快。 针对的是数据存储和传输 |
很快。 因为GPU要采样进行渲染,不能影响渲染速度。 |
压缩速度(编码速度) | 不快。 | 不快。 并不需要考虑纹理再压缩的情况,一般这个情况在程序之外完成。 |
访问速度 | 不快。 最大化压缩比率,不同数据块可变压缩比率,读取某个数据可能需要解压一大块数据 |
随机访问。 纹理的任何位置随时都可能被访问 |
压缩比率、图像质量 | 可以有较高压缩比率。 无损压缩,不损失图像品质 有损压缩,高压缩比率 不同数据块,不同压缩比率 |
一般为有损压缩 固定压缩比率(采用索引,支持随机访问) |
三、创建压缩纹理
压缩纹理和普通2D纹理的创建方法一样,这里可参照普通2D纹理的创建。区别就在于创建函数:
void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
// 创建一个压缩格式的二维纹理 // target: 指定纹理目标,可能值如下: // GL_TEXTURE_2D // GL_PROXY_TEXTURE_2D // GL_TEXTURE_1D_ARRAY // GL_PROXY_TEXTURE_1D_ARRAY // GL_TEXTURE_CUBE_MAP_POSITIVE_X // GL_TEXTURE_CUBE_MAP_NEGATIVE_X // GL_TEXTURE_CUBE_MAP_POSITIVE_Y // GL_TEXTURE_CUBE_MAP_NEGATIVE_Y // GL_TEXTURE_CUBE_MAP_POSITIVE_Z // GL_TEXTURE_CUBE_MAP_NEGATIVE_Z // GL_PROXY_TEXTURE_CUBE_MAP // level: 纹理详细等级(level-of-detail),=0表示原始纹理大小,=1表示1/2原始纹理大小,以此类推 // internalformat: data存储的压缩图数据的格式 // width: 纹理像素宽度,2D纹理至少64,立方体(3D)纹理至少16 // height: 纹理像素高度,同上 // border: 必须是0 // imageSize: 从data地址开始的image data 的unsigned byte数 // data: 指向内存中压缩图像数据的指针
<a name="nbsVC"></a>
# 四、压缩纹理格式
<a name="RmHz7"></a>
## 1、ETC(ETC1)
Ericsson Texture Compression,爱立信公司于2005年提出的有损纹理压缩技术,OpenGL ES 2.0的标准,但并不是强制的,它是最通用的纹理压缩格式,几乎所有的移动设备都支持,它是一种为感知质量设计的有损算法,其依据是人眼对亮度改变的反应高于对色度的改变。<br />但是并不支持alpha通道,所以各大GPU厂商会支持ETC,但一般都会各自开发一套纹理压缩技术。
```cpp
GL_OES_compressed_ETC1_RGB8_texture // 在 OpenGL ES 中扩展名
GL_ETC1_RGB8_OES // 压缩24位RGB纹理,0.5bpp
原理:https://gameinstitute.qq.com/community/detail/123075
RGB ETC 4bit**
- 每个像素占用4bit,对24位RGB数据提供了6:1的压缩比率,在OpenGL ES 2.0\3.0上支持,不支持alpha通道压缩,一般会采用以下方法解决这个问题:
- 一张图片保存2个纹理:ETC压缩纹理+alpha可见的灰度图,然后自定义shader。
- 两张图片:然后使用多重纹理技术(mipmaps)
- 现在基本淘汰了,一般直接使用ETC2。
相关工具
ARM提供的工具Mali Texture Compression Tool。
这个工具可以解决ETC的不支持alpha通道问题,一种方法是在一个ETC纹理中保存两张纹理,一张RGB的ETC,一张alpha纹理(将alpha通道转换为可见的灰度图像),在自定义片段着色器,对纹理多做一个alpha采样。另一种方法是单独生成一张alpha通道的纹理,然后通过多重纹理技术(mipmaps)将两张纹理组合到一起。
2、ETC2**
OpenGL ES 3.0的标准,为强制标准,所有支持OpenGL ES 3.0的设备都支持ETC2,相比于ETC的优势:
- 向下兼容ETC1
- 比ETC1提供更好的纹理压缩质量
- 支持alpha,支持单通道和双通道模式。
相比于其他纹理压缩技术(S3TC、PVRTC),压缩质量也更高,缺点是并不是所有的设备都支持OpenGL ES 3.0。
原理
- https://gameinstitute.qq.com/community/detail/123075
- https://www.khronos.org/registry/OpenGL/extensions/OES/OES_compressed_ETC1_RGB8_texture.txt
RGB ETC2 4bit
- 提供了和ETC相同的压缩比和功能,但压缩质量更高,在OpenGL ES 3.0上支持。
RGBA ETC2 8bit
- 每像素8bit大小,支持8bit alpha通道。对32 bitRGBA提供了4:1的压缩比。
RGB+1 bit alpha ETC2 4bit
- 每像素4bit大小,支持1bit alpha通道。
EAC
- 核心原理与ETC相同,但它只用于单通道或双通道数据,OpenGL ES 3.0和OpenGL 4.3后的设备大部分支持,但由于安卓平台五花八门的兼容性,一般不建议用单双通道贴图。
2、PVRTC
参考资料:https://www.jianshu.com/p/d4e51dd55dfa**
Power VR Texture Compression,由Imagination Technologies公司专为PowerVR显卡核心设计,支持的GPU为Imagination Technologies的PowerVR SGX系列。由于专利原因一般它只被用于苹果的设备,仅Iphone、Ipad和部分PowerVR的安卓机支持,有较高排他性。
仅支持POT纹理,支持alpha通道,如果图像数据不含有alpha通道,则该通道空间会用于存储RGB数据,提升压缩比和质量。 ```cpp
GL_IMG_texture_compression_pvrtc; // 在OpenGL ES中的扩展名
GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG; // 压缩24位RGB纹理,0.5bpp GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG; // 压缩24位RGB纹理,0.25bpp GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; // 压缩32位RGBA纹理,0.5bpp GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; // 压缩32位RGBA纹理,0.25bpp
**PVRTC2**<br />在GDC 2012上,Imagination Technologies对PVRT进行了更新,推出了PVRTC2,增强了图像压缩质量,尤其是一些高对比度、大面积颜色不连续的部分、纹理边缘,支持NPOT纹理,更好地支持alpha预乘(Alpha Pre-Multiplied)。
```cpp
GL_IMG_texture_compression_pvrtc2; // 在OpenGL ES中的扩展名
GL_COMPRESSED_RGB_PVRTC2_4BPPV1_IMG; // 压缩24位RGB纹理,0.5bpp
GL_COMPRESSED_RGB_PVRTC2_2BPPV1_IMG; // 压缩24位RGB纹理,0.25bpp
GL_COMPRESSED_RGBA_PVRTC2_4BPPV1_IMG; // 压缩32位RGBA纹理,0.5bpp
GL_COMPRESSED_RGBA_PVRTC2_2BPPV1_IMG; // 压缩32位RGBA纹理,0.25bpp
原理
PVRTC不同于DXT和ETC这类基于块的算法,而将整张纹理分为了高频信号和低频信号,低频信号由两张低分辨率的图像A和B表示,这两张图在两个维度上都缩小了4倍,高频信号则是全分辨率但低精度的调制图像M,M记录了每个像素混合的权重。要解码时,A和B图像经过双线性插值(bilinearly)宽高放大4倍,然后与M图上的权重进行混合。
https://gameinstitute.qq.com/community/detail/123075
https://zhuanlan.zhihu.com/p/237940807
https://www.khronos.org/registry/OpenGL/extensions/IMG/IMG_texture_compression_pvrtc2.txt
相关工具
Imagination Technologies提供了一套PVRTC格式工具,包括SDK、图形化工具PVRTexPool。可以借助工具生成PVRTC压缩纹理。
还有TexturePacker。
3、S3TC(DXTC)
S3TC:S3 Texture Compression
DXTC:DirectX Texture Compression
由 S3 Incorporated 公司在1999年申请的专利。后来被DX 6.0和OpenGL 1.3吸收为官方标准,因此S3TC也称DXTC,DXTC相当于Windows版的名字,S3TC是OpenGL中的名字。
支持的GPU为NVIDIA Tegra系列,在PC上广泛使用,移动设备商使用nVIDIA的很少。
GL_EXT_texture_compression_dxt1; // 在OpenGL ES中的扩展名
GL_EXT_texture_compression_s3tc; // 在OpenGL ES中的扩展名
GL_COMPRESSED_RGB_S3TC_DXT1 // 压缩RGB纹理,0.5bpp
GL_COMPRESSED_RGBA_S3TC_DXT1 // 压缩RGBA纹理,0.5bpp
GL_COMPRESSED_RGBA_S3TC_DXT3 // 压缩RGBA纹理,1bpp
GL_COMPRESSED_RGBA_S3TC_DXT5 // 压缩RGBA纹理,1bpp
原理
https://zhuanlan.zhihu.com/p/125751581
相关工具
可以使用DirectX SDK中自带的DirectX Texture Tool进行转换
4、ATITC
参考资料:https://huailiang.github.io/blog/2019/texture/
ATI Texture Compression。
支持的GPU为Qualcomm的Adreno系列,其他GPU厂商并不支持。
GL_ATI_texture_compression_atitc // OpenGL ES扩展名
GL_ATC_RGB_AMD // RGB,0.5bpp
GL_ATC_RGBA_EXPLICIT_ALPHA_AMD // RGBA,1bpp
GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD // RGBA,1bpp
相关工具
Adreno GPU SDK
Adreno Texture Tool
5、ASTC
参考资料
- https://zhuanlan.zhihu.com/p/237940807?utm_source=wechat_timeline
- https://zhuanlan.zhihu.com/p/158740249
- https://www.cnblogs.com/bylle/p/12212823.html
Adaptive Scalable Texture Compression,自适应可伸缩纹理压缩,由ARM和AMD联合研发,2012年发布,基于块的有损压缩算法,唯一一个不受专利影响的压缩格式,2018年被Khronos组织认可。
从IOS9开始支持 ,相对于PVRTC,ASTC(4X4)的压缩比会增加到0.25,显示效果也会好很多,而且不要求图片长宽相等且为2的幂次方,Android设备也支持,可以说,ASTC是目前最好的纹理压缩格式,默认首选。(由于这是最新压缩格式,所以可能存在部分机型不适配问题)
以2020年市场上的移动设备支持来看,推荐的纹理压缩格式如下:
- android
- ETC2:没什么问题。
- ASTC:在Android 5.0/OpenGL ES 3.1后支持,市场上约98.5%的手机机型支持。
- IOS
- ASTC:iphone 6以上都支持。
- PVRTC2:iphone 6以下选择。