[图形学]ASTC纹理压缩格式

article/2025/11/10 7:56:36

纹理压缩的目的

1,降低内存,特别是移动端应用,内存占用不应过大,否则低端机很容易崩溃
2,降低带宽,手游类应用,在渲染时会有大量贴图传输到GPU,不限制的话不仅会严重影响渲染性能,同时会带来很严重的发热

因此我们需要一种内存占用既小又能被GPU读取的格式——压缩纹理格式。纹理压缩对应的算法是以某种形式的固定速率有损向量量化(lossy vector quantization )将固定大小的像素块编码进固定大小的字节块中。
有损表示对于渲染来说,有损压缩是可以接受的,一般选择压缩格式时需要在纹理质量和文件大小上寻求一个平衡。
固定速率压缩指的是什么呢?因为GPU需要能够高效的随机访问一个像素,这意味着对任意像素,解码速度不该有太大的变化。因此,我们常见的贴图压缩算法都是有损压缩。相反的例如zip则是一种可变速率压缩。
向量量化(Vector quantization, VQ)是一种量化技术,将一组大量的点(向量)分成具有近似相同数量的最接近它们的点的组。每个组用它的质心点表示,因此存在数据误差,适用于有损压缩。放到纹理压缩中来理解,就是例如将4x4块像素的颜色以2个基色来表示。

编码和解码速度。一般来说编码速度慢没关系,因为通常纹理压缩只需要在游戏打包时进行一次,对于用户运行时体验完全没有影响。但解码速度必须足够快,而且基本上不能影响到渲染性能。

压缩比:通常以比特率或每像素的平均比特数(bits per pixel, bpp)表示,常见的为2~8bpp。一般RGB原生纹理的像素指24位,4bpp表示每像素占4位,所以也可以认为4bpp表示压缩比为6:1。

ASTC纹理压缩格式简介

ASTC(Adaptive Scalable Texture Compression),由ARM和AMD联合开发,2012年发布。是一种基于块的有损压缩算法。它的压缩分块从4x4到12x12最终可以压缩每个像素占用1bit以下。
ASTC格式支持RGBA,适用于POT和NPOT纹理。
在这里插入图片描述

上图展示了不同Block Size下每个像素占用的bits。易知,Block Size越大,压缩的越厉害。
以ASTC 4*4 Block Size为例,可以看到每个像素占用8bits即1个字节。因此一张1024*1024的RGBA图片按照该格式压缩后占用的内存大小为1MB。

nvidia官方对ASTC格式有详细的说明:astc-texture-compression-for-game-assets

适配机型

1,iOS
苹果从A8处理器开始支持ASTC,即iPhone6和iPad mini 4及以上的设备都支持,ASTC格式在iOS设备上的显示效果比PVRTC的效果要好很多(PVRTC格式存在两个大问题:首先是透明贴图在iOS上显示比较模糊,失真;另一点是对于颜色比较丰富的图,特别是UI,颜色过渡大的区域会出现色阶问题,目前的方案一般是拆分Alpha通道,见这里:IOS下拆分Unity图集的透明通道(不用TP)),Unity 分离贴图 alpha 通道实践。因此在当前情况下iOS上可以全部使用ASTC作为纹理格式。

2,安卓
安卓中所有支持OpenGL ES 3.1及以上的设备,和大部分支持OpenGL ES 3.0的设备都支持ASTC。因此在安卓上需要根据具体情况来设置纹理压缩格式,一般而言若项目依旧要考虑第三世界国家和低端机型,就要退而求其次使用ETC2格式进行压缩。

Unity官方对纹理压缩格式的选择和底层的一些异常处理都做了详细的说明:Recommended, default, and supported texture formats, by platform

其它

  • POT 和 NPOT
    虽然ASTC支持POT和NPOT,但是在项目中能使用POT的情况下尽量使用POT,这涉及到更复杂的图形学原因。这里引用一下一位知乎匿名用户的解释,OpenGL支持非二次幂纹理的底层原理是什么?

