[Unity优化]图片压缩格式

1.参考资料

游戏中的压缩纹理格式:https://www.cnblogs.com/zblade/p/10308038.html

[Unity优化] unity图片压缩格式和内存计算:https://www.jianshu.com/p/92fc1442a63e

学习笔记——Unity3D内存优化(贴图优化):https://blog.csdn.net/qq_39824797/article/details/84339886

Unity优化之贴图:https://www.cnblogs.com/ssw-men/p/10472007.html

Uinty3D性能优化之贴图科普篇:https://blog.csdn.net/acuriousguy/article/details/109492105

2.总结

(1)图片格式描述

图片文件的存储格式:用于图片文件的存储和传输,通常在磁盘文件,内存以及网络传输中使用。

常用的图像文件格式有BMP,TGA,GIF,JPG(有损不透明),PNG(无损透明)等;

(2)纹理格式描述

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

常用的纹理格式有R5G6B5,A4R4G4B4,A1R5G5B5,R8G8B8, A8R8G8B8等。

占用空间:R5G6B5,A4R4G4B4,A1R5G5B5每个像素占用2个字节(BYTE),R8G8B8每个像素占用3个字节,A8R8G8B8每个像素占用4个字节

 

例如:对于一个512 * 512大小的纹理,如果使用R5G6B5的纹理格式,其大小为512 * 512 * 2 = 512KB, 用A8R8G8B8, 就是1M,可以预见,游戏中占用容量最大将是各种纹理,很容易导致游戏安装包突破上G,为了缩小纹理格式的数据占用的内存大小,对应的压缩纹理格式产生了。注意,这不是在移动游戏出现后才产生的,早在PC端游戏时代就有压缩纹理格式

(3)压缩纹理格式

<0>移动GPU的四大厂商

<1>基于OpenGL ES的压缩纹理格式

 

ETC1(Ericsson texture compression)

不支持透明通道,所以仅能用于不透明纹理,OpenGL2.0支持

这种压缩纹理格式是OpenGL ES的图形标准,被所有的android设备支持,不支持透明通道,每个像素0.5个字节

 

ETC2

针对ETC1不支持透明通道的改进,用ETC2可以支持透明通道,不过要求OpenGL ES3.0及以上(Android4.3+),目前基本覆盖率在9成以上

 

 

PVRTC(PowerVR texture compression)

支持GPU为PowerVR SGX系列,基本的压缩参数有:

RGB_PVRTC_4Bit, RGB, 每个像素0.5个字节

RGB_PVRTC_2Bit, RGB, 每个像素0.25个字节

RGBA_PVRTC_4Bit, RGBA, 每个像素0.5个字节

RGBA_PVRTC_2Bit, RGBA, 每个像素0.25个字节

 

ATITC(ATI texture compression)

支持GPU为Qualcomm的Adreno系列, 基本的压缩参数有:

ATC_RGB_AMD, RGB, 每个像素0.5字节

ATC_RGBA_EXPLICIT_ALPHA_AMD, RGBA, 每个像素1个字节

ATC_RGBA_INTERPOLATED_ALPHA_AMD, RGBA, 每个像素1个字节

 

ASTC

目前各大厂商主推的压缩纹理格式,压缩质量高,压缩块方案多,代价是压缩时间长(需要不断尝试压缩结果,算法决定)

 

DXTC(又名S3TC,S3 texture compression)

是一种有损纹理压缩算法,可以说DXT是目前应用最广泛的纹理压缩格式,可以认为所有的PC端显卡都支持DXT压缩。在多数纹理压缩选择中都是最佳方案,几乎可以认为是PC下的标准压缩格式。

基本的压缩参数有:

RGB_S3TC_DXT1, RGB, 每个像素0.5个字节

RGBA_S3TC_DXT1, RGBA, 每个像素0.5个字节

RGBA_S3TC_DXT3, RGBA, 每个像素1个字节

RGBA_S3TC_DXT5, RGBA,每个像素1个字节

<2>Unity纹理格式总结

每位的像素点(bpp)是单个像素所需的存储量。该值越低,可以在GPU的缓存中存储的像素越多,从而可以更快地进行纹理访问。

可变比特率(VBR)表示每个像素的比特不是固定值,而是取决于实际内容。VBR仅适用于Crunch压缩,并且仅适用于磁盘上的纹理大小。内存中的大小与使用基础纹理格式时的大小相同(例如,对于RGB Crunched DXT1,使用RGB Compressed DXT1)。

Crunch compression是DXT或ETC Texture压缩之上的一种有损压缩格式(部分数据在压缩过程中丢失)。纹理在CPU上被解压缩为DXT或ETC,然后在运行时加载到GPU。

Crunch compression有助于Texture使用尽可能少的磁盘空间,但对运行时内存使用没有影响。

Crunch compression可能需要很长时间才能压缩,但是在运行时进行解压缩非常快。

质量和压缩时间之间的平衡:质量越高,文件大小越大。为了获得最佳性能,尤其是在移动设备上,请使用应用程序所针对的硬件所支持的每像素位数最少的格式,只要该格式能够提供足够的视觉质量即可。

 

<3>推荐使用的压缩纹理格式

[1]描述

移动端:android使用ETC2, ios使用PVRTC或者ASTC

PC端:DXT

[2]具体

通常

清晰度

1.(高清晰无压缩)采用RGBA32

2.(中清晰中压缩)RGBA16+Dithering 要采用Floyd Steinberg抖动处理,不然渐变很明显,拉伸就会差距

3.(低清晰高压缩)ETC2 PVRTC

4.ASTC压缩率和清晰度都会比较好,支持的GPU :

tvOS (all), iOS (A8以上,5S以下), Android (PowerVR 6XT, Mali T600 series, Adreno 400 series, Tegra K1)

2016年之后的安卓手机基本支持这种压缩格式

iphone6以及之后的机型支持这种压缩格式

 

例子:

(4)图片格式和纹理格式关系

没有关系。如果图片要传输给显卡使用,则必须转换成显卡能够识别的纹理格式,这个在游戏引擎中,会对应自动转换,也可以通过相关的代码设置显式的转换。

这样的过程,有一个问题,就是加压缩,解码,重新编码压缩的过程比较消耗CPU,如果在游戏总实时的执行这样的一个过程,会出现明显的卡顿掉帧。

一般在项目中,在资源导入或者打bundle的时候,会执行相关配套的纹理格式转换,最终打入游戏包或者Bundle中的是已经预先转换好的纹理格式,这样加载的时候优化了解码和转换的过程,能够提高加载速度。这也是为什么不同平台的bundle不能跨平台使用的原因之一。

注:使用目标平台支持的纹理压缩格式时,GPU可以直接使用它,没有增加消耗;

如果目标平台不支持纹理压缩格式时,默认会将纹理解压成RGBA32或RGB32,然后与压缩的纹理一起存储在内存中,会增加纹理加载时间和增加额外内存



 

posted @ 2021-07-21 11:14  微臣做不到  阅读(1624)  评论(0编辑  收藏  举报