关于压缩纹理的格式的思考
来源:互联网 发布:沈阳工业大学学校域名 编辑:程序博客网 时间:2024/05/16 18:58
常见的图像格式bmp、jpeg以及jpeg2000,以及png;甚至最近几年google的webp格式。
bmp格式基本上没有压缩;
jpeg是有损压缩,早已成为图像传输标准,不支持透明通道;jpeg2000最显著增加渐进式传输。jpeg可以任意指定感兴趣区域的压缩质量。
png无损压缩,支持透明通道,android的各种资源都是png。
webp,最近几年google的开源项目,更高的压缩比,更小的图像质量损失。
这么多现成的图像格式,为毛压缩纹理不采用呢?为何很多公司都推出自己的纹理压缩格式呢?原因很简单:jpeg、png这些压缩格式是为CPU解码设计的,不适合GPU的并行特性。
参见 Texture Compression Jacob strom, Ericsson Research
page48 道出了GPU解码图像的三个特点:
1)必须能够随机访问。即对于任意一个像素都能随机地快速算出它在图像数据中的地址(偏移值)。而对于JPEG显然是做不到的,它采用VLC(variable bit length coding)不定长编码方式,为不同区域分配不同的压缩位数,从而达到为不同区域分配不同压缩质量。
上图中,茶壶区域为重要和感兴趣区域,JPEG压缩数据中这块区域占更多的bits。
2)会有很多解压单元并行处理,使得解压算法复杂度必须足够低,足够简单。
3)调色板或者其他全局数据会导致 间接寻址(Indirect addressing),因此这些数据在纹理压缩中应该尽可能避免。jpeg内部也有。
上图为间接寻址模式中获取颜色数据的过程:GPU首先请求加载索引数据14;一旦有了索引数据就可以立即加载实际颜色值,来回四次最终得到颜色值。索引数据可能为FIFO缓冲区引入了性能隐患,芯片端保存颜色表的代价也十分大,颜色表可能和纹理缓存占的空间接近;所以最好避免使用颜色表这些全局数据。
于是显卡厂商推出专为GPU设计的压缩纹理格式应用而生了:
› Texture compression algorithms
– Palettized textures
– BTC
– CCC
– S3TC
– PVR-TC
– PACKMAN
– ETC (Ericsson Texture Compression), ETC1,ETC2。
› Normal map compression
– 3Dc
BTW: 普通jpeg、png图片,从文件加载的时候必须cpu先解码成原始的RGB、RGBA格式数据,然后glTexImage2D生成纹理; ETC这类纹理可以直接将原始数据glCompressTexImage2D传给OpenGL,GPU创建纹理时自行解码。
ETC1 Texture
opengles and ETC:opengle3.0后支持etc2,gles1.1和gles2.0支持etc1。
Android and ETC:android sdk自带的etc1tool.exe,支持从png直接转化成etc的pkm文件。etc1tool的过程在android源码中可以找到,etc1.h, etc1.cpp,两个文件可以单独抽出来,已上传到我的资源中。http://download.csdn.net/detail/dizuo/6708161
压缩性能:在小米1上测试,很慢达不到实时,etc1.cpp中压缩算法复杂度很高,只能离线处理。解码过程是GPU多个processor-单元并行处理速度很快。
测试Code:
int comprSize = etc1_get_encode_image_size(256, 256);etc1_byte* pComprData = new etc1_byte[comprSize];int width = 256;int height = 256;int pixelSize = 2;// 输入原始图像数据是RGB565,跟RGB888基本类似。int stride = pixelSize * width;int start = SysGetTickCount();etc1_encode_image((const etc1_byte*)texBuffer, width, height, pixelSize, stride, pComprData);int end = SysGetTickCount();__android_log_print(ANDROID_LOG_INFO,"etc1", "%d [ enter ]", (end-start));glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_ETC1_RGB8_OES, width, height, 0, comprSize, pComprData);delete[] pComprData;// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, texBuffer);测试结果输出:
12-13 12:09:18.621: I/etc1(11562): 376067 [ enter ]12-13 12:09:18.951: I/etc1(11562): 316295 [ enter ]12-13 12:09:19.471: I/etc1(11562): 306647 [ enter ]12-13 12:09:19.751: I/etc1(11562): 278829 [ enter ]12-13 12:09:20.061: I/etc1(11562): 280077 [ enter ]12-13 12:09:20.321: I/etc1(11562): 262186 [ enter ]12-13 12:09:20.621: I/etc1(11562): 293347 [ enter ]12-13 12:09:20.901: I/etc1(11562): 258785 [ enter ]12-13 12:09:21.161: I/etc1(11562): 260074 [ enter ]单位是GetTickCount的结果。
history - add etc1 texture 2013/12/13
- 关于压缩纹理的格式的思考
- unity3d 关于纹理压缩的一些交流,挺有用,备忘
- DirectX11 压缩纹理格式
- ETC1压缩纹理格式
- 个人理解的 纹理压缩
- Direct3D9的扩展纹理格式
- Direct3D9的扩展纹理格式
- Unity支持的纹理格式
- untiy的纹理格式介绍
- [概念]纹理的像素格式
- 常用纹理和纹理压缩格式
- 常用纹理和纹理压缩格式
- 常用纹理和纹理压缩格式
- 常用纹理和纹理压缩格式
- 常用纹理和纹理压缩格式
- 关于粗大的纹理
- 关于思考的思考
- 关于思考的思考
- 【面试题二】java实现的单例模式,c++实现单例模式,实现禁止拷贝
- java种有效的开发方案!
- opengl overpainting renderText paintEvent 选择
- 【面试题一的补充】C++ MyString类的封装
- 数据挖掘领域十大经典算法初探
- 关于压缩纹理的格式的思考
- android onActivityResult不执行问题
- Linux一站式编程,好书。。网页链接
- java的正确认识!
- POJ 2352(树状数组)
- cocos2dx转到android项目,使用第三方so库文件
- JAVA流程控制
- Codeforces Round #216 (Div. 2)
- ASP.NET IIS和本地测试虚拟目录问题