纹理压缩

导语 我们经常听说有相应的jpg,webpp,png等图像压缩格式,但你有没有听说过ETC,S3TC等格式吗?如果没听说就请看我这篇文章吧。

一、前言

游戏场景里,贴图是影响真实性的重要因素。通常贴图越大,也就越精细,但其占用的内存空间也就更大。

常用的图片文件格式有:BMP, TGA, JPG, GIF, PNG等。

不过,像JPG这种常见的图片压缩格式,对于多数应用的内存占用和显示总线带宽占用并没有带来直接的好处,因为还得对JPG进行解压缩成原始的像素,再传给显卡,而且还有加载时的解码计算负担。这是因为显卡的纹理解码硬件不理解JPG格式。所以,在没有显卡硬件支持的情况下,用压缩格式保存纹理没有什么意义,特别是对于移动设备来说,解码像JPG这种复杂格式是很浪费电的。

常用的纹理格式有:RGB_565, ARGB_4444, ARGB_1555, RGB_888, ARGB_8888等。

不论何种图片文件格式,它们都是为了存储像素信息而是用的对信息的特殊编码方式,它存储在磁盘中,或者内存中,但是并不能被GPU所识别,因为以向量计算见长的GPU对这些复杂的计算无能为力。当这些文件格式被游戏读入后,需要经过CPU解压成RGB_565,ARGB_4444, ARGB_1555, RGB_888, ARGB_8888等像素格式,才能传送到GPU里使用。纹理格式是能被GPU所识别的像素格式,能被快速的寻址并采样。

纹理格式如:RGB_565,每个像素占用:5+6+5=16 (bits),共 2 个字节。RGB_888,每个像素占 24 位,3 个字节。ARGB_8888占 32 位,4 个字节。

关于纹理格式的更多资料:http://en.wikipedia.org/wiki/High_color

二、贴图压缩方式

对于一张 512_512 的纹理,RGB_565格式的文件占用 512 KB的容量。

计算公式为:numBytes = width _ height _ bitsPerPixel / 8

ARGB_8888格式的文件需要占用1M的容量;如果是1024_1024,则需要更多。

現在一般的显卡上通常有 32MB 的显存容量。如果每个贴图都要 2MB 的話,即使不计 frame buffer 所占用的空間,也只能使用 16 张贴图。这显然是不可接受的。所以,现在的游戏通常无法使用很大的贴图。

然而,在储存一般的影像的時候,通常会使用某些压缩方式。现在常见的 JPEG 压缩,可以达到 1:6 甚至 1:12 的压缩比。如果把类似的压缩方式应用在贴图上,不就可以大量减少贴图所用的空间了吗?

不幸的是,一般的影像压缩方式,是沒有办法用在贴图上面的。因为,显示芯片在存取贴图时,是一种「随机存取」的动作。也就是说,显示芯片通常会需要以任意 的顺序存取贴图里的资料。一般的压缩方式如 JPEG,都利用了 variable length 的 coding,简单的说,它们必需以一定的顺序才能解开。因此,不能用这种方式来压缩贴图。

一种压缩方式,是改变颜色空间。例如,3dfx 的 YAB 格式,就是一种不同的颜色空间。利用 YAB,每个像素只需要 8 bits,就可以达到接近 16 bits 的效果。不过,无论如何,这样都使颜色的数目减少。因此,整个贴图的色彩变化就受到了限制。

另一种方式,就是用传统的「调色盘」结构。利用一个 256 种颜色的调色盘,就可以把贴图以 8 bits 的方式储存。不过,虽然它的色彩空间较大(可以是 24 bits 或 32 bits),但是总颜色数目还是不能超过 256 种。所以,它的应用范围仍然有限。

现在常用的贴图压缩方式,则是利用以区块为基础的方式。通常的做法是,把贴图切割成许多小区块,再对各个区块进行压缩。例如,S3TC 就是把贴图切成 4x4 的小区块。利用这种做法,就可以对区块进行某种处理(通常就是 vector quantization 或是其变形),显示芯片也可以以区块为单位,进行随机的存取动作。因此,这是适合用在贴图的方式。

不过,区块的大小会影响到压缩的效果。一般来说,区块越大,就能有越高的压缩比。不过,越大的区块也会使额外的负担增加。因为显示芯片只能以区块为单位来读取贴图,如果区块越大,则每个区块中就可能会有越多的资料是不需要的。所以,也不能任意把区块的大小加大

