为什么需要纹理压缩?

“最近在玩什么游戏,推荐一个”。不管是谁,总会说过或听过这个问题吧。

这时候,你脑海里面浮现的也许是这样的画面

或许最终小伙伴们也能接受这样的游戏

但还是会有一些玩家更怀念这样的游戏

在软件开发,特别是三维应用中,纹理随处可见,但受限于网络环境和硬件能力,纹理也是一大瓶颈。而且在一般的三维应用中,纹理所占大小基本都会在1/2以上,模型中往往超过2/3。或许你会说,纹理不就是一张图吗,有那么重要吗?

如下两张对比图,可能你会认为前者逼格高,但对于正常人而言,后者显然要好很多。正是有了纹理,如同在骨架上赋予了皮肤,让我们的应用更加的逼真,贴近现实。

而你能想象到吗?如上的模型一共有三张纹理,其中之一效果如下:

看上去怪怪的。其实在纹理的压缩中,人们先想到了如何去除冗余信息,对称的部分只保留一份,尽可能让不同的部分紧凑,充分利用好每一个像素来保存有效数据。得益于对称在大自然中的普遍性,这种方式确实极大的减少了纹理像素。

纹理的拼接是纹理压缩的开始,采用不同的压缩方式对纹理最终的大小影响也是显著的。比如上面的这张纹理在不同压缩格式下的大小差别也是非常显著的(原始文件为tga格式,通过Photoshop转换为其他格式,默认选项):

如果按照上面表格的逻辑,用jpg或png格式就好了,无损压缩,而且也是最小的。确实在很多情况下这是一个比较好的选择,比如网络带宽有限,这样可以很好的节约带宽和下载时间,而Bmp,tga,png以及jpg都是无损格式。但这类压缩存在一个致命缺陷,他们都是基于整幅图片下进行的压缩,比如霍夫曼编码等,这样像素和像素之间在解码的过程中存在依赖关系,无法直接实现单个像素级别的解析,这就发挥不了显卡的并发能力,更重要的是问题在于无论是png还是jpeg最终在显存中解码后都是RGBA的纹理格式,因此并无法减少显存的占用率。比如一张256*256的RGBA纹理,无论是png还是jpg格式,虽然文件大小不一样,在显卡中的大小仍然是256*256*4的显存空间。

正是因为传统的图片格式并没有考虑显卡的这种特性,所以很难满足三维应用中的要求。基于这些问题,如下四点可以作为我们选择纹理压缩格式的衡量标准(引自《Texture Compression using Low-Frequency Signal Modulation》)

  • 解析速度 在纹理操作中,读取纹理数据是关键步骤,所以解码速度至关重要。
  • 随机读取数据 能快速的随机读取任意像素
  • 压缩率和纹理质量 既要保证一个不错的压缩效果,也要把纹理损失控制在一定范围内
  • 压缩速度 通常纹理压缩在渲染前已经提前准备好,所以如果压缩的速度比解析速度慢,也是可以接受的。

调色板技术

最初想到的就是调色板技术,这个思路很简单,在当时硬件能力不高的情况下也非常的好用,类似GIF格式,通常保存一个8位或4位的调色板。为什么没有16位的调色板,因为16位的RGB的效果本身就相对不错,所以16位调色板的意义并不大。如下是调色板原理示意。

对于纹理中颜色个数不超过256,或者愿意适当删减,将颜色数目控制在256以内的话,调色板还是非常高效的压缩技术,相比RGBA的颜色格式要少87.5%的空间。当然,颜色越丰富,所效果损失越严重。如下是同一张纹理的效果对比:

调色板方式下还有一个非常明显的优势是风格的变化,只需要更改调色板信息,而不用保存多套纹理,就可以很轻松的实现风格的多样化,这种成本很低,而且还很高效。

但是显卡中并不支持这种调色板纹理方式,或者只有很老的显卡会支持,当然我们可以采用一维纹理的方式来模拟调色板,但这种情况下不能开启纹理过滤功能,因为调色板的颜色顺序是随机的,在插值过程中和我们预期的效果会有出入。

可见调色板的使用非常灵活,如果运用得当,很多复杂的问题都可以很好的解决,但毕竟显卡不支持这种纹理方式,而且毕竟也有256颜色的限制,在稍微复杂的情况下就有点捉襟见肘。而在顶点着色器上,每次都要操作两次(获取索引值,读取调色板对应的颜色),而且调色板也需要作为参数,或指定一个全局的调色板,这样就会存在内存和显存之间的频繁切换,从性能的角度来也不是最优方案。

纹理压缩

调色板方式有着很多的优点,但也有致命的缺点,在调色板的基础上不断改良,最终形成了现在这种相对平衡的压缩方案。

首先,意识到有损压缩下的显示效果还是不错的,所以压缩后以16位的颜色格式存储,如上是RGB和16位的对比效果图。再次则是自带“调色板”,化整为零,方便自身携带。

上图是纹理压缩原理图,对于一张原始纹理,会创建两张小纹理A和B,可以认为是原始纹理的缩略图,同时还有一个矩阵M,M的行列和原始纹理的长宽一致,里面的值类似于调色板中的索引,实现纹理A和纹理B的混合。示意图如下:

可以说目前主流的纹理压缩格式,比如DXT,PVR和ETC纹理压缩在原理上如出一辙,但在细节上会有很多独特的改善。我们逐个道来,对比其中的优劣。

DXT

DXT是一种有损纹理压缩算法,微软的Direct中支持,DXT的格式包括DXT1~DXT5,其中DXT1和DXT5较为多见,后面会做详细讨论。可以说DXT是目前应用最广泛的纹理压缩格式,可以认为所有的PC端显卡都支持DXT压缩,维基百科说记录,该专利有效期到2017年10月2号。

如上图,DXT的压缩思路也比较一致,有两个Color A(00)/B(11),而4*4矩阵中的索引比较简单,在DXT不同的格式中,差值的因子稍有不同,比如在DXT1中,差值得到的另外两个颜色的公式为:C2= 2/3*C0 + 1/3*C1, C3 = 1/3*C0 + 2/3*C1,这里有一个小技巧,尽管分母是3,但都会近似到2的N次幂,比如2/3约等于5/8,为什么?如下是食人怪纹理的DXT1效果:

DXT算法非常容易理解,而且整体看上去效果不错,但如果对局部特写,会发现在细节上会有很多丢失,这也是算法本身导致的,毕竟每个块只有两个颜色,而其他颜色都是在这两个颜色区间的差值,如果当前区域内还有其他显著颜色则必然会有丢失。

这种信息的丢失主要集中在比较细的边界中,但DXT1在压缩率上是RGB的6倍,这种问题可以通过提高纹理分辨率的方式来解决,高宽放大41%,这样整个纹理是以前的2倍,但压缩率还能保持为3倍,也是可以接受的。

在DXT中还有一个主要的损失,就是RGB的24位转为了16位颜色,16位中R&B各占5位,但是G占了6位,这是因为人眼对绿色最为敏感。

另外一个问题就是DXT3和DXT5之间的对比,相比DXT1不支持透明度(但支持是否透明),DXT5要大一倍(多了64bit),和之前颜色保存方案一样对透明度也保存了两个16位的颜色和对应的调色板,对RGBA的效果也得到了保证,但DXT3思路不一样,它是对每一个像素保存了4bit的透明度,同样也是多了64bit,但此时毕竟只有16个透明度选项,相比DXT5,在压缩率上相当,但对透明色的处理不够细腻,因此在实用性上并不推荐DXT3。

尽管DXT在细节上有明显硬伤,在总体效果不错,而且确实是一种强大的压缩方式,所以在多数纹理压缩选择中都是最佳方案,几乎可以认为是PC下的标准压缩格式。

PVR&ETC

也许是出于专利和商业角度,也许确实DXT在移动端确实无法满足要求,DXT并没有在移动端得到很大的支持,相反,在iOS设备中支持的是PVR压缩,在Android中支持的是ETC压缩。下面详细介绍一下PVR的压缩和ETC解压缩的过程。

DXT在细节上缺陷明显,最重要的原因是当把纹理分为4*4像素的区域块后,每个块之间都是独立的,尽管这极大的简化了压缩算法,但却丢失了相邻块之间这种普遍的相似性。这是算法本身导致的,而PVR则会考虑该区域块对应的右侧,下侧和右下侧的三个区域块的关联性。

如上,是PVR中一个block的结构图,同样的两张Color A/B,这里会有透明模式和非透明模式,这种策略是可取的,首先不用单独增加透明度的字段,尽管透明度的增加会牺牲RGB的质量,但在透明情况下,RGB的作用并不如在不透明情况下那样重要,这种损失也是可以接受并弥补。

首先,在生成Color A/B时,会对原始纹理做一些处理(最简单的就是翻转或旋转90度),得到一张delta image,这个delta可以用来调整生成的Color A/B,比如最简单的一个方式就是点乘每个delta向量。

然后基于Color A/B来计算该block中对应的M,相比于DXT1中的1/3和2/3,PVR中对应的值分别为:

在计算M的过程中,会对已有的Color A/B进行优化,这个过程称为SVD(Singular ValueDecomposition),因为非常耗时,时间复杂度是O(n^3),所以仅对中心块进行优化,而对四周不进行此操作。

虽然PVR也提供了2bpp(bits perpixel)的格式,但效果很烂,所以基本只有4bpp是可用的。另外因为考虑了区域块之间的相关性,还有SVD算法对效果的优化,不难想象,PVR纹理在压缩时性能慢的难以忍受。但没办法,毕竟PVR是iOS官方支持的纹理压缩,只能忍。

上面是PVR的压缩过程,下面我们对应的看一下ETC下解压缩的过程。

如上,是ETC中Color A/B的大致分布(其中一种较为简单的情况,总共两种情况,取决于diffbit是0还是1)。而cw1和cw2对应所需的“调色板”。

在ETC中,对调色板做了一个优化,下面是索引和值的对应关系:

