ASTC纹理压缩格式(Adaptive Scalable Texture Compression)

Posted ZJU_fish1996

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ASTC纹理压缩格式(Adaptive Scalable Texture Compression)相关的知识,希望对你有一定的参考价值。

原文:这是一个pdf的下载链接

介绍

        Adaptive Scalable Texture Compression(ASTC)是一种世界领先的新型纹理压缩格式。这种压缩格式已经加入Khronos标准,并已在某些硬件平台中提供。本文介绍了它的工作原理、使用方法和如何最大程度地使用它。更深入的信息可以参考编码器提供的规范[Eva]。

背景

        ASTC由ARM Limited针对目前已有的填充率较低的纹理压缩开发的一种灵活解决方案。在过去,不同的纹理压缩方法往往仅在一种或多种特定的数据通道和相关比特率的组合情况下表现较好。

        更糟糕的是,许多格式是平台专有的,限制了特定供应商的可用性,导致应用程序在安装后必须根据检测到的可用格式通过网络来获取其它资产。

        ASTC的核心基础是它可以压缩每种(表1.1)常用格式的输入图像,并以用户选择的任何比特率输出该图像,从8bpp到0.89bpp。如果是3D纹理,则为0.49bpp(表1.2)。

      

        低于1bpp的比特率是通过智能的可变块大小系统实现的。大多数基于块的纹理压缩方法具有单个固定的块大小,但是ASTC可以存储从4x4到12x12任意大小的块(包括非正方形块大小)的规则网格图像。ASTC还可以存储3D纹理,块大小从3x3x3到6x6x6不等。不论块的尺寸如何,它们始终以128位存储,因此比特率会按比例变化。

算法

        块中的每个像素点被定义为一对边界色上线性梯度的量化点,这允许非常平滑的着色区域。对于包含完全不同颜色区域的边界的块,它可以使用2048种颜色中的一种,将当前块分为1~4种不同的颜色梯度。

        这些块是通过算法生成的,选择正确的块进行压缩是减少计算时间的核心。该技术允许一个块包含完全不同色调的区域,这些色调具有任意着色或多个相交的不同色调的硬边色块。

        每个块最多定义四个颜色和一个分布图案id,以便每个像素都知道它们使用哪些对颜色来定义自己的颜色。然后,每个像素的值量化到0~1之间,以表示它们在像素之间的梯度上。由于每个128bit块中包含边界色和独立像素的变量,块中每个像素的精度量化为剩余可用数据大小。

        在压缩期间,算法必须选择正确的分布图案和边界颜色对,然后为每个像素生成量化值。在选择图案和边界颜色时要进行一定程度的反复测试,并且在压缩时,在压缩时间和最终图像质量之间要进行权衡。质量越高,算法在决定哪个最好之前可尝试更多的选择。无论压缩需要多长时间,解压缩时间都是固定的,因为图像数据始终可以通过一次遍历从图案和边界颜色重新推算出来。

        压缩算法还可以使用不同的指标来判断不同测试的质量,从使用信噪比,到偏向人类视觉的感知判断。该算法还可以单独而非整体判断各个通道,以保留纹理通道的细节,其中各个通道用作着色器程序的输入数据;或减少角度噪声,这对于切线空间的法线贴图很重要。

        总体而言,正确使用这些选项相比现有的压缩算法有明显的改进,如图1.2所示。

开始

        下载评估压缩程序[Eva]之后,可以使用命令行界面来压缩纹理。该程序支持png, target, jpeg, gif(仅非动画),Radiance HDR,Khronos Texture KTX , DirectDraw Surface DDS和Half-Float-TGA。对OpenEXR也有有限的支持。

        astcenc应用程序提供了可用命令行参数的完整列表,最基本的命令是:

astcenc -c <input.file> <output.file> <rate> [options]

       -c告诉程序压缩第一个文件,然后将压缩后的文件保存到第二个文件中。速率用于确定块大小,可以直接选择为块大小,例如5x4或3x3x3,或者可以为算法指定bpp并以此为目标并自动选择。比特率必须始终保持小数点后一位,从8.0到0.8(对3D纹理,可以低至0.6)。

        如果希望解压缩纹理以查看时,可使用如下命令:

