首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

一个操作让游戏内存立减 50%!

在游戏中,纹理不仅占据大量的包体,也占据了大量的内存。传统的图片压缩格式(如 JPEG、PNG 等)虽能减少资源大小,但是不能被 GPU 直接识别,还是需要先加载到内存通过 CPU 解码,转换成 RGB/RGBA 等能被 GPU 识别的格式,才能传送到 GPU 进行渲染。

为避免这些问题,社区Cocos Star Writer 楚游香带来针对 GPU 的纹理压缩方案,使纹理能够直接被 GPU 识别并进行渲染,它具有以下优点:

无需 CPU 解码,节省了 CPU 运算,减少耗电量;

纹理直接被传送到 GPU,避免了内存占用,提高渲染性能;

高效的压缩算法,减少了包体大小。

以下是具体操作讲解,欢迎阅读。

01

压缩纹理的原理

传统的图片压缩主要目的是存储和传输,为了尽可能的高效压缩,使用了可变的压缩比率,因此在解压时需要解压更多的像素位才能读取某个像素的位置,不适合随机和快速读取,也发挥不了 GPU 的并行处理优势。

而压缩纹理使用一个固定的压缩比率,将纹理划分成多个像素块,每个像素块包含 2*2 或 4*4 个像素,然后对每个像素块进行压缩,被压缩的像素信息存储在一个像素集合中,每个像素块的索引位置存储在一个块索引图中。

读取时,首先将纹理坐标转化为块索引值,然后在像素集合中查找对应的像素块,最后在这个像素块中找到纹理颜色值。

因为采用了固定的压缩比率,GPU 内部可以并行处理,从而快速的解压缩。与之相对的是,纹理的压缩过程发生在程序运行之前,并不在意编码速度,因此在压缩时会遍历所有可能性,找到和原始像素差值最小的编码,这也是纹理压缩耗时较久的原因。

顺便说一下,普通图片格式中,PNG 是无损压缩,JPEG 是有损压缩。而压缩纹理都是有损压缩,只是在绝大部分情况下,手机上看不出来而已。

02

常用的压缩纹理格式

手机上使用压缩纹理依赖于 OpenGL ES 的支持,OpenGL ES 2.0 本身并没有定义任何纹理压缩格式,它仅提供 glCompressTexImage2D()  方法供应用程序上传压缩纹理,压缩纹理的格式由各个 GPU 厂商定义和实现。

OpenGL ES 3.0 提供了压缩纹理标准,使各个平台都可以使用同一种压缩纹理,但市面上的设备还需要很长时间才会全部过渡到 OpenGL ES 3.0。因此,仍然需要对不同的平台和设备使用不同的压缩纹理格式。

手机游戏中常用的有以下格式。

2.1 ETC1

ETC1 把 4*4 的像素块压缩成固定的 64 位编码(8 个字节),4*4 像素块是 16 个像素,每个像素 4 字节,一共占 64 个字节,所以压缩比是 64/8=8。

但是 ETC1 只能存储 RGB 信息,不适用带透明度的纹理,为解决这个问题, Creator 在 ETC1 文件中额外写入了透明度信息,即 ETC1+A 格式,它的压缩比是 64/16=4。ETC1/ETC1+A 需要 OpenGL ES 2.0(对应 WebGL 1.0)环境,目前几乎所有 Android 手机都支持 ETC1,但是 iOS 不支持。ETC1/ETC1+A 纹理的长宽可以不相等,但要求是 2 的幂次方。

2.2 ETC2

ETC2 是 ETC1 的扩展,压缩比率一样,但压缩质量更高,而且支持透明通道,能完整存储 RGBA 信息。

ETC2 需要 OpenGL ES 3.0(对应 WebGL 2.0)环境,目前还有不少低端 Android 手机不兼容,iOS 方面从 iPhone5S 开始都支持 OpenGL ES 3.0。

