一次操作将游戏内存减少50+%-压缩纹理,优化Cocos Creator的性能
为了避免这些问题,纹理压缩是指一种针对GPU的纹理压缩方案,使纹理能够被GPU直接识别并渲染。它有以下优点。
传统图像压缩的主要目的是存储和传输。为了尽可能高效地压缩,使用了可变压缩比。所以解压缩时需要解压缩更多的像素位来读取一个像素的位置,不适合随机快速读取,也无法发挥GPU的并行处理优势。
压缩后的纹理使用固定的压缩比将纹理划分为多个像素块,每个像素块包含2*2或4*4个像素,然后对每个像素块进行压缩,压缩后的像素信息存储在像素集中,每个像素块的索引位置存储在块索引图中。读取时先将纹理坐标转换成块索引值,然后在像素集中找到对应的像素块,最后在这个像素块中找到纹理颜色值。
因为压缩比固定,GPU可以并行处理,所以解压很快。相比之下,纹理压缩的过程发生在程序运行之前,与编码速度无关,因此在压缩过程中会遍历所有可能性,以找到与原始像素差异最小的代码,这也是纹理压缩需要较长时间的原因。
对了,正常的图片格式,PNG是无损压缩,JPEG是有损压缩。压缩后的纹理是有损压缩,但大多数情况下,在手机上是看不到的。
压缩纹理在手机上的使用依赖于OpenGL ES的支持。OpenGL ES 2.0本身并没有定义任何纹理压缩格式,只是提供了glCompressTexImage2D()方法供应用上传压缩纹理。压缩纹理的格式由各种GPU制造商定义和实现。
OpenGL ES 3.0提供了一个压缩纹理标准,使得所有平台都可以使用相同的压缩纹理,但是市场上所有设备过渡到OpenGL ES 3.0还需要很长时间。因此,对于不同的平台和设备,仍然需要使用不同的压缩纹理格式。
以下是手机游戏中常用的格式。
ETC1将4*4像素块压缩成固定的64位代码(8字节)。一个4*4的像素块是16个像素,每个像素有4个字节,一个* * *占64个字节,所以压缩比是64/8=8。但是ETC1只能存储RGB信息,不适合透明纹理。为了解决这个问题,Creator编写了ETC1+A格式的额外透明信息,其压缩比为64/16=4。
ETC1/ETC1+A需要OpenGL ES 2.0(对应WebGL 1.0)环境。目前几乎所有安卓手机都支持ETC1,iOS不支持。
ETC1/ETC1+A纹理的长和宽可以不相等,但要求是2的幂。
ETC2是ETC1的扩展,压缩比相同但压缩质量更高,支持透明通道,可以完整存储RGBA信息。
ETC2需要OpenGL ES 3.0(对应WebGL 2.0)环境。目前很多低端安卓手机都不兼容,iOS从iPhone5S开始支持OpenGL ES 3.0。
ETC2和ETC1一样,可以长宽不等,但要求是2的幂。
在Creator中,常用PVRTC4+A,压缩比和ETC一样,iOS完全支持,Android不支持。另外,PVR要求纹理长宽(平方)相等,2的幂,比如一张1280*720的PNG图片转换后会变成2048*2048,这样会大大增加内存消耗。在实测中也发现转换后的画面质量不如ETC1,有模糊和毛刺,不适合对画面要求高的游戏。
压缩纹理的使用非常简单,根据构建平台添加需要的格式即可。详情请参考官方Creator文档,本文不再赘述。
Creator编辑器还提供了转换压缩纹理的选项,可以根据转换速度分为快、慢等几个文件。速度越慢,画质越好。但无论选择哪个,都只是影响显示效果和转换时间,内存占用是一样的。一般来说,内存占用是压缩纹理的文件大小。例如,如果文件大小为1.5m,内存占用也是1.5M..
在设置压缩纹理格式时,目前的Creator 2.x版本仍然需要逐个手动设置。如果要一次性设置全部或部分资源,也可以方便地编写脚本来遍历和修改相应的。元文件。下面是我写的一个脚本,可以一键自动设置压缩纹理格式。
实际项目中的测试结果显示,单张地图、自动图集、TexturePack组合的2000多张图片的Creator项目,使用PNG时apk包大小接近500M,内存占用为1.3G,使用压缩纹理后,包含大小减少到150M,内存占用减少到600M m。