astcenc -d <input.file> <output.file> [options]

        在这个例子里,-d意味着解压,输入文件是已经被压缩过的纹理,输出文件是非压缩格式的一种。

        要查看给定一组选项下纹理压缩后的效果,使用如下命令:

astcenc -t <intput.file> <output.file> <rate> [options]

        -t 选项意味着使用给定选项压缩文件,然后立即将其解压缩为输出文件。临时压缩图像不会保存,且输入和输出文件均为解压缩文件格式。

        选项可以不填,但要获得较好的效果,有几个需要注意的:

        最有用的预设是质量预设:

        -veryfast

        -fast

        -medium

        -thorough

        -exhaustive

        有许多可用的选项可以设置各种压缩质量因子,包含:

        要尝试的块分区图案的数量和范围;

        各个信噪比的临界值,以提前退出独立的决策阶段;

        不同边界颜色测试的最大迭代次数;

        大多数用户不会花时间寻找满足自己需求的最佳组合。因此,可以使用预设质量来提供一些高级提示,从而获取单个独立的质量因子。

        需要注意的是,veryfast几乎是瞬时完成的,但仅对一小部分输入图像给出了良好的结果。相反,较高的质量级别(准确地对每个块执行所有可能的边界模式组合)花费的时间要长的多,但和thorough模式下压缩地文件相比,可见差距较小。

使用ASTC纹理

        ASTC功能是一项从2013年下半年开始提供的新硬件功能。要立即开始使用ASTC,可从ARM网站上获得e ARM R MaliTM OpenGL R ES 3.0 Emulator [Ope ],它与ASTC纹理格式兼容,因此可以使用标准台式机GPU来测试基于ASTC的程序。

        以ASTC格式加载的纹理和其它压缩纹理格式没有什么不同,但是必须使用正确的内部格式。压缩程序输出的文件有一个数据头,其中包含加载压缩纹理所需的所有内容。

        使用清单1.1中的数据结构,应用程序可以检测ASTC纹理所需的重要信息。可参阅Mail开发人员中心网站以获取源代码示例。

质量设置

        本文已经提到了一些高级质量设置,但有更精确有针对性的方法可以调整压缩器输出的质量,命令行压缩程序具有两个主要类型的参数:搜索参数和质量指标。

        压缩纹理的算法在很大程度上取决于反复的尝试。比较多种块分区和边界颜色的组合,并使用该块的最佳组合。增加搜索参数将比较更多组合以找到正确的组合,从而使算法能够找到更好的匹配项,但同时也延长了搜索时间(因此延长了压缩时间)。

        plimit是每个块找到最好分区之前所能测试的最大分区数。

        dlimit是一个块的PSNR的临界值,以db为单位。如果块尝试的PSNR超过此值,则算法会认为它足够好并使用该组合,由于算法可能首先达到其它限制,因此可能不一定达到此PSNR。

        oplimit通过比较单分区和双分区之间的错误来作为临界值。也就是说,如果双分区错误比单分区错误严重得多,则可能就不至于去尝试三个或四个分区了。oplimit定义了放弃分区时的错误严重程度。

        mincorrel定义了颜色系数的相似度,该算法将尝试将其拟合到单个颜色平面中。该数字越小,同一平面上的颜色就越多,因此算法将不会尝试使用更大数量的分区来测试该块。

        bmc是要尝试的块模式的临界值。块模式定义了如何为每个图案使用不同的二进制模式来对各个颜色值进行精确的加权。

        maxiters是针对任何给定分区尝试将颜色细化为颜色和权重次数的临界值。

 

        可以单独设置这些值,使其在特定方向上扩展搜索,例如:

        具有许多细微细节的纹理应该具有较高的oplimit值,以确保细微的颜色变化不会被划分同一分区平面中。

        具有非常随机图案纹理,可能需要搜索更多的分区类型以找到合适的纹理。

         我们通常会使用一些质量预设作为默认设置,如表1.3所示,利用这些参数设置可以在质量和压缩时间之间寻求一个平衡。搜索的限制越大,算法接受当前块为“足够好”的块的“意愿”就越低,花更多的时间找到更好的匹配,不过还有另一种获得更好匹配结果的方法,那就是调整质量指标,改变压缩器判断块质量的因子。

