最全的Creator游戏优化方案(一)

今天下午闲下来也来写写creator中的优化方案。欢迎各位拍砖,过程中会使用到一些别人的图片还请见谅!


1.加载速度优化

1.避免使用单像素的大图,尽量使用9宫方式进行拉升。

在我们加载的时候降低游戏资源,加载小资源纹理自然就会加快了速度。而却也减小了包体。


2.对于一些想降低drawcall数使用很多相同图片,但是只是颜色不同的图片来说,这点需要大家自行取舍。

3.将图片进行模块合批处理


这样做有以下好处:

 

1. 提高了加载的速度(避免了来回打开/关闭不同图集所消耗的时间)
2. 降低了drawcall(所有的图都在一张图中,gl接口只会绘制被调用一次,这样一来就大大降低了drawcall,比如需要10drawcall的资源现在只用1次就可以了)
3. 降低包文件的体积(将多张图片放在一起,一般会有一定程度上的缩减)

同样这样做可以将一些通用资源统一加载到内存中常驻,这样就会避免了频繁的加载与释放所带来的不必要的开销。
4.图片资源压缩


对于图片上的压缩想必大家会有很多的方法,这一块呢其实对其加载速度上的影响不是很大,毕竟人家cpu的速度还是很快的,但是压缩还是很有必要的同样的图片大小不一样,证明包含的数据信息量不同,那么你想一下是大点好还是小点好呢。
先来看一张图:

比如RGBA8888这种pixelformat,它意味着rgba每一位占用8个bit,这样每个像素占用4个字节,因此这个压缩模式对于图片可以最大限度的保真,但压缩比方面没有其他的大。

在和大家提一下,图片的体积并不是意味着就是内存中的体积,换算方式是这样的

长*宽*4 = 内存体积
比如一张600k大小的1024*1024的图片,在内存中的占用大小为1024*1024*4 = 4M。

这里推荐两款压缩的工具:


1.TinyPNG,https://tinypng.com/一个在线压缩图片的网站,我称他为‘熊猫压缩’
2.另一个是[pngquant](https://pngquant.org/)的命令行压缩图片,你可以很好的集成到打包工具中使用。

对于不同格式的图片资源不同平台的机器支持的也不近相同


1.ios中支持比较好的就是使用PVR格式的资源,因为他可以直接被PowerVR显卡使用,这样就省下了不少cpu上传gpu的时间
2.android中支持ETC格式的资源比较好,而ETC的话,ETC1只能在android上使用。ETC2可以在目前的iOS上和android上同时使用,不过太低端的机子就不行了。

5.预制体的优化

预制体的耗时一般会出现在两个地点,1.在load加载时候,2.在实例化的时候

我们先来看一张creator预制体的加载图:
1.合理拆分预制体

将众多的组件拆分为多个预制体,这样可以有效的降低节点的复杂度,加快还原节点的速度。(那么有的人会说了,那打开的文件次数不就多了加大了io的消耗,哎,你要是能跟得上io的速度,全当我没说, 对于这点我们总是要舍弃一方面的,二者不可兼得)


2.延迟加载资源
creator中也为我们提供了加载方式的选择:延时加载资源

勾选这个选项可以减少prefab的加载耗时,但首次显示的耗时会增加。

这是由于勾选后,prefab所引用的资源,像图片、音效这些,不会在load时加载,而是会在prefab第一次显示的时候再进行资源的加载,根据具体情况选择使用。

3.勾选优化策略
对于优化策略,creator也给出了方案,1.优化单次渲染2.优化多次渲染
单次渲染优化:
这个选项是,prefab加载后会跳过预处理的步骤,这样在加载时的耗时会减少很多,但实例化时的耗时会增加。例如一些固定UI界面,由于方便加载场景或者时进行功能划分,通常会做成prefab,这种prefab只会加载一次的,就可以选择这个选项,提升加载的性能。
多次渲染优化:
这个选项是,Prefab加载后会进行一个预处理的操作,这个预处理其实就是动态生成一些prefab的实例化代码,并把这些代码交给jit去进行优化。这样在实例化时的耗时将会大大减少,相应的,在load时的耗时会有所增加。这是必然的。

6.场景优化


1.合理使用预制体布置界面,分批异步加载,对于界面首次显示不需要的界面可以通过动态添加的方式加入界面。
2.尽量少使用spine动画区布置主界面,有可能会导致内存大幅度上升,出现卡顿。
3.选用场景的延时加载资源的方式,避免同一时间加载大量的预制体。
4.避免同一时间实例化大量对象,避免内存的突然飙升。推荐使用async异步初始化方式,借用第三方库async

     async.eachLimit(array,  100,  (index,cb)  =>  {
            var node = new cc.instantiate(‘自己的预制体’);
           //其他操作
        });

 

2.渲染优化


对于渲染的优化主要目的就是降低Drawcall
draw call是openGL的描绘次数
一个简单的openGL的绘图次序是:设置颜色→绘图方式→顶点座标→绘制→结束。
一般情况下一张图片都是绘制一次,也就是drawcall+1。

1.通常我们选择自动图集批处理。

那在实际的项目过程中,既然已经有了自动图集批处理的机制,为何我们的draw call还居高不下?
这是因为并不是所有的纹理都可以放到自动图集批处理中。
使用自动图集批处理有几个限制:
1、单图尺寸小于512*512并且大于88*88
2、渲染buffer必须为MeshBuffer类型的资源才能批处理(引擎中renderComponent源码,像bmfont label和sprite都是MeshBuffer,所以它们可以进入到批处理中。而像9ScaleSprite,Spine这些所使用的为QuadBuffer,因此没办法进行批处理)
3、对节点部分特殊的操作不能进入批处理(比如Mask,Color)

给大家一个表仅供参考



       creator 2.x(2.0~2.0.6)的版本中,支持Bmfont Label和Sprite进入批处理,其他的节点或者操作会打断批处理。这里所说的Color和Opacity是指node节点上的color属性或者是opacity属性不相同的话,就算使用同一张图片资源,也会打断批处理。
       creator 2.1版本和2.0.7(公测版)中,Bmfont,Sprite,9ScaleSprite,Color,Opacity都会进行自动批处理。


2.使用Camera和RenderTexture降低drawcall
对于这样的预制体我们会如何处理呢?

代码:

 

cc.Class({
    extends: cc.Component,

    properties: {
        camera : cc.Camera,
        layout : cc.Node
    },


    start () {
        let renderTexture = new cc.RenderTexture();
        let gl = cc.game._renderContext;
        let width = 100;
        let height = 100;
        renderTexture.initWithSize(width, height, gl.STENCIL_INDEX8);
        this.camera.targetTexture = renderTexture;
        this.camera.render();
        for (let i = 0; i < 100; i++) {
            var node = new cc.Node();
            node.addComponent(cc.Sprite);
            node.getComponent(cc.Sprite).spriteFrame = new cc.SpriteFrame(renderTexture);
            node.parent = this.layout;
        }
    },
});


通过上述方法可以将所有节点显示都绘制在同一renderTexture中,将drawcall大幅度降下来。不过此方法限制也很大。适用于刷新率不高,或者刷新情况比较固定的显示。
(未完待续)
留下个人博客以供学习:taoqy666.com

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值