Cocos2d-x3.0 Auto-batching 三个小实验

3.0版本开始就有了Auto-batching的功能,这个功能比起以前的SpriteBatchNode方便很多。

但是今天偶然发现一个问题:即使是使用同一个纹理创建的精灵,如果不是连续创建的,就会被划分成多个批次,无法在同一个批次里进行渲染。
我进行了三个实验,分别如下。

1.测试代码如下:

/* 创建很多很多个精灵 */
    for (int i = 0; i < 14100; i++)
    {
        Sprite* xiaoruo = Sprite::create("sprite0.png");
        xiaoruo->setPosition(Point(CCRANDOM_0_1() * 480, 120 + CCRANDOM_0_1() * 300));
        this->addChild(xiaoruo);

        xiaoruo = Sprite::create("sprite1.png");
        xiaoruo->setPosition(Point(CCRANDOM_0_1() * 480, 120 + CCRANDOM_0_1() * 300));
        this->addChild(xiaoruo);
    }


```


运行后调试数据如下:
  


我在每一次的循环里都创建了两个不同纹理的精灵,这样,同一个纹理的精灵就不是连续创建 。
结果渲染批次并不是预想中的个位次数,而是达到了16425次。



2.然后,再做一个小改动,渲染批次就会达到预想的效果,代码如下:
/* 创建很多很多个精灵 */
    for (int i = 0; i < 14100; i++)
    {
        Sprite* xiaoruo = Sprite::create("sprite0.png");
        xiaoruo->setPosition(Point(CCRANDOM_0_1() * 480, 120 + CCRANDOM_0_1() * 300));
        this->addChild(xiaoruo);
    }
    for (int i = 0; i < 14100; i++)
    {
        Sprite* xiaoruo = Sprite::create("sprite1.png");
        xiaoruo->setPosition(Point(CCRANDOM_0_1() * 480, 120 + CCRANDOM_0_1() * 300));
        this->addChild(xiaoruo);
    }


```

结果如下:
  

使用不同纹理的精灵我分别用两个循环来创建,这样在单个循环里,同一个纹理的精灵就是连续创建的。
这次的渲染批次倒是正常多了,但是帧率并没有明显的提升。




3.于是,我试试用回SpriteBatchNode的形式,代码如下:
auto batchNode1 = SpriteBatchNode::create("sprite0.png");
    this->addChild(batchNode1);

    auto batchNode2 = SpriteBatchNode::create("sprite1.png");
    this->addChild(batchNode2);


    /* 创建很多很多个精灵 */
    for (int i = 0; i < 14100; i++)
    {
        Sprite* xiaoruo = Sprite::create("sprite0.png");
        xiaoruo->setPosition(Point(CCRANDOM_0_1() * 480, 120 + CCRANDOM_0_1() * 300));
        batchNode1->addChild(xiaoruo);
    }
    for (int i = 0; i < 14100; i++)
    {
        Sprite* xiaoruo = Sprite::create("sprite1.png");
        xiaoruo->setPosition(Point(CCRANDOM_0_1() * 480, 120 + CCRANDOM_0_1() * 300));
        batchNode2->addChild(xiaoruo);
    }


