COCOS2DX 3.0 优化提升渲染速度 Auto-batching

COCOS2DX 3.0 优化提升渲染速度 Auto-batching
近期在看COCOS2DX 3.0的Auto-batching合批与Auto Culling动态缩减功能以下就来细致看看吧:整合好的渲染提速干货:

简单介绍

在游戏的绘制渲染中。往往消耗非常多资源和内存,当绘制精灵数量越多,游戏的卡顿会非常明显,为了优化和提升渲染效率。

Cocos2d-x为我们提供了Auto-batching和SpriteBatchNode。

Auto-batching 意思是Renderer将多次draw的调用打包成一次big Draw 调用。

(又名批处理)。

SpriteBatchNode 主要用于批量绘制精灵提高精灵的绘制效率的,须要绘制的精灵数量越多,效果越明显。

Auto-batching

在3.0版本号实现了引擎的逻辑代码与渲染代码的分离。实现了Auto Batch与Auto Culling功能。不再推荐使用SpriteBatchNode提高精灵的绘制效率。

Auto-culling的支持,Sprite在绘制时会进行检查。超出屏幕的不会发给渲染。

Auto-batching的渲染流程

如今。一个渲染流程是这种:

(1)drawScene開始绘制场景

(2)遍历场景的子节点。调用visit函数,递归遍历子节点的子节点,以及子节点的子节点的子节点,以及…

(3)对每个子节点调用draw函数

(4)初始化QuadCommand对象。这就是渲染命令。会丢到渲染队列里

(5)丢完QuadCommand就完事了,接着就交给渲染逻辑处理了。

(6)是时候轮到渲染逻辑干活干活,遍历渲染命令队列。这时候会有一个变量,用来保存渲染命令里的材质ID。遍历过程中就拿当前渲染命令的材质ID和上一个的材质ID对照。假设发现是一样的。那就不进行渲染。保存一下所需的信息,继续下一个遍历。好,假设这时候发现当前材质ID和上一个材质ID不一样,那就開始渲染,这就算是一个渲染批次了。


(7) 因此,假设我们创建了10个材质同样的对象,可是中间夹杂了一个不同材质的对象。假设它们的渲染命令在队列里的顺序是这种:2个A,3个A,1个B,1个A。2个A。2个A。那么前面5个同样材质的对象A会进行一次渲染,中间的一个不同材质对象B进行一次渲染。后面的5个同样材质的对象A又进行一次渲染。

一共会进行三次批渲染。

SpriteBatchNode

它是批处理绘制精灵,主要是用来提高精灵的绘制效率的,须要绘制的精灵数量越多,效果越明显。

由于cocos2d-x採用opengl es绘制图片的,opengl es绘制每个精灵都会运行:open-draw-close流程。

而SpriteBatchNode是把多个精灵放到一个纹理上。绘制的时候直接统一绘制该texture。不须要单独绘制子节点,这样opengl es绘制的时候变成了:open-draw()-draw()…-draw()-close(),节省了多次open-close的时间。SpriteBatchNode内部封装了一个TextureAtlas(纹理图集,它内部封装了一个Texture2D)和一个Array(用来存储SpriteBatchNode的子节点:单个精灵)。注意:由于绘制的时候仅仅open-close一次,所以SpriteBatchNode对象的全部子节点都必须和它是用同一个texture(同一张图片)。

在addChild的时候会检查子节点纹理的名称跟SpriteBatchNode的是不是一样,假设不一样就会出错。

// check Sprite is using the same texture id

CCASSERT(sprite->getTexture()->getName() == _textureAtlas->getTexture()->getName(), "CCSprite is not using the same texture id");


SpriteBatchNode和SpriteFrameCache结合使用代码演示样例

必须保证SpriteFrameCache和SpriteBatchNode载入的是同一纹理贴图。


SpriteBatchNode vs. Auto-batching

在3.0版本号中提供了新的渲染机制,实现引擎逻辑代码和渲染的分离。该版本号依旧支持SpriteBatchNode,和曾经的版本号保持一致。可是不再推荐使用SpriteBatchNode。

Auto-culling的支持,Sprite在绘制时会进行检查。超出屏幕的不会发给渲染。

使用Auto-batching

·需确保精灵对象拥有同样的TextureId(精灵表单spritesheet);

·确保他们都使用同样的材质和混合功能

·不再把精灵加入SpriteBatchNode上

·避免打乱QuadCommand队列

Auto-batching拥有更好的性能提升。

以下通过代码来分析几种符合Auto-batching使用的情况

1、使用同一图片生成精灵,加到场景中。

此种情况最简单。就是反复加入同一个精灵。

由于满足Auto-batching的条件。此时的渲染批次为2.(首先,即使我一个精灵也不创建,渲染批次也至少是1,加上刚刚这反复加入的精灵的渲染)



2、使用精灵帧表单,载入生成加入不同的精灵。

可是各个精灵的材质都是一样的,满足Auto-batching的条件。

此时的渲染批次为2.(首先。即使我一个精灵也不创建,渲染批次也至少是1,加上刚刚这反复加入的精灵的渲染)


在实际使用中推荐使用这种方式。


3、此种情况假设在不同的zOrder下加入不同的精灵。在遍历子节点之前,事实上还偷偷做了一件事情,那就是,调用sortAllChildren();函数对子节点进行排序。尽管反复加入不同材质生成的精灵。可是它们的zOrder不一样,依据zOrder,Auto-batching渲染命令被又一次排序。依据材质同样加入渲染队列从而减少了渲染次数。


假设凝视掉sprite2->setZOrder(1);你会发现渲染批次会升高。

posted @ 2017-06-27 16:31  yfceshi  阅读(1397)  评论(0编辑  收藏  举报