[图形学]ASTC纹理压缩格式
纹理压缩的目的
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
- 你所需要了解的几种纹理压缩格式原理
[图形学]ASTC纹理压缩格式相关推荐
- unity 纹理压缩格式‘_[2018.1]Unity贴图压缩格式设置
一.移动平台GPU 参考文档: 各种移动GPU压缩纹理的使用方法 - LuMing - 博客园www.cnblogs.com 1.Imagination Technologies的PowerVR S ...
- Unity常见纹理压缩格式
前言:本人一直对RGB16bit有一个疑惑,比如RGB565其表值范围只有(32,64,32)如何能表示0-255,今天就用这篇文章梳理一下. 预备知识: 一个字节有8位:1byte = 8 bit. ...
- unity 纹理压缩格式‘_纹理优化:让你的纹理也“瘦”下来
在上一期<纹理优化:不仅仅是一张图片那么简单>中,我们针对纹理相关的优化,挑选了部分知识点分析.无论是大家在开发时的疏忽,还是对相关知识点的理解不足,这些问题的积累最终都会反映到项目的性能 ...
- Unity 优化翻译官方文档(二) ------ 平台特定覆盖的纹理压缩格式
官方文档 : https://docs.unity3d.com/Manual/class-TextureImporterOverride.html 虽然Unity支持许多常见的图像格式作为导入纹理的源 ...
- 常用纹理和纹理压缩格式
简单纹理格式 RGBA8888 每个像素4字节,RGBA通道各占用8位 RGBA4444 每个像素2字节,RGBA通道各占用4位 RGB888 每个像素3字节,RGB通道各占用8位,无透明通道 RGB ...
- DXT纹理压缩格式解析
我们知道游戏中对于3D物体表面细节的表现最重要的还是靠贴图来实现的,那么越是高分辨率越是真彩色的贴图自然表现力也是越强,但是同时带来的问题是所需占用的内存会成倍的上升,而节省内存这一点在目前的游戏中还 ...
- 游戏中纹理压缩格式之Texture压缩纹理
记载目录 1.杂言杂语 2.纹理格式与文件格式的区别 3.常见的纹理格式和应用场合及硬件的特定要求常见的压缩纹理格式硬件需求 4.压缩纹理特殊处理RGBA16 + Dithering 处理ETC1的通 ...
- unity-贴图压缩格式
title: unity-贴图压缩格式 categories: Unity3d tags: [unity, ios, astc] date: 2017-12-21 20:09:12 comments: ...
- 【百人计划】图形3.5 纹理压缩的格式
笔记部分> 一.什么是纹理压缩格式(概念) 为了解决内存和带宽问题,在计算机图形渲染中(储存纹理)的一种图像压缩.优化技术. 二.为什么要进行纹理压缩? 对于低硬件设备和移动端,有两个问题需要解 ...
- Unity 之 纹理类型导入设置和压缩格式介绍
Unity 之 纹理类型导入设置和压缩格式介绍 一,纹理相关 1.1 导入设置 1.2 支持格式 二,纹理类型 2.1 纹理类型说明 2.2 纹理尺寸大小 三,所有支持的纹理压缩格式 一,纹理相关 1 ...
最新文章
- 微软语音扩展全球语言支持,发布160个新声音
- nginx配置使用笔记:三
- sql随机查询数据语句(NewID(),Rnd,Rand(),random())
- 9.10 css
- elasticsearch常见报错总结
- mysql导出数据意义_11、mysql导出数据
- 诱导公式的本质【转载】
- cocos2d-x 3.0 画图节点——Node
- (128)System Verilog下降沿检测实例
- 如何查看Hive版本
- ICCV 2019 | ICCV 2019 论文接收列表 | ICCV 2019一共接收1077篇 | 共4303篇投稿
- 公开说说别人看不到_为什么我在QQ空间里面发表说说别人看不到?
- 3DMAX导出插件编写(续)
- 2011 信义聚会记实
- 宝山区企业技术中心、区级工程技术研究中心给予奖励20万元
- C语言中变量的作用域和生存期的区别
- httpqyl.php,php使用base64加密解密图片示例分享_PHP
- 【艾琪出品】《计算机应用基础》【试题汇总1】
- BIOS模式怎么退出
- Whistle pc抓包,手机抓包,https抓包