我们在使用cocos在windows平台下,运行速度很快很流畅,很强大,可是当我们打包成apk文件,在手机上运行的时候,流畅度很可能降低,甚至还有间歇性内存彪高。
游戏内存优化我们一般可以从这么3个方面入手:引擎自身提供的优化选项,引擎底层框架,语言上层(内存泄漏)。事实上,代码运行占用的内存是很低的,图片等资源的加载和使用占80%你所使用的的内存资源。在这里我们着重分析一下如何由图片减少内存的使用。
- 首先,图片的格式!各个类型(png8,png32,jpg......)我们区分一下。jpg最大的缺点是不透明,所以只能作为一些不动的背景,在最底层使用。与jpg很像的png8格式都是减少包体的好选择,因为他们的压缩比都是最好的,当然要适用,否则适得其反。
- 其次,图片是有颜色深度RGBA4444和RGBA8888,即使是采用同样的色深(24bit or 32bit)保存,RGBA4444比RGBA8888的图像质量会差一些,而且在cocos中,最终都会使用RGBA8888,RGBA4444尽量使用颜色深度为16bit的图片,在TexturePacker中开启抖动算法,cc.Texture2D.setDefaultAlphaPixelFormat(cc.Texture2D.PIXEL_FORMAT_RGBA4444)改变默认像素格式,如何单个加载可以在加载需要将颜色深度设为RGBA4444的文件的前后,分别设置PixelFormat;图片保存格式: 8bit 、 24bit 和 24bit(with alpha channel)=32bit 三种格式;
setFormat(RGBA4444); loadTexture("SpriteSheet.png"); setFormat(RGBA8888);
- 接下来,看一下纹理加载过程中的内存变化, 先以一张1024*1024 本身大小500k的jpg/png图片为例:
1. 读取图片文件(500k)
2. 把jpg/png数据最终都是按RGBA8888(默认)格式解析(4mb)
3. 释放500k的图片内存
4. 上传给OpenGL纹理数据(4mb)
5. 释放4mb内存
计算图片纹理大小:
1. 图片的像素点个数(分辨率)
2. 单位像素占用的字节数(像素格式)。
即纹理内存大小 = 纹理长度 * 纹理宽度 * 单位像素占用的字节数,如:一张1136x640的RGBA8888的png图片占用的内存为 1136x640x4 = 2.8M左右
- 知道了以上信息,我们可以选择对不同的设备优化:
iOS用什么?当然是用PVR格式。
pvr是iOS设备的图形芯片 PowerVR 图形 支持的专用压缩纹理格式。它在PowerVR图形芯片中效率极高,占用显存也小。
Android设备上,因为硬件不统一,每个厂商GPU使用的不同的纹理压缩,目前可以采用ETC1或者PNG/JPEG格式。
- 如何使用将图片打包压缩,较少包体,较少内存花销呢?
1.首先使用TexturePacker打包,如果颜色深度不是很高,可以选择抖动算法,打包成大图
2.将压缩后的图片使用https://tinypng.com/这个网站再压缩一次,显著减少包体
此外,在浏览各个大佬博客的时候,看到以下的cocos图片的技巧,(转博客地址http://imgtec.eetrend.com/d6-imgtec/blog/2018-07/16921.html):
1、一帧一帧载入游戏资源
2、减少绘制调用,打包大图
3、载入纹理时按照从大到小的顺序
4、避免高峰内存使用
5、使用载入屏幕预载入游戏资源
6、需要时释放空闲资源
7、收到内存警告后释放缓存资源
8、使用纹理打包器优化纹理大小、格式、颜色深度等
9、使用JPG格式要谨慎!
10、请使用RGB4444颜色深度16位纹理
11、请使用NPOT纹理,不要使用POT纹理
12、避免载入超大纹理
13、推荐1024*1024 NPOT pvr.ccz纹理集,而不要采用RAW PNG纹理
1. 场景、背景、全屏图片
2D手机游戏中,多半都有这样的图片,以作为背景,特别在一些SLG,横版过关游戏中。这种图片对ALPHA没有要求,并且,在同一时间,只会出现一张(如果是多张拼接,也不会超过屏幕尺寸太多),内存不会成为关键点。所以,在这种情况下,我们大胆选择JPG就可以了。
2. 场景的前景,装饰物,可移动对象(npc,moster,…)
这种要看规模,如果规模较小,类型不多。 或者类型虽然多,但同一时间出现在场景中的类型不多,那我们可以选择压缩PNG8的方式,它支持ALPHA通道,文件又小。如果同屏可能出现多种这种,则需要考虑在IOS上使用PVRTC,在ANDROID上使用ETC1+ALPHA_MASK。实际上,为了好维护,一般都是统一用pvr.ccz打包。
3. UI
UI的背景图,可以优先考虑使用压缩PNG8,如果达不到精度要求,则使用PNG32。而对于UI的小元素,可以考虑使用压缩PNG8.
对于UI的图标,一般是不带ALPHA的PVRTC/ETC + 一张公共的ALPHA掩码图,通过双层混合来实现圆边效果。 因为图标同屏出现可能较大。 如果图标能够控制在一定范围内,由于图标是48X48等大小,一张1024x1024的大图,可以放400个图标。 换用JPG,也有4MB的开销,如果这个是可以接受的,也可以使用JPG+ALPHA_MASK的方式。
写到这里才发现,其实只需要下面一句话就可以搞定。
这类图片会不会同时出现多个,同时出现时,内存开销是否无法接受, 如果确实无法接受,则使用GPU纹理,否则,优先考虑JPG,JPG+ALPHA,或者PNG8。就是说,首先要减小安装包大小,如果内存有无法接受的情况,才需要用GPU纹理进行优化。
原文地址:https://www.cnblogs.com/zhangthree/p/10575689.html