这个调色板并不复杂,结合M中对应的索引(2bit),获取每个原始像素对应Color A/B的偏移量

如上是ETC的解压,至此,我们详细介绍了三种主流的压缩格式,他们之间思路相仿,但具体细节上各有所长,为了压缩的性能,可以说里面有很多小的技巧值得我们借鉴。当然孰优孰劣,每个人或许都会有自己的判断。下面是一个详细的各种压缩格式下效果和压缩比的对比图,各位感兴趣的可以自行对比。

总结

终于写完了,本文主要参考资料和图片来自joostdevblog中对DXT和调色板的详细介绍,以及上面提到的Texture Compression这篇经典论文,以及维基百科中关于DXT纹理压缩,以及OpenGL官网上对ETC纹理的介绍。在学习纹理压缩这个过程中,也在思考这样设计的目的,不同纹理之前的细微区别,究竟是商业因素还是技术问题,导致了这些差异,也在试图总结,这么多的trick他们是怎么想到的,虽然看起来不起眼,但里面都是经验和智慧的结晶,整合在一起确实让人叹服,个人也在不断的梳理方方面面,希望能通过自己的理解,能让大家有条理的,相对深入的了解纹理压缩的原因,更好的理解运用这些技术。当然,难免有出错的地方也希望指正。

但从现实的角度来看,受制于专利和硬件厂商,我们并没太多选择的余地,Android下就要用ETC,iOS下只能PVR,而在PC上不用DXT估计就要被嘲讽了。但这也是一个很棘手的问题,比如在WebGL下,特别是Android下差异化很大,是否支持纹理压缩,甚至在同一个设备不同的浏览器,因为驱动的不一致,可能系统自带的会支持ETC压缩,而微信等QQ浏览器下并不支持。而且华为的手机貌似在浏览器级别下都不支持ETC(硬件支持,还是驱动的问题)。而如果在移动设备上不用压缩,显存是有限的,除非你在数据量上做出牺牲,怎么解决都很矛盾,相比而言,iOS下则要舒服很多。设备的多样性带来的烦恼,让我觉得乔布斯的伟大之处:优秀的同事不是为了计算机而工作,而是因为计算机是传达某种情感的最佳媒介,他们渴望分享,正是因为这种精神,有些人宁愿做诗人也不愿意做银行家,我想把这种精神溶入产品里,而计算机就是我传达情感的媒介。

原文发布于微信公众号 - LET(LET0-0)

原文发表时间:2016-05-10

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏AI研习社

揭开Faiss的面纱 探究Facebook相似性搜索工具的原理

本月初 AI 研习社报道,Facebook 开源了 AI 相似性搜索工具 Faiss。而在一个月之后的今天,Facebook 发布了对 Faiss 的官方原理介...

42710
来自专栏我爱编程

航空公司客户价值分析

项目目标 借助航空公司客户数据,对客户进行分类 对不同的客户类别进行特征分析,比较不同类别客户的客户价值 对不同价值的客户类别提供个性化服务,制定相应的营销策略...

3615
来自专栏新智元

【干货】谷歌 TensorFlow Fold 以静制动,称霸动态计算图

【新智元导读】谷歌日前推出深度学习动态图计算工具 TensorFlow Fold,可以根据不同结构的输入数据建立动态的计算图,简化训练阶段输入数据的预处理过程,...

2933
来自专栏数据派THU

独家 | 教你实现数据集多维可视化(附代码)

翻译:张媛 校对:卢苗苗 用代码将你的数据集进行多维可视化! 介绍 描述性分析是与数据科学或特定研究相关的任何分析生命周期中的核心组成部分之一。数据聚合,汇总...

7919
来自专栏人工智能头条

最全技术图谱!一文掌握人工智能各大分支技术

702
来自专栏企鹅号快讯

AI、神经网络、机器学习、深度学习和大数据的核心知识备忘录分享

来源:深度学习与NLP 在过去的几个月里,我一直在收集AI相关知识,并整理成易于记忆的备忘录。在这期间,我也和我的朋友、同事分享这些备忘录,都反映不错,所以我决...

2025
来自专栏AI科技评论

开发 | 揭开Faiss的面纱 探究Facebook相似性搜索工具的原理

AI科技评论按:本月初AI科技评论曾报道Facebook 开源了 AI 相似性搜索工具 Faiss。而在一个月之后的今天,Facebook 发布了对 Faiss...

4588
来自专栏机器人网

Python最有用的机器学习工具和库

Python是最好的编程语言之一,在科学计算中用途广泛:计算机视觉、人工智能、数学、天文等。它同样适用于机器学习也是意料之中的事。

955
来自专栏Petrichor的专栏

深度学习: 局部响应归一化 (Local Response Normalization,LRN)

局部响应归一化(Local Response Normalization,LRN):

1484
来自专栏数据科学与人工智能

【机器学习】Python语言下的机器学习库

Python是最好的编程语言之一,在科学计算中用途广泛:计算机视觉、人工智能、数学、天文等。它同样适用于机器学习也是意料之中的事。 当然,它也有些缺点;其中一个...

23210

扫码关注云+社区