导航:首页 > 源码编译 > unity3d图片压缩算法

unity3d图片压缩算法

发布时间:2023-01-31 19:35:36

‘壹’ unity图片压缩格式和内存计算

例子2:使用RGB ETC 4bit压缩,占用内存 = 0.5Bytes 512 512 = 128KB

一、2的N次方大小的图片会得到引擎更大的支持,包括压缩比率,内存消耗,打包压缩大小,而且支持的力度非常大。

二、减小图片的占用大小和内存方式有:图片大小变化(Maxsize),色彩位数变化(16位,32位),压缩(PVRC)。

三、U3D对于图片的格式是自己生成的,而并不是你给他什么格式,他就用什么格式,一张1024 1024图在无压缩格式下,它会被U3D以无压缩文件形式存放,也就是说U3D里的Texture Preview里显示的占用大小 *MB不只是内存占用大小,还是空间占用大小

U3D的内部机制为自动生成图片类型来替换我们给的图片,在图片的压缩方式上需要进行谨慎的选择。

压缩格式在U3D的Component Reference里有介绍我就不再详细介绍,只介绍几个重点的:

RGBA32格式为无压缩最保真格式,但也是最浪费内存和空间的格式。Automatic Turecolor和它一个意思。

RGBA16格式为无压缩16位格式,比32位节省一半的空间和内存。Automatic 16bits和它一个意思。

RGBA Compressed PVRTC 4bits格式为PVRTC图片格式,它相当于把图片更改了压缩方式新生成了一个图片来替换原来的我们给的图片格式(比如我们给的是PNG格式)。

注意:U3D所有图片的压缩格式都会以另一种方式来存储,不会以你给的方式来存储,只有你指定了某种格式,它才会转成你要的格式。而且压缩格式在Android里并不一定有效,因为Android的机型多,GPU的渲染方式也不一样,有的是Nvidia,有的是PowerVR,最最好的在安卓机子上启用RGBA16方式,因为这个是适应所有机型的,并且比32位占用量少一半,但也需要因项目而异,只是推荐使用的格式,可以多用,但要权衡内存和显示效果。

‘贰’ 有关图片压缩整理

有损压缩:是指对图像的压缩过程中,算法丢失一部分图像信息,降低了图像的质量,并且这种损失是不可逆的。有损压缩可以减少图像在内存和磁盘中占用的空间。使用有损压缩的图片如果在屏幕上显示,可能肉眼看起来影响不大,但如果用高分辨率打印机打印出来,那么图像质量就会有明显的受损痕迹

无损压缩:是指对图像的压缩过程中,不丢失图片原本的信息,任何时候都可以从无损压缩过的图片中恢复出原本的信息;无损压缩虽然能减小图像占用磁盘的大小,但不能减少图像占用的内存空间,因为实际的显示过程中,看图软件会先把图片还原成原本的信息。无损压缩能较好的保存图片质量,但压缩率较低

索引色:用一个数组来代表一种颜色,在存储图像的时候,存储一个数字的组合,同时存储数字到图像颜色的映射。这种方式只能存储有限种颜色,通常的用法是256种颜色

直接色:使用四个数字来代表一种颜色,这四个数字分别代表颜色中的红色R、绿色G、蓝色B以及透明度A。所以直接色可以表示2^32种颜色。当然,并非所有的直接色都直接这么多种变化,为压缩空间,可能有多种设定

点阵图:也叫位图,象素图。构成点阵图的最小单位是像素,位图就是由像素点阵列的排列来实现其显示效果。点阵图缩放会失真

矢量图:也叫做向量图。矢量图并不记录画面上每一点的信息,而是记录元素的形状以及颜色的算法,当你打开一副矢量图的时候,软件对图像对应的函数进行运算,将运算结果显示给你看,无论显示画面是大还是小,画面对应的算法是不变的,所以对画面进行倍数相当大的缩放,其显示效果仍然相同(不失真)

介绍了这些,那么我们来看看我们经常见到的图片的一些特性

JPEG 有损,直接色,点阵图 ;BMP 无损,直接色,点阵图;PNG-8 无损,索引色,点阵图;PNG-24 无损,直接色,点阵图

为什么png还有多种样式?那是因为PNG算法在把图像转化成图片的时候有很多参数和方式可以选择,这些参数和方式就决定了图像的压缩和成像品质

Android平台默认支持格式:JPEG、PNG、GIF、BMP 和 WebP

iOS平台默认支持格式:JPEG、JPEG2000、PNG、GIF、BMP、ICO、TIFF、PICT、APNG、SVG、RAW

既然Android和iOS支持这么多图片格式,那么游戏中为什么没有”直接”使用JPEG或者PNG这两种都支持格式呢?下面进行下原因的分析

常见的图片文件格式,比如PNG,JPG,BMP等,是图像为了存储信息而使用的对信息的特殊编码方式。它存储在磁盘中,或者内存中,但是并不能被GPU所识别。这些文件格式当被读入后,还是需要经过CPU解压成bitmap,再传送到GPU端进行使用。

一般在游戏中,有很多透明物件,而JPEG不支持透明度,所以没法使用