在Beers,Agrawala和Chaddha于1996年发表的一篇影响深远的论文基於已壓縮紋理的渲染 [1]中,他们列举四项纹理压缩的特点,使其不同于其他图片压缩技术。

解压速度:为了尽可能不影响性能,解压缩要尽可能快,最好能直接从已压缩的纹理直接渲染。(所谓解压,就是把贴图转换成GPU能识别的纹理格式:RGB_565等。)

随机访问:由于几乎不可能预测纹理像素被访问的顺序,任何纹理压缩算反必须允许对其中的纹理的随机访问。所以几乎所有的纹理压缩算法都已块为单位压缩和存储纹理像素,当某一个纹理像素被访问时,只有同一块中的若干纹理像素被读取和解压缩。这项需求也排除了很多压缩率较高的图片压缩格式,例如:JPEG和行程長度編碼。

压缩率和图像质量:由于人眼的不精确性,相比于其他应用领域,图像渲染更适宜使用有损压缩。

编码速度:纹理压缩对压缩速度的要求不高,因为绝大多数情况下,纹理只需要进行一次压缩。(但是对解压速度要求较高。)

由于其数据访问模式是事先知道的,纹理压缩常作为整个渲染管线的一部分,在绘制时动态的对已压缩数据进行解压缩(可以把解压缩放在shader里处理)。而反过来渲染管线也可以通过纹理压缩技术来降低对显卡位宽和存储的需求。在纹理贴图中,已经压缩的纹理和没有经过压缩的纹理使用起来基本没有区别,都可以被用来存储颜色数据或其他数据,例如凹凸贴图或法线贴图,也都可以和Mipmapping或各项异性过滤等共同使用。

主流的纹理压缩标准:ETC, PVRTC, S3TC。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏YG小书屋

Query Auto Completion自动完成查询(一)

当我们用搜索引擎或其他工具搜索内容时,输入框下方的提示内容会根据你的输入进行调整展示。这个过程我们称之为Query Auto Completion(QAC)。用...

581
来自专栏祝威廉

谷歌BigQuery ML VS StreamingPro MLSQL

今天看到了一篇 AI前线的文章谷歌BigQuery ML正式上岗,只会用SQL也能玩转机器学习!。正好自己也在力推 StreamingPro的MLSQL。 今...

673
来自专栏人工智能

从零开始:TensorFlow机器学习模型快速部署指南

选自Hive Blog 作者:Bowei 机器之心编译 参与:李亚洲、李泽南 本文将介绍一种将训练后的机器学习模型快速部署到生产种的方式。如果你已使用 Tens...

3717
来自专栏流媒体

音频编码(一)——FFmpeg编码

这里为啥讲到了声波,讲到了我们的中学物理上的知识,因为我想大家能从根本理解后面音频编码的各种参数以及原因。当然这些知识网上都能搜到,我只是整合一下。

1313
来自专栏AI2ML人工智能to机器学习

TF Boy 之初筵 - 分布十三式

我们在 " 机器学习平台的优化器 (平台篇、优化篇)" 里面提到TensorFlow (TF) 速度的成为深度学习的武林第一大帮。 博士好友清华,在这方面也颇有...

542
来自专栏祝威廉

为Spark Deep Learning 添加NLP处理实现

前段时间研究了SDL项目,看到了Spark的宏大愿景,写了篇Spark新愿景:让深度学习变得更加易于使用。后面看了TFoS,感觉很是巧妙,写了一篇TensorF...

643
来自专栏AI研习社

Github 项目推荐 | 在 Spark 上实现 TensorFlow 的库 —— Sparkflow

该库是 TensorFlow 在 Spark 上的实现,旨在 Spark 上使用 TensorFlow 提供一个简单的、易于理解的接口。借助 SparkFlow...

842
来自专栏人工智能LeadAI

译文 | 与TensorFlow的第一次接触 第六章:并发

第一版TensorFlow第一版发布于2015年11月,它可以运行在多台服务器的GPU上,同时并在其上面进行训练。2016年2月,更新版中增加了分布式与并发处理...

4007
来自专栏机器之心

TensorFlow发布重要更新AutoGraph,自动将Python转化为TF计算图

作者:Alex Wiltschko、Dan Moldovan、Wolff Dobson

1254
来自专栏智能算法

OpenCV特征点检测——ORB特征

目录 什么是ORB 如何解决旋转不变性 如何解决对噪声敏感的问题 关于尺度不变性 关于计算速度 关于性能 Related posts 什么是ORB ? ORB是...

3317

扫码关注云+社区