UI批量渲染优化

mark

方便加个扣扣?

mark

我发你消息了

mark

2.0.9基于楼主的改了一点,设置为这种渲染模式下,conf里没配置的默认为0(因为感觉大部分节点都应该是一个图集可以放一起渲染),label自动后排,这样配置写起了就没有那么繁琐
楼主你看这样有没有什么问题呀?

更新一下,楼主这个的opacity 好像有点Bug,改不动透明度,我在2.0.9的解决了

let childrens = [];
let cqueue = [];
_proto._childrenBatchRender = function(node) {
    node._renderFlag &= ~CHILDREN;
    node._renderFlag |= CHILDREN_BATCH_RENDER;
    let cullingMask = _cullingMask;
    let batcher = _batcher;

let parentOpacity = batcher.parentOpacity;
let opacity = batcher.parentOpacity *= (node._opacity / 255);

let worldTransformFlag = batcher.worldMatDirty ? WORLD_TRANSFORM : 0;
let worldOpacityFlag = batcher.parentOpacityDirty ? COLOR : 0;
let worldDirtyFlag = worldTransformFlag | worldOpacityFlag;

let config = node.config;
childrens.length = 0;
cqueue.length = 0;
Array.prototype.push.apply(cqueue, node._children);
let ch = null;
node._batcherOpactity = opacity
while(cqueue.length > 0) {
    for(let i = 0, len = cqueue.length; i< len; i++) {
        ch = cqueue.shift();
        if(ch.active) {
          ch._batcherOpactity = ch.parent._batcherOpactity * (ch._opacity / 255)
          ch._color._fastSetA(ch._opacity * ch.parent._batcherOpactity);
          childrens.push(ch);
          Array.prototype.push.apply(cqueue, ch._children);
        }
    }
}
childrens.sort((ch1, ch2) => {
    function _getRenderIndex(node){
        let name = node._name
        // 设置节点排序默认值为0
        let index = 0
        if(config[name]){
            index = config[name]
        }else{
            // 设置Label的Index
            const LabelIndex = cc.Enum({
                NONE: 109,
                BITMAP: 107,
                CHAR: 108,
            });

            const CacheMode = cc.Enum({
                0: "NONE",
                1: "BITMAP",
                2: "CHAR",
            });
            // 自动处理一些label
            if(name.startsWith("Label")){
                let label = node.getComponent(cc.Label)
                if(label){
                    let cacheMode = label.cacheMode
                    index = LabelIndex[CacheMode[cacheMode]]
                }
            }
        }
        return index
    }
    return _getRenderIndex(ch1) - _getRenderIndex(ch2);
});

let children = childrens;
for (let i = 0, l = children.length; i < l; i++) {
  let c = children[i];
  if(c.childrenCount > 0) {
    c._renderFlag &= ~CHILDREN;
  }
  // Advance the modification of the flag to avoid node attribute modification is invalid when opacity === 0.
  c._renderFlag |= worldDirtyFlag;
  if (!c._activeInHierarchy || c._opacity === 0) continue;

  // TODO: Maybe has better way to implement cascade opacity
  let colorVal = c._color._val;
  // c._color._fastSetA(c._opacity * opacity);
  flows[c._renderFlag]._func(c);
  if(c.childrenCount > 0) {
    c._renderFlag &= ~CHILDREN;
  }
  c._color._val = colorVal;
    }
    batcher.parentOpacity = parentOpacity;
    this._next._func(node);
}

以前的配置 是全部没注释的,改了就只需要单独把 散图标出来

    let config = {
        // item:0,
        // Node:1,
        // HeadImage:1,
        Sprite_Head:7,
        Sprite_Icon:3,
        // Label_name:6,
        // Label_rank:5,
        // Label_score:5,
    }
2赞

核心就是同层级的ui排一起,只要能正常显示都没问题。我觉得你的想法没问题。
你可以断点到_childrenBatchRender看看节点是不是按你的需求排序的,或者用webgl inspector调试看看是不是一层一层渲染出来的。

mark

战略插眼

mark,然后求分享一下

我在creator编辑器中做了一个很大的额地图,有很多节点,这个该怎么去优化呢,做了自动打包图集还有drawcall四百多呢

你的这个节点层级是什么?zIndex还是?

按照这样布局的

你明确了到底是哪些节点打断你的drawcall吗?

这个不明确,因为这个地图有很多元素,布局的时候往上面添加的,那些打断了,这个就得一一查看了

那你最好先知道是什么原因导致了drawcall被打断,这样才能有目的的优化。
建议你用webgl inspector去调试下。

1赞

mark

mark

mark

mark下