但是,它与常规压缩(例如png,jpeg)有何不同?
#1 楼
正如西蒙(Simon)的评论所暗示的那样,硬件纹理压缩与其他常用图像压缩之间的一个主要区别是前者不使用熵编码。熵编码是使用较短的位字符串来表示源数据中常见的或重复的模式-如在容器格式(例如ZIP),许多常见的图像格式(例如GIF,JPEG和PNG)以及许多常见的音频中可以看到和视频格式。熵编码擅长压缩各种数据,但本质上会产生可变的压缩率。图像的某些区域可能没有多少细节(或者您所使用的编码模型可以很好地预测出细节)并且需要很少的位,但是其他区域可能具有复杂的细节,需要更多的位进行编码。这使实现随机访问变得困难,因为没有直接的方法来计算在压缩数据中可以找到给定(x,y)坐标的像素的位置。而且,大多数熵编码方案都是有状态的,因此不可能简单地在流中的任意位置开始解码;您必须从头开始建立正确的状态。但是,纹理采样需要随机访问,因为着色器可以随时从纹理中的任何位置采样。
因此,硬件压缩而不是熵编码,而是使用固定比率的基于块的方案。例如,在DXT / BCn压缩中,纹理被切成4×4像素块,每个像素块以64位或128位编码(取决于选择哪种格式);在ASTC中,不同的格式使用4×4到12×12的块大小,并且所有块均以128位编码。位如何表示图像数据的详细信息在格式之间有所不同(甚至在同一图像中从一个块到下一个块也可能有所不同),但是由于该比率是固定的,因此硬件很容易计算在内存中找到该块的位置包含给定的(x,y)像素,并且每个块都是独立的,因此可以独立于任何其他块进行解码。
硬件纹理压缩的另一个考虑因素是解码应该有效可在硬件中实现。这意味着强烈反对繁重的数学运算和复杂的数据流。例如,可以通过对每个块执行少量的8位整数数学运算来填充较小的查找表,然后仅按像素查找适当的表项来解码BCn格式。这需要很少的片上面积,这很重要,因为您可能希望并行解码多个块,因此需要解码硬件的多个副本。
相反,基于DCT的格式(例如JPEG)每个像素需要大量的数学运算,更不用说一个复杂的数据流,该数据流在一个块内的像素之间交换和广播各种中间值。 (有关DCT解码的一些细节,请参阅本文。)这对于硬件实现而言会是很多麻烦,我想这就是为什么AFAICT(没有GPU硬件曾经实现基于DCT或基于小波的纹理压缩)的原因。 。
评论
$ \ begingroup $
极好的答案。您还可以添加一些论文,其中提到在某些情况下您可以自己压缩并使用像素着色器中的客户端代码对其进行解码,而不必依赖于专用硬件。我不知道在现实世界中不会使用它,这可能仅值得研究,但它确实存在。
$ \ endgroup $
–v.oddou
2015年9月28日,下午3:25
$ \ begingroup $
@ Nathan-Reed基于变换的压缩,实际上,Microsoft的Talisman项目使用了称为TREC的压缩方案(作为一种模式)使用DCT,但与JPEG不同,它允许随机访问块(我怀疑必须有是包含地址的表)。然后,这将允许为各个块使用可变长度的数据,但是这种间接操作对于硬件来说是令人不快的-这是VQ TC过时的原因。 FWIW我尝试了大约12个TC创意B4 PVRTC;有些是固定速率的,基于变换的,但是“丢失”的系数仍然使用位。类似BTC的固定coeff位置表示“免费”信息。
$ \ endgroup $
–西蒙F
15年9月29日在6:08
$ \ begingroup $
@ Nathan-Reed。从我所看到的,所有硬件解码器都可以使用纯逻辑路径(数据路径中的位解码,一些查找,一些数学运算)来实现,而无需循环/寄存器。您是否知道有任何方案会增加周期延迟到纹理查找? (我很有趣地实现了VHDL ETC1解码器)我的印象是每个纹理单元(TU)都嵌入了解码器。
$ \ endgroup $
–罗曼·皮奎斯(Romain Piquois)
2015年9月30日14:06
#2 楼
“(硬件)纹理压缩的工作原理”是一个大话题。希望我能在不重复Nathan回答内容的情况下提供一些见解。要求
纹理压缩通常不同于“标准”图像压缩技术,例如JPEG / PNG有四种主要方式,如Beers等人的“从压缩纹理渲染”所述:
解码速度:您不希望纹理压缩变慢(至少不会如此明显) ),而不是使用未压缩的纹理。解压缩也应该相对简单,因为它可以帮助实现快速解压缩而又不增加硬件和电源成本。如果访问的纹素的某个子集M来自图像中间,则很重要的是,不必为了确定M而不必解码纹理的所有“先前”线条;对于JPEG和PNG,这是必需的,因为像素解码取决于先前解码的数据。
请注意,这仅仅是因为您具有“随机”访问权限,并不意味着您应该尝试完全采样
>压缩率和视觉质量:Beers等人(令人信服地)认为,为了提高压缩率而在压缩结果中损失一些质量是一个值得权衡的问题。在3D渲染中,数据可能将要进行处理(例如,过滤和着色等),因此质量的损失可能会被掩盖。
非对称编码/解码:尽管也许更具争议性,但他们认为可以接受比解码慢得多的编码过程。考虑到解码需要以硬件填充速率进行,这通常是可以接受的。 (我承认,以最高质量压缩PVRTC,ETC2和其他一些压缩文件可能会更快)
早期历史和技术
有人知道纹理压缩已经存在了三十多年,这可能会让某些人感到惊讶。 70年代和80年代的飞行模拟器需要访问相对大量的纹理数据,并且考虑到1980年的1MB RAM> 6000美元,减少纹理覆盖区至关重要。再举一个例子,在70年代中期,即使是少量的高速存储器和逻辑,例如足够用于适度的512x512 RGB帧缓冲区)可以让您背上小房子的价格。包括:
数学/过程纹理合成的简单形式,
b。使用单通道纹理(例如4bpp),然后将其乘以每个纹理的RGB值,
c。 YUV和
d。调色板(文献表明使用Heckbert方法进行压缩)
对图像数据建模
如上所述,纹理压缩几乎总是有损耗的,因此问题就成为其中之一。尝试以紧凑的方式表示重要数据,同时处理次要信息。下面将要描述的各种方案都有一个隐式的“参数化”模型,该模型近似纹理数据和眼睛响应的典型行为。
此外,由于纹理压缩倾向于使用固定速率编码,因此压缩过程通常包括一个搜索步骤,以找到参数集,当输入到模型中时,这些参数集将生成一个很好的近似值。原始的纹理。但是,该搜索步骤可能很耗时。(除了optipng之类的工具外,这是PNG和JPEG的典型用法与纹理压缩方案不同的另一个领域)
在进一步发展之前,为了帮助进一步了解TC,值得研究一下主成分分析(PCA),这是一种非常有用的数据压缩数学工具。
示例纹理
要比较各种方法,我们将使用以下图像:
请注意,这是一个相当困难的图像,尤其对于调色板和VQTC方法而言,因为它跨越了RGB的大部分彩色立方体,只有15%的纹理像素使用重复的颜色。
PC和(90年代中期以后)控制台纹理压缩
为了降低数据成本,一些PC游戏和早期游戏控制台还使用了调色板图像,这是矢量量化(VQ)的一种形式。
基于调色板的方法假定给定图像仅使用RGB(A)色块的相对较小的部分。调色板纹理的问题是,对于所获得的质量,压缩率通常相当适中。压缩为“ 4bpp”(使用GIMP)的示例纹理产生了
再次注意,对于VQ方案,这是相对困难的图像。
具有较大矢量的VQ(例如2bpp ARGB)
尽管VQ可以在〜2bpp的条件下达到令人满意的质量,但是这些方案的问题在于,它需要依赖的内存读取:从索引图中进行初始读取以确定像素的代码,然后是a第二个是实际获取与该代码关联的像素数据。额外的缓存可以帮助减轻某些延迟,但会增加硬件的复杂性。
使用2bpp Dreamcast方案压缩的示例图像为
。
索引图为: VQ数据的压缩可以通过多种方式完成,但是IIRC,上述操作是使用PCA来进行的,然后沿着主矢量将16D矢量划分为2组,例如两个代表性向量使均方误差最小。然后重复该过程,直到产生256个候选向量为止。
然后应用了全局k均值/劳埃德(Lloyd)算法来改进代表。
颜色空间变换
颜色空间变换也利用PCA指出颜色的全局分布通常沿主轴分布,而沿其他轴的分布则少得多。对于YUV表示,假设如下条件:a)主轴通常在亮度方向上,并且b)眼睛对该方向的变化更敏感。
3dfx Voodoo系统提供了“ YAB”一种8bpp的“窄通道”压缩系统,该系统将每个8位纹理像素拆分为322格式,然后将用户选择的颜色变换应用于该数据,以将其映射为RGB。因此,主轴具有8个级别,较小的轴每个都有4个级别。
S3 Virge芯片具有稍微简单的4bpp方案,允许用户为整个纹理指定两种最终颜色。 ,应位于主轴上,并带有4bpp单色纹理。然后,将每个像素的值与适当的权重混合以产生RGB结果。
基于BTC的方案
回溯了几年,Delp和Mitchell设计了一个一种简单的(单色)图像压缩方案,称为块截断编码(BTC)。本文还包括一种压缩算法,但就我们的目的而言,我们主要对生成的压缩数据和解压缩过程感兴趣。
在该方案中,图像通常分为4x4像素块,实际上可以使用局部VQ算法独立对其进行压缩。每个块由两个“值” a和b以及一组4x4索引位表示,这些索引位标识每个像素要使用两个值中的哪个。
S3TC:4bpp RGB(+ 1bit alpha)
尽管提出了几种用于图像压缩的BTC颜色变量,但我们很感兴趣的是Iourcha等人的S3TC,其中一些似乎是对Hoffert等人的一些被遗忘的工作的重新发现。 Apple的Quicktime。
没有DirectX变体的原始S3TC将RGB或RGB + 1位Alpha的块压缩为4bpp。纹理中的每个4x4块均由两种最终颜色A和B代替,固定重量的线性混合可从中获得最多两种其他颜色。此外,该块中的每个纹理像素都有一个2位索引,该索引确定如何选择这四种颜色中的一种。
例如,以下是使用AMD / ATI Compressenator工具压缩的测试图像的4x4像素部分。 (从技术上讲,它取自测试图像的512x512版本,但请原谅我没有时间更新示例)。
说明了压缩过程:计算颜色的平均值和主轴。然后执行最佳拟合,以找到“位于”轴上的两个端点,以及两个派生的这些端点的1:2和2:1混合(或在某些情况下为50:50混合),最小化错误。然后将每个原始像素映射到这些颜色之一以产生结果。
如果在这种情况下,通过主轴合理地逼近这些颜色,则误差将相对较低。但是,如果像下面所示的相邻4x4块中的颜色更加多样化,则误差会更高。
使用AMD Compressonator压缩的示例图像产生:
由于每个块的颜色都是独立确定的,因此在块边界处可能会出现不连续性,但是,只要保持足够高的分辨率,这些块伪影可能就不会被注意到: br /> Ericsson Texture Compression也适用于4x4的纹理像素块,但假设与YUV一样,局部纹理像素的主轴通常与“ luma”密切相关。然后可以仅通过平均颜色和像素在该假定轴上的投影的高度量化的标量“长度”来表示一组像素。
由于相对于S3TC这样可以降低数据存储成本,因此它允许ETC引入分区方案,从而将4x4块细分为一对水平4x2或垂直2x4子块。这些都有自己的平均颜色。
示例图像产生:
喙周围的区域还说明了4x4块的水平和垂直分区。
Global + Local
有些纹理压缩系统在全局方案和局部方案之间是有交叉的,例如Ivanov和Kuzmin的分布式调色板的方案或PVRTC的方法。
PVRTC:4和2 bpp RGBA
PVRTC假定(实际上,双线性)放大图像是对全分辨率目标的良好近似,并且近似值与实际分辨率之间的差异目标(即增量图像)是局部单色的,即具有主导主轴。此外,它假设可以在图像上插入局部主轴。
(要做:添加显示分解的图像)
使用PVRTC1 4bpp压缩的示例纹理产生:
喙周围区域:
与BTC方案相比,通常会消除块状伪影,但是如果源图像中存在强烈的不连续性(例如在lorikeet头部的轮廓周围),有时可能会出现“过冲”。
2bpp该变体的误差自然高于4bpp(请注意,靠近脖子的蓝色高频区域的精度损失),但可以说质量仍然合理: >
尽管上述方案的压缩算法具有中等至较高的评估成本,但解压缩算法(尤其是对于硬件实现而言)相对便宜。例如,ETC1只需要几个MUX和低精度加法器。 S3TC有效地多了一些添加单元来执行混合;和PVRTC,再增加一点。从理论上讲,这些简单的TC方案可以使GPU架构避免在解压缩阶段之前进行解压缩,从而最大限度地提高内部缓存的效率。
其他方案
其他应当提及的常见TC模式为:
ETC2-是ETC1的(4bpp)超集,可改善对颜色分布与'luma'不一致的区域的处理。还有一个支持1位alpha的4bpp变体,以及用于RGBA的8bpp格式。
ATC-实际上是S3TC的一个很小的变体。
FXT1(3dfx)是S3TC主题的一个更宏大的变体。
BC6和BC7:一个支持ARGB的8bpp,基于块的系统。除了HDR模式外,它们还使用比ETC更复杂的分区系统来尝试更好地模拟图像颜色分布。
PVRTC2:2&4bpp ARGB。这引入了其他模式,包括克服图像边界强的限制的一种模式。
ASTC:这也是一个基于块的系统,但是稍微复杂一点,因为它具有大量针对大范围bpp的可能的块大小。它还具有一些功能,例如多达4个带有伪随机分区生成器的分区区域,以及索引数据和/或颜色精度和颜色模型的可变分辨率。
评论
$ \ begingroup $
哇,这应该是某个地方的博客文章!好答案!
$ \ endgroup $
–glampert
2015年10月8日在18:39
$ \ begingroup $
很高兴能提供帮助。至于博客,我十年前确实写过这篇文章,但是我真的没有时间去做。
$ \ endgroup $
–西蒙F
2015年10月9日在8:01
$ \ begingroup $
托管旧博客的网站已死。这是最新的存档版本:web.archive.org/web/20160322090245/http://web.onetel.net.uk/…
$ \ endgroup $
–ahcox
20-2-5在1:38
评论
什么是“普通压缩”-诸如JPEG和PNG之类的东西?您是在问那些与DXT和ASTC等硬件支持的格式之间的区别吗?(最后,我对此有所了解!)与PNG / JPEG不同的是随机访问。如果您要访问Texel(X.Y),则可以快速确定生产该texel所需的少量数据。 JPG或PNG可能需要解压缩所有数据! Wikipedia文章的第1部分和第2部分是一个很好的摘要。
正如SimonF所写。这是一个非常广泛的问题,答案取决于您对哪种类型感兴趣。 DXT?