关于图像文件格式和纹理格式

图像文件格式:BMP、JPG、PNG、TGA

说明:文件格式 是为了存储到物理磁盘使用的特殊编码格式

GPU 访问不能直接读取文件编码格式的图像文件,CPU 读入后需要特殊的解码操作 然后传输给GPU

纹理是一种能够被GPU 快速识别的像素格式,能够被快速寻址采样。

格式   压缩模式   交错支持  透明支持   动画支持
JPG   有损压缩   支持         不支持       不支持
PNG  无损压缩   支持         支持           不支持

BMP  无压缩     不支持      不支持        不支持

TGA  无损压缩  不支持      支持            支持

NPOT纹理是一种纹理,其尺寸不是2的幂(两个非幂)。在早期的硬件中,要求纹理的尺寸是两个大小的幂。NPOT纹理是不限于两个幂的纹理

POT 纹理 ,其尺寸是2的整数幂。

GPU再处理纹理数据 会以POT形式,如果是NPOT形式 会经过转化为POT形式

NPOT 比POT省内存;OpenGL ES 2.0开始支持了NPOT,这样比较省内存,只有要使用mipmaps时才要求是POT。

另外 IOS在使用POT的时候opengl会自动生成mipmap导致会增加33%的内存占用,据说是ios Bug...

关于纹理格式:

openGl ES 2.0 不支持ETC1 带alpha 通道,unity 在将.png转化为JPG  时需要分离alpha 通道;然而JPG 暂用内存会更小。

这里我们不妨把JPG和PNG的一些特性进行一个简单对比:


JPG的特性
1、支持摄影图像或写实图像的高级压缩,并且可利用压缩比例控制图像文件大小。
2、有损压缩会使图像数据质量下降,并且在编辑和重新保存JPG格式图像时,这种下降损失会累积。
3、JPG不适用于所含颜色很少、具有大块颜色相近的区域或亮度差异十分明显的较简单的图片。
PNG的特性
1、能在保证最不失真的情况下尽可能压缩图像文件的大小。
2、PNG用来存储灰度图像时,灰度图像的深度可多到16位,存储彩色图像时,彩色图像的深度可多到48位,并且还可存储多到16位的α通道数据。
3、对于需要高保真的较复杂的图像,PNG虽然能无损压缩,但图片文件较大,不适合应用在Web页面上。

综述,项目中使用哪种格式,需要根据实际情况来决定。

尽管 jgp 和png 压缩率很高 但是不支持 随机访问像素,另外还需要解码。

简单的纹理格式:

  • RGBA8888 每个像素4字节,RGBA 4通道各占用8位
  • RGBA4444 每个像素2字节,RGBA 4通道各占用4位
  • RGB888 每个像素3字节,RGB 3通道各占用8位,无透明通道
  • RGB565 每个像素2字节,RGB 3通道各占用5/6/5位,无透明通道
  • RGBA5551 每个像素2字节,RGB3通道各占用5位,透明通道1位,所以要么完全透明要么不透明

ETC 纹理格式压缩:

ETC1

ETC1把一个4x4的像素单元组压成一个64位的数据块。4x4的像素组先被水平或垂直分割成2个4x2的组,每一半组有1个基础颜色(分别是RGB444/RGB444或RGB555/RGB333格式)、1个4位的亮度索引、8个2位像素索引。每个像素的颜色等于基础颜色加上索引指向的亮度范围。

比如对于某一个半组: 
1. 12位的基础颜色是RGB(0, 34, 255); 
2. 4位的亮度索引从亮度表中选择亮度补充,亮度表有16个,下表是0-7,8-15是0-7的2倍。亮度索引1对应(-12, -4, 4, 12); 
3. 2位的像素索引是0,所以亮度补充是-12。由此可以得到此像素的颜色值是(0-12, 34-12, 255-12),也即(0, 22, 243)。

四大移动设备GPU都支持ETC1,所以在各种Android设备上非透明纹理都可以采用ETC1格式,遗憾的是ETC1不支持透明。对于透明纹理,在Android设备上,可以把RGB和Alpha拆到2张ETC1纹理上,游戏中再合成使用。

 Khronos 支持的开放标准,在移动平台中广泛采用。它是一种为感知质量设计的有损算法,其依据是人眼对亮度改变的反应要高于色度改变。类似于DXT,ETC也是把4x4的像素块压缩成一个64或128位的数据块,也是有损压缩

ETC2