PNG格式支持透明度,但是因为PNG的压缩算法是根据图片整体进行压缩(比如采用霍夫曼编码),像素和像素之间存在依赖关系,无法直接实现单个像素级别的解析,这就没办法发挥显卡的优势

间接寻址

上图为间接寻址模式中获取颜色数据的过程:GPU首先请求加载索引数据14;一旦有了索引数据就可以立即加载实际颜色值,来回四次最终得到颜色值。索引数据可能为FIFO缓冲区引入了性能隐患,芯片端保存颜色表的代价也十分大,颜色表可能和纹理缓存占的空间接近;所以最好避免使用颜色表这些全局数据。

无论是JPEG或者PNG 的图片最终在显卡解码之后,都是RGBA纹理,(宽*高*4)无法减小显存的占用(256×256像素的图片,虽然文件格式、磁盘占用、内存占用大小不一样,但都是占用256Kb的显存空间,性能消耗大)

jpeg和png图片,从文件加载的时候都必须先在cpu先解码成原始的RGB(A)格式的数据

纹理压缩之后占用显存减少,一种比较简单的统计方案。你直接查看纹理压缩文件的大小就好了,比如纹理压缩文件是170k,那显存占用也是170k

正是因为传统的图片并没有考虑显卡的这种特性,所以很难满足三维应用中的要求,要满足显卡能使用的纹理格式,应该具有以下特点:

在纹理操作中,读取纹理数据是关键步骤,所以解码速度至关重要,这一点是最应该考虑的

能快速的随机读取任意像素,因为显卡中很多操作都是针对单个像素执行的,所以这一点也很重要

既要保证一个不错的压缩效果,也要把纹理损失控制在一定范围内

通常纹理压缩在渲染前已经提前准备好,所以如果压缩的速度比解析速度慢,也是可以接受的。

说明:Unity在导入图片后,编辑器会卡住弹出一个进度条窗口,就是使用原图进行纹理压缩然后生成新的图片文件的过程。生成的文件的位置,你可以根据导入图片对应的.meta文件内的guid,去项目中的Library文件夹中查找,Unity打包图片的Assetbundle其实是根据这个文件来打包的,这已经不是你导入的那张原图

纹理压缩不同于其他图片压缩方式(jpg,png),在使用中,不会在CPU中进行解压缩,而是直接把压缩内容传给GPU,而且在GPU中也不会一次把整张图片进行解压缩,只会在需要采样特定区域的纹理时对这一区域的纹理进行解压缩。

为了满足以上4点,图形工程师开发了很多种纹理压缩格式,目前移动设备主流的纹理压缩格式有PVRTC、ETC/ETC2、ASTC,当然,还有其他的类型(比如:RGBA32、RGBA16、Alpha8等有兴趣的可以去了解下)

纹理压缩格式不需要CPU解码

ETC/ETC2纹理压缩格式

说到ETC ,就要说到OpenGL ES,OpenGL ES 是 OpenGL 三维图形 API 的子集,针对手机、平板和游戏主机等嵌入式设备而设计. OpenGL ES2 支持ETC 格式,所以我们可以在支持OpenGL ES2的显卡的设备上使用ETC这种纹理压缩格式;而ETC2 则需要OpenGL ES3才能支持,而OpenGL ES3已经发布了三四年,所以现在市面上的显卡都支持,也就是说,现在市面上的移动设备都支持ETC2这种纹理压缩格式了,可以放心使用了;

ETC不支持透明通道,所以以前很多项目的做法是用2张纹理来保存一张图片。ETC+Alpha8的组合形式,然后用自定义Shader合并。不过现在基本淘汰,可以直接使用ETC2代替。

Alpha压缩率适用机型

ETC1N6:1OpenGLES 2.0支持几乎所有市面上的Android机,所有iPhone

ETC2Y6:1OpenGLES3.0支持大部分高端Android机,iPhone 5S及以上

PVRTC纹理压缩格式

iPhone的图形芯片(PowerVR MBX)对 PVRTC 的压缩提供硬件支持,Apple推荐在开发iPhone应用程序时使用 PVRTC 压缩纹理格式。而且,根据图像成图质量以及占用内存等,有多种格式可选择(pvtrc_rgba2,pvrtc_rbga4等);缺点是需要图片的长宽相等而且为2的幂次方(针对这种情况,可以考虑把图片打包在一张2的幂次方图集内)

支持的Android机型需要GPU为 PowerVR系列

在实际游戏引擎内(以Unity为例),图片显示流程大概是:原图 —> 纹理压缩(ETC/ETC2等)—>OpenGL ES3—>显卡—>游戏内显示;

而一张图片在游戏引擎中运行时占用的显存大小,与这种图片本身占用磁盘大小无关,只和图片的宽和高相关;

图片导入到Unity引擎中,之所以很慢,是因为在进行纹理压缩编码生成新的文件,这一步很耗时间;

AssetBundle打包图片,不是打包原图,而是针对你对图片设置的纹理压缩格式而生成的新的文件打包,所以ab文件的大小也和原图本身占用磁盘大小无关;