ETC2 和 ETC1 一样,长宽可以不相等,但要求是 2 的幂次方。

2.3 PVRTC

Creator 中常用的是 PVRTC4+A,压缩比和 ETC 一样,iOS 全系列支持,但是 Android 不支持。另外 PVR 要求纹理长宽相等(正方形)且是 2 的幂次方,例如 1280*720 的 PNG 图片,转换后变成 2048*2048,这一点会大大增加内存消耗。

在实测中还发现转换后的图片质量不如 ETC1,存在模糊、毛边现象,对画面要求高的游戏不适合。

03

压缩纹理的使用

压缩纹理的使用非常简单,根据构建平台添加需要的格式即可,具体参见 Creator 官方文档,本文不再重复。

Creator 编辑器还提供了转换压缩纹理的选项,根据转换速度分为 Fast、Slow 等好几档,速度越慢则画面质量越好。但不管选哪个,只影响显示效果和转换时长,显存占用都是一样的。

一般情况下,显存占用就是压缩纹理的文件大小,例如文件大小是 1.5M,则它占用的显存也是 1.5M。

在设置压缩纹理格式时,目前 Creator 2.x 版本还需手动一个一个设置。如果想一次性设置所有或部分资源,记得有大佬提供过插件,当然自己写个脚本遍历修改对应的 .meta 文件也比较方便。

这里是一个我写好的脚本:

https://www.chuyouxiang.com/archives/760(一键自动化设置压缩纹理格式)

04

总结

在实际项目中的测试结果是,单图、自动图集、TexturePack 合图加起来超过两千张图片的 Creator 工程,使用 PNG 时打出来的 apk 包大小近 500M,内存占用 1.3G。采用压缩纹理后,包体大小降到 150M,内存占用降到 600M。

压缩纹理的初始文件大小比 PNG 大 1-2 倍,但经过 zip 或打包成 apk、ipa 后,大小比 PNG 小了 1/2-1/3,对减小包体有巨大好处。

从 OpenGL ES 2.0 开始,GPU 纹理支持非 2 幂次方(例如,小于 2048 的图片比 2048 图片更节省内存),目前所有手机都已经是 OpenGL ES 2.0 及以上了。

对于 Android 原生平台,要想兼容尽可能多的设备,又想发挥内存和包体优势,目前最佳选择是 ETC1。

对于 iOS 原生平台,PVR 画面质量不佳,如果只考虑 iPhone5S 及以上设备,则使用 ETC2 比 PVR 好。

OpenGL ES 3.0 开始新推出一种 ASTC 格式,Android 和 iOS 都支持,画面质量比 PVR 好,且不要求纹理长宽相等和 2 的幂次方。ASTC 可能会是未来的统一格式,但目前很多 Android 低端设备还不支持。

以上是来自社区Cocos Star Writer 楚游香的个人经验分享,大家可根据个人项目实际情况酌情使用。

至于压缩纹理在 Creator 中的配置方法、使用方法,以及对不同平台的支持情况等,可参考【官方文档】:

https://docs.cocos.com/creator/3.0/manual/zh/asset/compress-texture.html

社区有许多大佬除了技术过硬外,独立做游戏好多年,不仅前端、后端自己搞定,还各种外服一起搞,感谢大佬们一直不吝分享自己的经验,普惠广大开发者,也希望更多的同学可以一起加入到我们的行列中。

05

直播预告

最后,本周五(3 月 19 日)晚 19:30,Cocos 引擎组放空老师将携神秘嘉宾在 B 站开展直播,带来关于《Cocos Creator 3.0 轻松玩转 npm 海量资源》、《FrontJS SDK,你的线上黑猫警长》等内容。

欢迎各位开发者准时围观,也欢迎大家提前准备关于Cocos Creator 2.x 升级 3.0所遇到的问题,引擎组会在直播间里为大家解答噢!期待您的参与!

最后,欢迎大家常在社区交流玩耍!

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20210317A04NLL00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券