通道权重

        最简单的质量因子是通道权重,使用如下命令行参数:

        -ch <red-weight> <green-weight> <blue-weight> <alpha-weight>

        这定义了噪声计算的加权值。例如,参数-ch 1 4 4 1使得绿色通道上的错误为任何给定通道上的噪声的四倍。参数 -ch 0.25 1 0.25 0.25具有相同的效果,它仍然会使绿色通道中的错误发生率高四倍,但总体错误率更低。因此更容易获得足够好的结果。

        使用-esw参数结合使得通道权重工作的更好。对于没有alpha通道的纹理,swizzle -esw rgb1会使alpha通道饱和,并不在随后的噪声计算中对其计数。

块权重

        尽管人的视力对绿色的变化较敏感,而对红色的变化不敏感,但通道加权的作用依然是有限的。

        在许多情况下,其它权重也可以改善压缩纹理的质量。其中之一是块错误检查,尤其是在大面积具有复合渐变的纹理上。默认情况下,没有基于块内部错误的检测权重,两个相邻块边界处的纹理像素可能在其自身纹理像素的误差范围内,但在相邻的位置处具有噪声,这意味着块之间差距比较大。可以使用命令行参数解决:

        b <weight>

        判断块合适性的公式考虑了已经处理过的任何相邻块的边缘。

        但是,这仅会使搜索算法比其它算法更容易接受具有更好匹配边缘的块,但它可能会以其它方式增加噪声。需要注意的是:相邻平滑块对于法线贴图特别有用。

法线权重

        当压缩法线贴图或使用数据信息而非颜色信息的贴图时,有一些参数可以实现多个附加设置。即-normal psnr,-normal percep和-mask。一次只能选择其中的一个,因为它们是互斥的。

        前两种设置针对2通道压缩的法线,它将x和y转换为亮度和alpha,覆盖默认的oplimit和mincorrel,并增加角度误差的权重,这在法线贴图中更为重要。-normal percep参数比较类似,但权重略有不同,是为了获得更好的感知结果。这些可在图1.5中看到。

        这两个方法都使用了隐含的esw rrrg参数将X和Y转换为亮度和alpha,还具有dsw raz1的内部编码转换,将亮度转换为X,将alpha转换为Y,并使用以下方法重构z:

       

        参数rn添加了角度噪声误差度量。其它纹理压缩方法则缺少此选项。一直以来,法线贴图都存在压缩的问题,因为x,y所隐藏的角度分量的细微变化在信噪比计算中会被忽略。

标记通道错误

        参数 -mask告诉压缩器假定输入纹理在每个通道里具有完全不相关的内容,因此,一个通道中的错误影响其它通道是不可取的。

        如图1.6所示,它是位图字体的示例,其中红色通道代表字符,蓝色通过代表发光,绿色代表投影。

        掩码过滤器基于-v和-va的组合。这两个参数可以从较低级的层次访问从块的各个纹理像素差异中收集错误值的方式。完整语法为:

        -v <radius> <power> <baseweight> <avgscale> <stdevscale> <mixing-factor>

        半径是相邻纹理像素的面积,使用以下公式可以将误差的平均偏差和标准偏差相结合:

       

        在计算平均值和标准偏差值之前,将各个误差值提高到幂级别。混合因子用于确定平均之前或之后是否合并各个通道错误。如果混合因子为0,则每个颜色通道都会计算自己的平均值和标准偏差,然后合并到上式中。如果混合因子为1,则在计算单个平均值之前会合并每个通道的误差。介于1和0之间的值可提供这两个值的组合。

        如果仅对一个块求平均值,会得到错误的结果,会导致接受噪声较多的输出。使用给定半径上的标准偏差可以使误差计算可见于纹理像素之间的任何附加噪声,与使用块权重检查块之间的步长变化的方式几乎相同。

        这个平均噪声方程适用于彩色通道,alpha通道是单独控制的,在命令行参数中具有一组相似的值:

        -va <baseweight> <power> <avgscale> <stdevscale>

        -a <radius>

        alpha通道是单独控制的,尤其是对punch through纹理而言,量化噪声可能比边缘柔化更好。