AssetBundle文件的大小与加载成正比关系,同时,纹理压缩格式的解码时间也有差异(差异不是很大)

平台的最佳纹理压缩格式是:astc_rgba_4x4 它兼顾了成像质量,内存占用,ab大小,解码时间,跨平台等因素

‘叁’ 一张图片放到Unity3D中为什么会变大许多

存储容量是存储格式的容量
资源容量是资源格式的容量

肯定是某种存储格式的容量,jpg或者png之类的。4M,八成是 贴图资源格式RGBA的容量。
资源格式可以直接对应到数据结构,在内存或者显存中使用。存在文件类型里的都是存储格式,资源格式可以作为存储格式使用,反之不一定行
存储结构适合传输,不止是硬盘。资源结构指的是内存或显存,适合计算。
png jpg 这种结构 都不适合这个计算,所以没有硬件使用这种结构来做贴图

那为什么我选compress要比RGBA占内存小?
因为压缩比例不一样

‘肆’ unity 图片里formart下compressde和truecolor的区别

个人理解就是Compress是Unity用自带的图片压缩算法(Compress是用RGB Compressed ETC4 算法压缩的)重新压缩一遍图,Truecolor是用RGB 24bit 压缩算法处理导入的图片

如果想要导入的图片小(直接影响输出的程序安装包大小),对清晰度要求不大,可以用compressed,如果是UI界面的图片等要求清晰度高的,建议用TrueColor。

‘伍’ unity图集在ios下需要压缩吗

没硬性规定说要遵循2条件遵循没
1 图片要2幂比128X128, 256X256128X256 ,512X512等等遵循没UNITY3D自帮调整2幂

2 图片越数据量越所要尽量控制影响效前提越越WINDOWS图片支持4096X4096IOS支持2048X2048IOS屏幕像素没所图片太没意义拜拜浪费电脑资源

‘陆’ 【Unity】图片压缩的解决方案

公司做的项目需要拍照生成精灵,流程是客户端先拍照,压缩后上传给服务器,然后由服务器的图像识别算法进行生成裁剪后的精灵与精灵身上的器官坐标点。

问题来了,客户端拍出来的照片太大,普遍是2M-5M,所以客户端拍出来的照片需要经过压缩才能上传给服务器。

在网上寻找图像压缩的解决方案,最终暂定有三种方案:

第一种方案
由于PC端运行时用的是DGI图像接口,不能调用System.Drawing库,所以暂时否定第一种方案

第二种方案
理论
第三种方案由于需要付费,并且服务器稳定性不可控,暂定为优先级最低的方案,目前正在研究第二种方案

‘柒’ (转)Unity 图片压缩技巧

转自 移动设备压缩纹理使用技巧

压缩纹理能够节约不少内存空间,因此目前项目中UI全都是用Texture Packer打包出大图之后压缩。Unity导入纹理的默认设置是compress,在符合条件的情况下会优先使用PVR或ETC、否则会降为RGBA4444。从程序的角度来说,当然是1/4大小的压缩纹理更好啦~但是,毕竟是有损压缩,会带来一定的损失,有时候还是挺郁闷的。

第一个常见的问题是渐变颜色区域经过压缩之后会出现色阶,如下图所示。我参考了dither思路,用Photoshop加了一层0.3%的高斯分布杂音;可以看到ETC和PVR都有所改进,但是仔细盯着看依然能看到一些噪声。

另一个很常见的问题就是有杂色(下图绿色部分),本质是在某些block里边界混合了…解决方法就是非常粗暴的放大分辨率,可以看到当放大到2x大小的时候就完全没问题了。这个事情桌子很早也和我提过,压缩纹理的UI部分最好放大一些,当超采样来用…

顺便再提一句就是,新版本的Texture Packer里有了polygon布局,还能扣洞真是excited…

ps. 最早我们使用的是将原始图片拆分成RGB和Alpha Mask两张图的策略,然后替换默认的UI Shader。但是Unity-5.2开始默认将ETC2设为默认(顺便支持了ETC1 Compression for Sprite Atlases),所以我就懒得切图+每个Sprite拖材质球了…直接一张RGBA进行压缩完事儿

阅读全文

与unity3d图片压缩算法相关的资料

热点内容
以前手机号换了要怎么登录农行app 浏览:192
线切割编程系统怎么绘画 浏览:233
如何搭建云服务器异地容灾 浏览:923
黄金拐点指标源码 浏览:91
算法导论第九章 浏览:276
鸽子为什么生成服务器没反应 浏览:490
freebsdnginxphp 浏览:215
噪声消除算法 浏览:607
vue类似电脑文件夹展示 浏览:112
后备服务器有什么功效 浏览:268
连不上服务器怎么连 浏览:600
什么构架的可以刷安卓系统 浏览:771
爱奇艺APP怎么兑换CDK 浏览:994
程序员买4k显示器还是2k显示器 浏览:144
python多进程怎么多窗口 浏览:818
电脑文件夹怎么取消类别 浏览:47
cad拉线段命令 浏览:924
如何用电脑清理手机没用的文件夹 浏览:100
储存层次结构对程序员的意义 浏览:477
微信文件夹查看器 浏览:952