```

运行结果如下:
  

这次不管是渲染批次还是帧率都达到了预想的效果。



于是,我的疑问来了,是我对Auto-batching的理解有误,还是Auto-batching存在Bug?
经过上面3个不怎么严谨的实验,我看到的结果是:
1. 对于使用同一个纹理创建的精灵,只有连续创建的,才能使用同一批次进行渲染,如果不连续,则,会放到下一个新的批次里渲染
2.在这实验中,Auto-batching似乎对帧率的提升失效了?是因为这是特殊情况,还是说,Auto-batching本身对效率的提升并不能达到SpriteBatchNode的效果?

期待大家的讨论:10:




================================== 以下是来自2014.05.29添加的内容 ======================================
由于我的疏忽,没仔细看文档,导致浪费大家的时间来讨论这个问题,十分抱歉。
不过,似乎Auto-batching和SpriteBatchNode这个话题还是值得探讨了,因为之前的测试主要是为了弄清楚为什么渲染批次和预想的不一样,所以用Windows平台直接就开测了。
导致帧率的数据十分不可靠,为了不误导后来者,我又特意花了点时间(开始邀功了~)在我的Android测试机上测了几组数据,我的手机比较牛(跑分8000多的“神机”),大家看着办~


1.第一组数据,创建了两组不同纹理的精灵,各1100个,三种实验(实验顺序和帖子之前的那三个实验一致)的数据分别如下:
 
由于截图时机的影响,看起来Auto-batching要好一点,帧率其实是不断的跳动的,Auto-batching和SpriteBatchNode帧率差不多。


2.第二组数据,创建了两组不同纹理的精灵,各500个,三种实验的数据分别如下:
 
估计还是我测试机性能问题,帧率 不稳定,数据都差不多。


3.第三组数据,创建了两组不同纹理的精灵,各200个,三种实验的数据分别如下:
 

好了,我不想拿这仅有的三种数据来得出什么结论,比较数据太少了,没有什么好参考的~
做这几组实验是为了帮Auto-batching澄清一下,它和SpriteBatchNode并没有像之前在Windows平台上所测试的那样相差太多。

不过这里想吐槽一下,官方的中文文档 对Auto-batching的介绍似乎有点误导我们,让我们误以为可以舍弃SpriteBatchNode。
关于连续才能批次渲染的这个问题,还是挺麻烦的。

反正让我去改引擎的这部分我是没能力的,于是我很邪恶地期待官方能慢慢完善Auto-batching

这个问题值得关注啊!!!

fps要看真机,模拟器不能说明问题。
另外,这是auto bathcing的缺陷。所以,batchNode还是有用的。另外,即使是同一张纹理 创建出来的精灵,如果其blendfunc和shader状态不同的话,也是不能auto batching的。

这个问题值得研究

原来如此,我还以为我的打开方式不对 :7:

虽说模拟器不太能说明,不过,这帧率差别还是蛮大的,估计Auto-batching和SpriteBatchNode在真机上也有不小的差距,我还是真机试试吧,不能瞎猜,哈哈:868:

PS:很期待Auto-batching的完善,毕竟SpriteBatchNode用起来有些局限~

Auto-batching
Auto-batching means that the Renderer will package “multiple draw calls” in just one “big draw call” (AKA batch). In order to group “draw calls” certain conditions are needed:
It only works with QuadCommand commands (used by Sprite and ParticleSystem objects)
The QuadCommands must share the same Material ID: same Texture ID, same GLProgram and same blending function
The QuadCommands must consecutive

笨木头仔细看看官方的文档,里面有说明的

原来文档都说明白了,我劳师动众了…

不过,你这段文字是在哪个文档看到的?~
我找了几个地方,找到了这个文档:https://docs.google.com/document/d/17zjC55vbP_PYTftTZEuvqXuMb9PbYNxRFu0EGTULPK8/edit#heading=h.dii2kgdfqgcp (是这个页面的其中一个链接:http://www.cocos2d-x.org/wiki/Renderer?project_id=cocos2d-x)
它也有提到了连续和不连续的那个问题…但是没看到你那段文字:5:

我错了。。。你看的文档是哪个地方…难道我一直看的文档和大家的不一样:8:

山人,如果autobatch 如此之说,只能按照这个规则,才能解决2.X两个batchnode里面不同子个体的zorder问题和性能提升吗?但是这个框框,使用起来太不方便啊,距离
版本描述里说的更新内容,差的很远啊,我要做到类似皇城守卫军里的,那么多数量的小兵和怪的批次庞大问题,而且zorder实时变化的问题,如何解决,能给些建议不,3.0版本,也许也只能委婉解决这个问题(正准备尝试),刚看了楼主说的,貌似很吃力。

用batchNode,用小图。100-200个应该没问题。