[自学记录02|百人计划]纹理压缩

news2024/12/26 23:10:04

一、什么是纹理压缩

纹理压缩是为了解决内存、带宽问题,专为在计算机图形渲染系统中存储纹理而使用的图像压缩技术。

1.图片格式和纹理格式的区别

(1)图片格式

图片格式是图片文件的存储格式,通常在磁盘、内存中储存和传输文件时使用;例如:JPG、PNG、GIF、BMP等。

(2)纹理格式

纹理格式是显卡能够直接进行采样的纹理数据格式,通常在向显卡中加载纹理时使用。

2.纹理管线

纹理压缩格式基于块压缩,能够更快读取像素所属字节块进行解压缩以支持随机访问;图片压缩格式基于整张图片进行压缩,无法直接实现单个像素的解析;图片压缩格式无法被GPU识别,还需要经CPU解压缩成非压缩纹理格式才能被识别。

根据老师所讲的内容,我个人倾向于把图片格式理解为顺序表,读取不随机,也就是说使用的时候要进行查找,而纹理格式则不同,它类似于哈希表,GPU可以随机访问,这样大大提高了效率。

二、常见的纹理的格式

1.非压缩格式

2.压缩格式

(1)DXTC

DXTC纹理压缩格式来源于S3公司提出的S3TC算法,基本思想是把4×4的像素块压缩成一个64或128位的数据块,优点为创建了一个固定大小且独立的编码片段,没有共享查找表或其他依赖关系,简化了解码过程。

DXT1格式主要适用于不具透明度的贴图或仅具一位Alpha的贴图(非完全透明则即完全不透明)。

DXT1将每4×4个像素块视为一个压缩单位,压缩后的4×4个像素块占用64位,其中有2个16位的RGB颜色和16个2位索引,如

DXT1中的两个RGB颜色负责表示所在压缩的4×4像素块中颜色的两个极端值(极端值颜色为RGB565格式),然后通过线性插值我们可以再计算出两个中间颜色值,而16个2位索引则表明了这4×4个像素块所在像素的颜色值,(00,01,10,11)可以表示4种状态,刚好可以完整表示color_0color_1以及我们通过插值计算出的中间颜色值color_2和color_3。而对于具有一位Alpha的贴图,则只计算一个中间颜色值color2,而color_3则用来表示完全透明。 
对于如何判断DXT1格式是表示不透明还是具有1位alpha的贴图,则是通过两个颜色值color_0和color_1来实现的,如果color_0的数值大于color_1则表示贴图是完全不透明的,反之则表示具有一位透明信息。  

而对比RGB24的格式,DXT1的压缩比达到了 6:1(24*16 / 64 = 6)


DXT2DXT3可以表示具有更复杂的透明信息的贴图,这两种格式采用的是显式的Alpha表示,我们知道了在DXT1中,我们使用64位数据来描述4*4的像素块的颜色信息,在DXT2DXT3中,这部分颜色信息是不变的,而是通过另附加64位数据也就是每个像素4位来表示他们的Alpha透明信息,而这4位的Alpha的信息通常情况下我们可以采用直接编码的方式来表示即可。 
这样每个4×4像素块占用128位也就是8个字,0~3字表示透明信息;4~7表示前面描述的颜色的信息。 
DXT2DXT3不同之处在于,

DXT2中颜色是已经完成了Premultiplied by alpha操作(已完成颜色与alpha的混合,当透明度发生改变时,直接改变整体颜色值,不必再单独复合)

DXT3的Alpha信息则是相对独立的,之所以要区分开了则是为了适应不同的需要,因为有些场合需要独立的Alpha信息。


DXT4、DXT5也是用于表示具有复杂的透明信息的贴图,与2和3不同的是:4和5的Alpha信息是通过线性插值计算所得,类似于DXT1的颜色信息。同样的,每4×4的像素块的透明信息占用64位,所不同的是,64位中采用了2个8位的alpha值和16个3位的索引值,既然每个像素的索引占3位,那么可以表示8种不同的透明状态。 
在这里插值的方法有两种,一种用于表示具有完全透明和完全不透明的状态,另一种则是仅在给出的极端值alpha_0和alpha_1中进行插值。区分的方法也是通过比较alpha_0和alpha_1的大小来实现的,如果alpha_0大于alpha_1,则通过插值计算剩下的6个中间alpha值;否则,只通过插值计算4个中间alpha值,alpha_6直接赋值0,alpha_7直接赋值255。 
DXT4和DXT5的区别同DXT2和DXT3的区别相同,DXT4的颜色值是理解为已经完成Premultiplied by alpha操作的。 
另外需要注意的是,所有的压缩纹理格式都是2的幂,因为纹理压缩的单位是4×4像素,所以如果贴图的大小位16×2或者8×1这样的比例,系统会同样采用4×4的单位进行压缩,会造成一定的空间浪费,同样的大小会被占用,只是不会参与使用而已。