ETC2是ETC1的扩张,向后兼容ETC1,对RGB的压缩质量更好,并且支持透明通道。目前下列ETC2压缩格式在OpenGL ES 3.0和OpenGL 4.3上被要求支持: 
- GL_COMPRESSED_RGB8_ETC2 压缩的RGB888格式,类似于ETC1 
- GL_COMPRESSED_RGBA8_ETC2_EAC 压缩的RGBA8888格式,支持完全的透明通道 
- GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 压缩的RGBA数据,只有一位Alpha

ETC2比ETC1压缩质量更高,而且支持透明,在Android设备上再也不需要打不同纹理格式的包了。不过需要OpenGL ES 3.0以上才可以,目前很多设备只支持OpenGL ES 2.0。

PVRTC

PowerVR Texture Compression,PVRTC格式与基于块的压缩格式,比如S3TC、ETC的不同之处是,它使用2张双线性放大的低分辨率图,根据精度和每个像素的权重,融合到一起来呈现纹理,并且2-bpp和4-bpp都支持ARGB数据。PVRTC格式压缩比高,也是有损压缩。

PVRTC 2-bpp

2 bits per pixel,每个像素2位,质量较差,把一个8×4的像素单元组压成一个64位的数据块。每个数据块中存储了6个变量:调制数据(32位),punch-through Alpha标志(1位),颜色A(15位),颜色A不透明标志(1位),颜色B(14位)和颜色B的不透明标志(1位)。

PVRTC 4-bpp

4 bits per pixel,每个像素4位,把一个4×4的像素单元组压成一个64位的数据块。每个数据块中存储了6个变量:调制数据(32位),调制标志(1位),颜色B(14位),硬转换标志(1位),颜色A(15位)和不透明标志(1位)。

注意:颜色A和B必须格式相同(都为RGB或RGBA),并且整个纹理都是这个RGB或RGBA格式。关于PVRTC的详细细节请参考[7],下面给出一张PVRTC2的格式图: 

PVRTC格式可以用在所有的iOS设备和使用PowerVR GPU的Android设备上,它要求纹理的高、宽必须都是2的整数次幂,最小为8,并且必须是正方形。

 

 

 

 

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------PVR---------------------------------------------------------------------------------------------------------------------------------

通常情况下用PVR格式的文件来进行图片显示的时候,在运行速度和内存消耗方面都要比PNG格式要快和小。一般情况下PVR消耗的内存比PNG消耗的内存小25%左右。PVR格式可以用ZWoptex导出。PVR是apple芯片能直接读取和显示的文件;

PVR是最灵活的纹理文件格式。除了支持标准的未压缩的RGB图片格式。另外,未压缩的pvr格式的纹理的内存消耗非常地低。不像png图片那样要消耗2倍于本身内存占用大小的内存,pvr格式只需要消耗纹理本身内存大小再加上一点点处理该图片格式的内存大小

PVR纹理支持PVRTC纹理压缩格式。它主要是采用的有损压缩。如果拿PVRTC图片与JPG图片作对比的话,它只有JPG图片中等质量,但是,最大的好处是可以不用在内存里面解压缩纹理

----------------------------------图片抗锯齿----------------------------------

图片在放大的时候会出现锯齿。纹理类提供了setAntiAliasTexParameters()函数来处理抗锯齿。当图片放大的时候会使用相邻的四个像素进行混合运算。从而消除锯齿。但是会让图片产生模糊的感觉;

图片缩小时的抗锯齿处理:

使用minmap,缩小时效果会更好;

--------------------------------按照纹理Size从大到小顺序加载纹理-------------------------------

由于加载纹理时额外的内存消耗问题,所以,采用按纹理size从大到小的方式来加载纹理是一个最佳实践。

假设,你有一个占内存16MB的纹理和四个占用内存4MB的纹理。如果你首先加载4MB的纹理,这个程序将会使用16MB的内存,而当它加载第四张纹理的时候,短时间内会飙到20MB。这时,你要加载16MB的那个纹理了,内存会马上飙到48MB(4*4 + 16*2),然后再降到32MB(4*4 + 16)。

但是,反过来,你先加载16MB的纹理,然后短时候内飙到32MB。然后又降到16MB。这时候,你再依次加载剩下的4个4MB的,这时,最多会彪到(4*3 + 4*2 + 16=36)MB。

在这两种情况下,内存的峰值使用相差12MB

PS:如有错误,欢迎指正,共同学习 一起进步 😊

posted @ 2018-05-06 12:28  GamesClient  阅读(757)  评论(0编辑  收藏  举报