这个问题其实与GPU的寻址方式(地址对齐要求)有关,并非是图形API层面的限制。
GPU作为一种专用的绘图硬件(当然现在也在逐渐泛用化),其高速运作的能力来自于对于特殊目的定制的特殊硬件模块。其中,实现贴图参照的模块就是这么一种特殊的硬件模块。
在CPU当中,当要参照一张贴图的时候,你需要在程序当中给出计算地址的公式。比如,当你要访问一张宽度为w高度为h的以行优先顺序存储的贴图当中的坐标为(x,y)的贴图的时候,就需要用y*w+x来计算这个地址。这个计算公式是以代码的形式给出的,对于CPU来说,它只是将这张贴图作为一个连续的内存空间处理而已。
但是GPU不同。GPU当中完成对贴图访问(寻址以及获取数据)的模块是以硬件形式存在的。它是不可编程的,你只能从它所提供的几种方式当中选一种。这是第一个因素。
其次,GPU当中进行的是大量的并行计算。这就意味着GPU经常会需要对贴图的不同位置进行同时参照。而且,这种参照往往是需要截取贴图当中一小块面积的内容,也就是是一种2D甚至是3D形状的参照,按CPU那种1D线性的方式保存贴图的话,会使得要参照的那一小部分地址不连续,从而影响高速缓存的命中率,降低速度。
所以,贴图在GPU的内存(显存)当中,一般都不是以行优先或者列优先方式存储的,而是以“块”为单位存储的。就好像一块一块马赛克组成的墙面那样,每个马赛克对应的像素在内存上是连续存储的。这是第二个因素。
此外,为了尽可能节约内存开销和传输带宽,贴图一般都会以一种合适的压缩格式存储。而常用的压缩格式,如BC或者DXT,都是将贴图分块进行压缩。这同样隐含了贴图必须是这些“块”的整数倍这样一个条件。这是第三个因素。
上述几个因素(硬件寻址+贴图在内存上的特殊排布方式+压缩算法要求)决定了一款GPU在设计的时候就会将这个“块”的最小尺寸固定下来。有的GPU是2x2像素,有的是4x4像素,还有的是8x8像素。所以当贴图的尺寸不是这些“块”的整数倍的时候,当贴图被传送到GPU内存(显存)的时候,就会被拉伸或者在四周(一般是右侧和下侧)填充无用数据,使其成为这些“块”的整数倍。(称为pitch)
这个情况是GPU硬件的要求,与使用何种图形API无关。但是诸如OpenGL这种抽象等级较高的图形API在易用性和可控性之间选择了易用性,也就是尽力隐藏这些细节,在其内部为你完成必要的拉伸或者pitch的操作,从而使得你觉得好像它支持非二次幂的纹理。

  • 为什么我们不使用png、jpg这类常见的压缩格式?
    尽管像jpg、png的压缩率很高,但并不适合纹理,主要问题是不支持像素的随机访问,这对GPU相当不友好,GPU渲染时只使用需要的纹理部分,我们总不可能为了访问某个像素去解码整张纹理吧?不知道顺序,也不确定相邻的三角形是否在纹理上采样也相邻,很难有优化。这类格式更适合下载传输以及减少磁盘空间而使用。

参考文档

  • ASTC纹理压缩格式详解
  • Compressed GPU texture formats – a review and compute shader decoders – part 1
  • 你所需要了解的几种纹理压缩格式原理

http://chatgpt.dhexx.cn/article/5wGOOmIS.shtml

相关文章

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

原文:这是一个pdf的下载链接 介绍 Adaptive Scalable Texture Compression(ASTC)是一种世界领先的新型纹理压缩格式。这种压缩格式已经加入Khronos标准,并已在某些硬件平台中提供。本文介绍了它的工作原理、使用方法和如何最大程度地使用它。更深入的信…

ASTC纹理压缩格式介绍

一、ASTC纹理压缩格式介绍 ASTC是在OpenGL ES 3.0出现后,在2012年中产生的一种业界领先的纹理压缩格式,它的压缩分块从4x4到12x12最终可以压缩到每个像素占用1bit以下,压缩比例有多种可选。ASTC格式支持RGBA,且适用于2的幂次方长宽…

选择软件人力外包公司看这几点没错

近几年,大数据、云计算等各种互联网技术飞速发展,深入到我们工作生活的各个角落。很多企业为了提升竞争力也加快了信息化建设的步伐,而信息化建设的关键就是软件人才,谁能快速构建真正高效的软件开发团队,谁就能先一步…

10 个Web3 设计灵感网站

10 个Web3 设计灵感网站:Cosmos、Axies Infinity、DeSo Foundation、Foundation App、Llama、Snapshot、Juicebox、Alchemy、RabbitHole 正如Twitter前首席执行官Jack Dorsey最近发的一条推文“你不拥有web3,但风险投资家拥有”,而Marc Andre…

web 服务器有哪些

<1>什么是web服务器 "网络服务"&#xff08;Web Service&#xff09;的本质&#xff0c;就是通过网络调用其他网站的资源。 Web Service架构和云 如果一个软件的主要部分采用了"网络服务"&#xff0c;即它把存储或计算环节"外包"给其他…

要不要进外包?

互联网行业的估计都听过这句话:外包&#xff0c;你是外包&#xff0c;麻烦不要偷吃公司零食&#xff0c;注意素质&#xff01; 事情是这样的:她说自己被外派到一家大公司上班&#xff0c;因为那家公司是大公司&#xff0c;在休息的时候还提供零食和下午茶。大家都知道女生爱吃…

为什么程序员做外包会被瞧不起?

二哥&#xff0c;有个事想询问下您的意见&#xff0c;您觉得应届生值得去外包吗&#xff1f;公司虽然挺大的&#xff0c;中xx&#xff0c;但待遇感觉挺低&#xff0c;马上要报到&#xff0c;挺纠结的。 以上是读者小 K 给我发的私信。除此之外&#xff0c;还有个读者 down 也问…

被迫选择了到了外包公司