在Unity内贴图类型选为法线后会采用DXTnm压缩格式,它基于DXT5,该格式会把法线贴图R通道存入A通道,然后RB通道清除为1,这样可以将法线XY信息分别存入到RGB/A中分别压缩,以获得更高的精度,然后再根据XY构建出Z通道数据。

那么对于RGBA32格式,DXT2345的压缩率则为 4 :1    (32/128*16)

参考:DXT纹理压缩_lhc717的博客-CSDN博客

(2)ATI1/2(BC4/5)

ATI1(BC4),主要用于压缩高度图、法线图等具有单一灰度通道的纹理贴图,采用固定32字节块的压缩方式,每个块可以压缩4x4像素纹理数据。在每个压缩块中,只需要2个红色分量存储压缩后的数据,可以用两个8位整数、一个16位的整数、或者一个12位整数和一个4位整数存储这些数据。因此,在使用ATI1压缩算法时,搭配的纹理比原始纹理小约75%,这大大减少了存储空间的需求。

ATI1尤其适用于包含高度信息的纹理(如Displacement Maps),但对最终图像制品的视觉影响很小。不过,因为它不能进行色彩太多变化的压缩,所以它不适合用于HDR纹理(高动态范围纹理)。

总体而言,ATI1能够提供比较小的文件尺寸和较低的显存占用,同时还能满足设计师对细节的需求。

ATI1的压缩率:单通道8位:(64位/16像素) = 2  :  1


ATI2(BC5),主要用于压缩法线图和切线空间贴图等具有两个灰度通道的纹理贴图,采用固定块大小的压缩方式,每个块可以压缩4x4像素纹理数据。在每个压缩块中,采用两个分离的压缩算法(RG存储分别经过压缩的正半球和负半球法向量)。然后再对编码后的R通道和G通道进行解压合成Z轴信息得到完整的归一化法线向量。每个R和G通道都可以用3个8位整数、或者一个10位整数和一个6位整数存储,使得最终的压缩结果无需外部计算即可直接读取。

相比于ATI1,ATI2增加了红色和绿色Two-Step交替方法进行压缩,获得了更高的压缩率和更好的细节表现。但由于使用了两个分离的压缩算法,所以在解压的时候还需要进行额外的操作。另外,ATI2作为一种压缩纹理格式,对于最终的图像质量还需要在算法上进行精度控制和优化平衡。

ATI2的压缩率:双通道8位(16位):(2*64位/16像素) = 2  :  1

                         双通道16位(32位) :(2*64位/16像素) = 4  :  1


(3)BC6/7

BC6和BC7的官方原理说明:

BC6H 格式 - UWP applications | Microsoft Learn

BC7 格式 - UWP applications | Microsoft Learn


(4)ETC

上述我们说的DirectX选择了DXTC作为标准压缩格式,那对于OpenGL则选择了爱立信研发的ETC格式,几乎所有的安卓设备都可以支持ETC压缩,所以其在移动平台上被广泛应用;

ETC方案与DXTC具有相同特点,将4×4的像素单元压缩成64位数据块,并将像素单元水平或竖直朝向分为两个区块,每个像素颜色等于基础颜色加上索引指向的亮度范围。

第一行:24位 颜色信息(RGB444 * 2 或 RGB333 + RGB555)

第二行:32位 像素索引信息

第三行:8位 亮度索引信息

ETC1针对RGB24格式进行压缩,压缩后的结果是64位数据块的16个像素。

所以ETC1的压缩比为 6  :  1

因为ETC压缩在安卓上的良好兼容性和不错的效果,目前大多数安卓平台手游都采用了ETC压缩方案,但为了解决ETC1不支持Alpha的问题,我们可以采用两张纹理混合的方式来实现带Alpha通道的压缩。

ETC1和ETC2的差别

ETC1要求长宽为2的次幂的贴图,它适用于所有安卓设备,压缩率比较高,但不适用于带Alpha通道的贴图。ETC2是ETC1的扩展,它要求长宽都能被4整除的贴图,且硬件要求OpenglES3.0和Opengl4.3以上,支持Alpha通道的压缩,但它的内存占用大于ETC1。

(5)ASTC

ASTC128位数据块中存储的信息:

11位:权重、高度信息,特殊块标识;

2位:Part数量

4位:16种插值端点模式(如LDR/HDR,RGB/RGBA)

111位:插值端点信息,纹素权重值,配置信息 

