微信小游戏DrawCall和模拟器相差巨大

cocos版本:1.9.1-rc最新版

模拟器或者web模拟器:
drawcall:15-25左右,
verts: 1100左右

微信小游戏上:
drawcall: 290左右
vert:6 tri: 430-460

在模拟器上相对流畅,结果到微信上奇卡无比。
ios上运行没看数据,但是和微信小游戏一样卡。

图集全部是合并过的,能解释下上面数据的问题吗?差别很大!

ps: 连续发了好几个问题了,都没有人鸟 - -!
但这些问题的解答真的太重要了,先行谢过

1赞

是因为模拟器渲染可以批量渲染,而微信小游戏不支持批量渲染吗?看这数据猜测的。
还有微信小游戏也是用的webgl,不是canvas渲染哦。

不科学。。。用 webgl 渲染都会做批处理,web 浏览器上执行的代码和微信小游戏上执行的代码没有本质区别,draw call 应该是一样的。
有可能是你以为在微信上用了 webgl 渲染,但是由于某些特殊的原因没有办法开启

好久不见你出来回答问题了

我用了camera组件,在微信小游戏上不用webgl渲染是没法进入场景的。

场景描述:
我的地图是用格子(110*110)绘制的,并没有用tilemap。每个格子的图片虽然有不一样,但图片都是来自同一个图集。以下是我测试了地图上主角移动时的数据(摄像机跟随主角,没有其他操作)。

格子数量:17 * 7

web模拟器:

FPS:59.97 Draw call: 5

微信小游戏:

格子数量: 27 * 28

web模拟器:

FPS:59.96 Draw call 13
微信小游戏:

格子数量: 27 * 28

微信小游戏:

以上数据看,web模拟器在格子数增大的情况下,draw call变化不大,都在15以内,运行流畅。
而微信小游戏draw call一直很高,随格子数增大而变高,帧率低下。

如果在渲染中由于某些特殊原因没法开启webgl渲染,那如何排除这种情况,性能损耗非常严重啊。
另外在主角移动用了粒子效果做拖尾,但是不启用也是一样卡。

@panda

经过自己进一步排除发现了一些新现象:
通过去掉地图绘制,以及摄像头组件,物理系统。最后发现微信小游戏的draw call初始就有60。
原来是我在加载场景的时候预先initial了30个子弹,并放在了场景中(不可见的位置)。目的是为了方便后续使用,因为用对象池也要设置parent,觉得这样还是会有性能损耗,就干脆提前放入了场景。

这排除了地图批量渲染的问题,但新问题来了:
1:为什么提前在同一个位置设置30个相同的精灵(带刚体),初始drawcall就是60?
2:把影响calldraw的代码去除后,calldraw降下来了,但是FPS依然很低?(drawcall降到15,fps也只有15)
3:为什么模拟器上和微信小游戏对于这种渲染会有不同的drawcall?及时恢复但fps依然相差巨大?

下图是去掉加载场景是置入30个子弹后微信小游戏的数据:

影响drawcall的代码:

var initSimpleBulletCount = 30;
for(var i=0; i<initSimpleBulletCount; ++i){
var simpleBullet = this.newSimpleBullet();
this.simpleBullets.push(simpleBullet);
}

newSimpleBullet() {
var simpleBullet = cc.instantiate(this.simpleBullet);
simpleBullet.position = cc.gameData.globalCommon.getBulletBornPos();
simpleBullet.parent = this.bulletNode;
return simpleBullet;
},

不太清楚在微信小游戏如何具体做性能测试,由于ios卡顿和微信小游戏差不多,我就在ios上面开了profile看了下了。下面是截图,显示drawBatchedTriangles相关堆主耗时很多。

是因为渲染的性能问题导致在微信小游戏和ios上帧率严重下降吗?
而同时浏览器和模拟器上渲染性能又很正常,好奇怪,有官方解释吗?

同问!

微信小游戏目前测试来看, 性能瓶颈主要在cpu,所以draw call的数量影响不是很大。但是draw call的数量会导致 opengl api call的数量上升(引擎本身有很多redundant call ), 同时gl.bufferData的调用次数变多,这些都是要消耗性能的。

另外,你可以考虑把sprite culling去掉,用浏览器去profile js的性能消耗,解决性能瓶颈。

如果是tiledMap,可以考虑自己去实现culling,不是针对单个sprite,而是针对整个地图,另外sprite的quad data提交是一个一个copy的,可以考虑事件用typeArray构建好,在rendenring的时候统一去调 typeArray.set 方法一次赋值,这个提升效果也比较大。

2赞

子龙大大又粗现了

你说的这些,我能懂啥意思。不过听起来都是引擎内部的实现吧,但是让我去研究引擎内部实现这很头大啊。

比如如何关闭sprite culling?
去哪改quad data的提交方式?

开放的api都没有你说的这些设置和方法,如果是引擎内部实现,能否在引擎端实现一种渲染策略,我们开发者只需要设置全局参数就可以啊。

这个性能问题真的很折腾,感谢回复让我理解性能瓶颈的出处,但解决方案上去改引擎我是有点懵的。咋办?

其实思路就是叫你去修改下底层地渲染模块。。。

子龙大大的意思是:自己技术过硬的话,就去改改底层啥的,给了你思路。。不过硬呢?。。等着新版本吧。。

自己改底层模块,老实讲我内心是抗拒的,难以表达此刻复杂的心情:joy:

同问此问题,项目做完后,发现微信小游戏奇卡无比,于是从渲染块入手,看到登录界面H5上DC 为2个,一张大图+ 三个图集中按钮(显示)+ 四个隐藏并未展示按钮(同一图集) 然后在微信小游戏上 DC个数 为 8 个,刚刚好是没有合批的DC数量,但是在我进入游戏后,返回登录界面DC下降为4个,实在让人捉摸不透,中间并没有其他渲染组件会打断合批,只有这几个按钮,隐藏按钮的四个按钮子节点有四个同样状态为隐藏的Label,难道隐藏状态中也会打段批处理操作,小游戏一直在赶项目,没什么特别多的时间去测试,验证,而且本身自己也菜,寻求各位老哥帮助

1赞

这个问题时隔四年还存在呢,老板现在让我这个菜鸡优化。

把老板优化

这个问题时隔五年还存在呢