其它颜色格式

        ASTC支持1至4通道的图像,从仅亮度到RGBA。此外,该算法还支持不同的颜色空间编码:

        Linear RGBA

        sRGB + linear A

        HDR RGB + A

        HDR RGBA

sRGB

        ASTC在压缩和解压时都支持非线性sRGB颜色空间转换。

        为了图像在使用结束前都保留在sRGB颜色空间中,只需要以通常的方式压缩它们即可。然后,在加载它们时,使用sRGB纹理格式,而不是常规的纹理格式。这些名称中包含SRGB8 alpha8。每个RGBA格式都有一个等效的sRGB等效项。

        有用的是,sRGB格式的常数始终比RGBA常数大0x0020,而从可以很容易地在两者之间进行编码切换。

        作为在运行时使用sRgb纹理的替代方法,压缩程序还有一个命令行参数,可在压缩之前将其转换为线性RGBA。-srgb参数将转换颜色空间并在线性空间中压缩纹理,以使用常规的RGBA纹理格式加载。

HDR

        ASTC还支持HDR图像格式。使用这些编码无需花费额外的时间,并且可以上述详述的相同加载功能。以HDR格式编码图像时,编码器默认情况下不适用HDR编码。为此,必须使用以下两个参数之一。

        - forcehdr_rgb

        - forcehdr_rgba

        在此模式下,编码器将根据每个块使用HDR或LDR。在-forcehdr rgb模式下,alpha通道(如果存在)将始终被编码为HDR。还有一些更简单的参数:       

        -hdr

        -hdra

        它们等效于-forcehdr rgb和-forcehdr rgba,但对块适用性评估进了其它更改(预设的-v和-a),更适用于hdr图像,也可用:

        -hdr_log

        -hdra_log

        它们是类似的,但其适用性基于对数误差。从数学角度来看,使用此设置编码的图像通常可以提供更好的结果,但在感知伪影方面效果不佳。

3D纹理

        压缩算法还可以在块级别处理3D纹理。

        尽管可以使用其它图像压缩算法来存储和访问3D纹理,但它们会在2D空间中作为一系列单个texel层纹理进行压缩,而ASTC会压缩3维纹理数据块,从而提高了沿着z轴纹理读取的串行纹理读取的缓存命中率。

        目前,并没有太多的3D图像格式可以作为接受的输入,因为对3D纹理进行编码具有特殊的语法:

        -array <size>

        使用此命令行参数,假定输入文件是实际输入的前缀模式,并使用0、1等装饰文件名,一直到<size-1>。因此,例如,如果输入文件是带有参数array 4的slice.png,则压缩算法将尝试加载名为slice0.png,slice1.png,slice2.png和slice3.png的文件。然后,将多个纹理层的存在作为信号,以对请求的速率使用3D块编码。

总结

        本文展示了ASTC相对于其它当前可用纹理压缩方式的优势,并提供了在任意图形项目中可以轻松使用ASTC纹理文件的代码,并详细说明了命令行参数,以充分利用评估编解码器的结果。

        ARM提供了一个免费的纹理压缩工具,该工具可通过图形用户界面(GUI)自动执行本文中介绍的ASTC命令行参数,从而简化了压缩过程,并提供有关压缩质量的视觉反馈。

以上是关于ASTC纹理压缩格式(Adaptive Scalable Texture Compression)的主要内容,如果未能解决你的问题,请参考以下文章

上传ASTC压缩纹理使用glCompressedTexImage2D花费太多时间?

Unity纹理格式之Crunched

还原堆栈信息,分析地形系统使用ASTC格式的纹理导致Crash的问题

unity-贴图压缩格式

unity-贴图压缩格式

unity-贴图压缩格式