详情参考:

 ASTC纹理压缩格式详解 - 知乎 (zhihu.com)


(6)PVRTC 

PVRTC旨在减少纹理数据的存储空间和带宽需求,从而提高性能和降低功耗。

PVRTC压缩算法包括两种版本:PVRTC1和PVRTC2。这里我们主要介绍PVRTC1的工作原理。

PVRTC1支持两种压缩比,4bpp(每像素4位)和 2bpp(每像素2位)。我们以4bpp为例:

压缩后的64位数据块中包含A,B两张图像,A和B都是在原本的基础上长和宽分别压缩了4倍后得到的低分辨率图像,A占了14位(RGB:554,RGBA:4433),B占了15位(RGB:555,RGBA:4443),同时对于16个像素,每个像素存储了2位调制数据(00,01,10,11),可以表示4个状态。同时还有一位的调制模式0/1,在不同调制模式下,4个状态可以得到不同的混合值,最终通过得到的混合值和A,B的颜色值可以得到最终的混合值,还有2位分别在A,B上表示不透明标值,用来判断是RGB存储还是RGBA存储,至于采用哪一个,会选用A和B中位数更高上面的不透明标值。

PVRTC2相较于PVRTC1有所改进,主要表现在颜色空间处理、边缘处理等方面,以获得更高的图像质量。总之,PVRTC通过将纹理划分为小块并利用颜色插值以及模拟像素技术,实现了较高的压缩比,从而降低了存储和带宽需求。这对于移动设备来说尤为重要,因为它们通常具有有限的硬件资源。

PVRTC1-4bpp的压缩率:对于RGB24,压缩率为24/4也就是 6  :  1

                                         对于RGBA32,压缩率为32/4也就是 8  :  1

三、总结

1.画质比较

RGBA > ASTC 4×4 > ASTC 6×6 > ETC2 ≈ ETC1

2.压缩比

DXT1    6:1                DXT2/3    4:1

DXT4/5    4:1                 ATI1 4:1

ATI2     4:1                      BC6 6:1

BC7    3:1                      PVRTC 6:1

ASTC       4:1~35.95:1

3.适配

英伟达和Unity官方对于不同类型贴图给出了不同的压缩方案建议,感兴趣的同学可以看下:

Using ASTC Texture Compression for Game Assets | NVIDIA Developer

Unity - Manual: Recommended, default, and supported texture compression formats, by platform (unity3d.com)

参考:

3600_纹理压缩_哔哩哔哩_bilibili