即使大厂裁员下来的员工愿意被迫选择了到了外包公司&#xff0c;迫不得已做外包的工作&#xff0c;那么&#xff0c;中小型企业那势必也得裁员&#xff0c;为了接收从大厂下来的&#xff0c;有大厂背景的员工&#xff0c;那么就会裁掉自己公司的员工。 这样看来&#xff0c;这…

测试应届生是去自研小公司好还是外包公司好?

我不知道当年怎么想的&#xff0c;能在一个外包公司一干就是3年&#xff0c;后来终于跳出来了&#xff0c;现在的公司虽然不是什么大厂吧&#xff0c;但至少是个正经的互联网企业&#xff0c;待遇也不错。其实很多地方的朋友都有提到外包公司的一些弊端。 外包公司&#xff1a…

网站建设公司该不该把web前端外包出来!精辟

如今的网站建设公司其实过的并不好&#xff0c;一些建站平台、模板建站、仿站等都对网站定制造成了比较大的影响&#xff0c;网站建设公司如何降低用人成本、灵活的整合第三方资源成为度过“特殊时期”的重要手段&#xff0c;迎接下一波春天的到来。 网站建设公司该不该把前端…

外包公司面试门槛高吗?软件测试员进外包公司容易吗?

虽然很多测试人员都抵制外包&#xff0c;但实际情况则是依旧有大量软件测试员&#xff0c;选择加入到外包这个圈子。外包公司面试门槛高吗?外包公司容易进吗?本篇来解答一下这个问题。 外包公司面试门槛高吗&#xff1f; 外包的面试门槛&#xff0c;相对大厂要低很多。尤其…

我的web前端工作日记11------在腾讯外包的这一年

说在前面的话 本文只是大概说一下自己在腾讯做了一年前端外包的收获和一些心得感悟&#xff0c;希望自己能客观的描述&#xff0c;能给一些后来者参考取舍&#xff0c;看是否值得去腾讯做外包。写的没啥逻辑&#xff0c;都是想到啥就写啥&#xff0c;所以大家将就着看看。 一…

进程平均周转时间的计算

题目&#xff1a; 有4个进程A,B,C,D,设它们依次进入就绪队列&#xff0c;因相差时间很短可视为同时到达。4个进程按轮转法分别运行11,7,2,和4个时间单位&#xff0c;设时间片为1。四个进程的平均周转时间为 &#xff08;&#xff09;&#xff1f; 分析 要理解周转时间的含义&am…

操作系统进程完成时间,周转时间,带权周转时间, 平均周转时间, 带权平均周转时间计算

计算规则 周转时间作业完成时刻-作业到达时刻&#xff1b; 带权周转时间周转时间/服务时间&#xff1b; 平均周转时间作业周转总时间/作业个数&#xff1b; 平均带权周转时间带权周转总时间/作业个数&#xff1b;

平均周转时间和平均带权周转时间怎么算?

周转时间&#xff1a;从作业被提交给系统开始&#xff0c;到作业完成为止的这段时间间隔称为作业周转时间。 带权周转时间&#xff1a;即作业的周转时间T与系统为它提供服务的时间Ts之比&#xff0c;即W  T/Ts 周转时间 作业完成时刻 - 作业到达时刻带权周转时间 周转时间…

操作系统:周转时间和其他时间

1&#xff0c;周转时间 周转时间&#xff1a;作业被提交给系统开始&#xff0c;到作业完成为止的这段时间间隔。 包括&#xff1a;&#xff08;1&#xff09;作业在外存后备队列上的等待作业调度的时间。&#xff08;2&#xff09;进程在就绪队列上等待进程调度的时间。&#x…

多种调度算法的平均周转时间算例

有5个批处理的作业&#xff08;A、B、C、D和E&#xff09;几乎同时到达一个计算中心&#xff0c;估计的运行时间分别为2、4、6、8、10分钟&#xff0c;它们的优先数分别为1、2、3、4、5&#xff08;1为最低优先级&#xff09;。对下面的每种调度算法&#xff0c;分别计算作业的…

FCFS计算周转时间、带权周转时间、平均周转时间和平均带权周转时间。

#include<stdio.h> #include<string.h> #include<conio.h> main() {char pn[10][10],t[10];int arr[10],bur[10],star[10],finish[10],tat[10],wt[10],i,j,n,temp;int totwt0,tottat0; //clrscr();printf("请输入进程数量:");scanf("%d"…

周转时间 平均周转时间 带权周转时间 平均带权周转时间

1.周转时间 2.平均周转时间 平均周转时间是对n个而言的 3.带权周转时间 真正的运行时间指的是进程占有处理机的时间 4.平均带权周转时间 即n个平均的带权周转时间

【周转时间、平均周转时、带权周转时间和平均带权周转时间的计算】

一个作业到达后就是一个作业的提交时间&#xff0c;从提交时间起到开始执行之间的时间为等待时间。开始执行到执行完毕之间为执行时间。作业执行完毕的时间即为完成时间。 1.周转时间:作业到达后到作业完成的时间。 周转时间完成时间-提交时间 周转时间执行时间等待时间 2.平…