PPT:3600百人计划-纹理压缩 (qq.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/603894.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

单片机GD32F303RCT6 (Macos环境)开发 (三十三)—— 光照传感器 (BH1750)

GD32 光照传感器 BH1750的使用 1、GPIO模拟i2c配置 使用管脚为SCL PB10 SDA PB11,移植代码时可换自己的管脚。软件模拟i2c在十九章中讲过,与其不同的地方是,这里的us延时函数,换成了定时器3做us级的延时。 tim3的配置&#xf…

linux 找回root密码(CentOS7.6)

linux 找回root密码(CentOS7.6) 首先,启动系统,进入开机界面,在界面中按“e”进入编辑界面。如图 2. 进入编辑界面,使用键盘上的上下键把光标往下移动,找到以““Linux16”开头内容所在的行数”,在行的最后…

java-字符流和字节流(二)

java-字符流和字节流(二) 一、字节缓冲流 1.1字节缓冲流构造方法 字节缓冲流介绍 BufferOutputStream:该类实现缓冲输出流。 通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用 BufferedIn…

chatgpt赋能python:Python动图如何优化SEO?

Python动图如何优化SEO? Python是一种高级编程语言,广泛应用于数据分析、人工智能和网站开发等领域。Python还支持创建动态图像,这些动态图像通常用于数据可视化、演示和教育目的。在本文中,我们将探讨如何使用Python创建动态图像…

chatgpt赋能python:Python加f之SEO的重要性

Python加f之SEO的重要性 随着互联网的不断发展和普及,越来越多的企业和个人纷纷进入到了网站建设,网络营销的大军之中。而SEO作为重要的一环,在各个领域内也变得愈加重要。而Python中的f字符串是近些年来引起广泛关注的一种新的字符串格式化…

chatgpt赋能python:Python动态内存分配:如何优化你的代码

Python动态内存分配:如何优化你的代码 在编写Python代码时,你可能已经注意到内存使用方面的一些问题。Python动态内存分配是一个重要的话题,它涉及到Python程序如何在运行时使用内存。本文将向您介绍Python动态内存分配的基本概念和如何优化…

chatgpt赋能python:Python动态代码在SEO中的重要性

Python动态代码在SEO中的重要性 Python是一种非常流行的编程语言,用于开发Web应用程序、数据分析、人工智能和机器学习。Python的动态代码能够动态生成HTML、CSS和JavaScript来创建动态网页。这种能力使Python在SEO中非常有用,因为它可以帮助网站排名更…

chatgpt赋能python:如何使用Python制作动画?

如何使用Python制作动画? Python是一种高级编程语言,被广泛应用于各种领域,包括动画制作。Python的简洁性和强大的功能使得它成为一个很好的选择来制作动画。在这篇文章中,我将向您介绍使用Python如何制作动画。 第一步&#xf…

Vue3 相关Composition Api 2

一,其他Composition Api shallowReactive 与 shallowRef shallowReactive:只处理对象最外层属性的响应式(浅响应式)。 shallowRef:只处理基本数据类型的响应式,不进行对象的响应式处理。 什么时候使用? 如果有一个对…

Hive

Hive 概览 Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供类SQL查询功能。 本质是将SQL转换为MapReduce程序。 主要用途:用来做离线数据分析,比直接用MapReduce开发效率更高。 架构 数…

chatgpt赋能python:用Python制作动画,你不可错过的工具

用Python制作动画,你不可错过的工具 Python是一种高级编程语言,最初被设计用于编写自动化脚本和简化复杂任务。然而,如今它越来越多地被用于创意和艺术性的项目,甚至是动画制作。 Python在动画制作中的优势一直受到赞誉。它是一…

辅助驾驶功能开发-功能算法篇(2)-ACC-状态机跳转设计

1、ACC状态介绍 ALOD_MODE (ACC状态) 状态说明OFF ACC关闭状态,此时ACC图标不显示,且其他相关信号都发默认值。此状态下车辆完全由驾驶员控制。 PassiveACC已由驾驶员开启,但有抑制条件(如安全带、车门)满足&#xff0…

chatgpt赋能python:Python制作录屏软件,让你的屏幕动作不再错过

Python制作录屏软件,让你的屏幕动作不再错过 作为一名Python工程师,你可能有很多需要记录屏幕操作的场景,比如演示软件或者录制教学视频。那么,有没有一款Python制作的录屏软件来满足你的需求呢?答案是肯定的&#xf…

K-means聚类算法原理、步骤、评价指标和实现

1、聚类 聚类与分类不同,聚类分析分通过分析大量含有一定规律但杂乱数据,得到数据间内在的逻辑,将杂乱的数据按照所得的数据规律划分成不同的种类。K-measn、DBSCAN和层次是当前广泛使用的三种聚类方法。以下对三种方法进行分析,…

Mybatis 如何实现返回多个结果集——详测版

文章结构 本文介绍一个在 Mybatis 中不常见的操作,但是可能有些朋友刚好需要用到,Mybatis 如何实现返回多个结果集 什么情况会返回多个结果集: 存储过程多个 select 语句 具体过程如下(作者实测:跟着观战就完事了&a…

chatgpt赋能python:Python:一个强大、适用广泛的编程语言

Python:一个强大、适用广泛的编程语言 作为一种高级编程语言,Python 可以轻松地完成许多计算机编程任务。它是一种协作和代码重用的语言,Python旨在提高生产力并减少缺陷。 对于那些想要学习编程语言的人来说,Python 是非常适合…

Class源码

介绍 如果想要在程序运行阶段访问某个类的所有信息,并支持修改类的状态或者行为的话,肯定会用到反射,而反射靠的就是Class类。 通过Class类可以获取类的实例,构造方法,字段,成员方法,接口等信…

网络编程知识点总结(3)

socket 服务器的开发步骤和代码实现 1.创建套接字 socket()函数 int socket(int domain, int type, int protocol); domain: 指明所使用的协议族,通常为 AF_INET,表示互联网协议族(TCP/IP 协议族)AF_INET IPv4因特网域. AF_INET6 IPv6 因特网域 AF_U…

屏幕录制安卓应用被发现在监视用户

据 ESET 的研究人员称,一款在 Google Play 商店中下载量超过 50,000 次的屏幕录像机应用程序被发现使用设备的麦克风悄悄地录制音频并窃取文件,这表明它可能是间谍活动的一部分。 iRecorder 是一个合法的应用程序,于 2021 年 9 月可用&#…

chatgpt赋能python:Python动态函数介绍

Python动态函数介绍 Python是一种高级编程语言,它支持动态函数。动态函数就是在Python中可以在运行时创建函数。这意味着编程者可以在编写代码时不必事先定义所有函数,而是可以通过Python函数来创建函数。 Python动态函数的一个好处是可以轻松地编写可…