美文网首页
cocos creator2.4.8 合批的shader

cocos creator2.4.8 合批的shader

作者: 许彦峰 | 来源:发表于2022-05-12 11:50 被阅读0次

    测试例子:1122,红色绿色,字号20、 50



    cc.dynamicAtlasManager.showDebug(true);
    

    动态图集情况如下:
    label.CacheModel="bitmap"

    label.CacheModel="char"

    可以观察到无论哪种模式,只要label使用的字号,颜色,字体不同,都会进行单独的渲染,注意这里的颜色,也会受影响,原因是shader里面不处理node color导致的。

    即如果label除了颜色剩下的属性都相同,都会生成同等颜色个数的label。

    通过spector.js可以找到对应的shader

    Creator\2.4.8\resources\static\default-assets\resources\effects\builtin-2d-sprite.effect

    // Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
    
    CCEffect %{
      techniques:
      - passes:
        - vert: vs
          frag: fs
          blendState:
            targets:
            - blend: true
          rasterizerState:
            cullMode: none
          properties:
            texture: { value: white }
            alphaThreshold: { value: 0.5 }
    }%
    
    
    CCProgram vs %{
      precision highp float;
    
      #include <cc-global>
      #include <cc-local>
    
      in vec3 a_position;
      in vec4 a_color;
      out vec4 v_color;
    
      #if USE_TEXTURE
      in vec2 a_uv0;
      out vec2 v_uv0;
      #endif
    
      void main () {
        vec4 pos = vec4(a_position, 1);
    
        #if CC_USE_MODEL
        pos = cc_matViewProj * cc_matWorld * pos;
        #else
        pos = cc_matViewProj * pos;
        #endif
    
        #if USE_TEXTURE
        v_uv0 = a_uv0;
        #endif
    
        v_color = a_color;
    
        gl_Position = pos;
      }
    }%
    
    
    CCProgram fs %{
      precision highp float;
    
      #include <alpha-test>
      #include <texture>
    
      in vec4 v_color;
    
      #if USE_TEXTURE
      in vec2 v_uv0;
      uniform sampler2D texture;
      #endif
    
      void main () {
        vec4 o = vec4(1, 1, 1, 1);
    
        #if USE_TEXTURE
          CCTexture(texture, v_uv0, o);
        #endif
    
        o *= v_color;
    
        ALPHA_TEST(o);
    
        #if USE_BGRA
          gl_FragColor = o.bgra;
        #else
          gl_FragColor = o.rgba;
        #endif
      }
    }%
    
    

    展开后的shader:

    #define USE_TEXTURE 1
    #define CC_USE_MODEL 0
    #define USE_ALPHA_TEST 0
    #define CC_USE_ALPHA_ATLAS_texture 0
    #define INPUT_IS_GAMMA 0
    #define USE_BGRA 0
    
    precision highp float;
    uniform mat4 cc_matViewProj;
    uniform mat4 cc_matWorld;
    attribute vec3 a_position;
    attribute vec4 a_color;
    varying vec4 v_color;
    #if USE_TEXTURE
        attribute vec2 a_uv0;
        varying vec2 v_uv0;
    #endif
    void main () {
        vec4 pos = vec4(a_position, 1);
        #if CC_USE_MODEL
            pos = cc_matViewProj * cc_matWorld * pos;
        #else
            pos = cc_matViewProj * pos;
        #endif
        #if USE_TEXTURE
            v_uv0 = a_uv0;
        #endif
        v_color = a_color;
        gl_Position = pos;
    }
    
    #define USE_TEXTURE 1
    #define CC_USE_MODEL 0
    #define USE_ALPHA_TEST 0
    #define CC_USE_ALPHA_ATLAS_texture 0
    #define INPUT_IS_GAMMA 0
    #define USE_BGRA 0
    
    precision highp float;
    #if USE_ALPHA_TEST
        uniform float alphaThreshold;
    #endif
    void ALPHA_TEST (in vec4 color) {
        #if USE_ALPHA_TEST
            if (color.a < alphaThreshold) discard;
        #endif
    }
    void ALPHA_TEST (in float alpha) {
        #if USE_ALPHA_TEST
            if (alpha < alphaThreshold) discard;
        #endif
    }
    varying vec4 v_color;
    #if USE_TEXTURE
        varying vec2 v_uv0;
        uniform sampler2D texture;
    #endif
    void main () {
        vec4 o = vec4(1, 1, 1, 1);
        #if USE_TEXTURE
            vec4 texture_tmp = texture2D(texture, v_uv0);
            #if CC_USE_ALPHA_ATLAS_texture
                texture_tmp.a *= texture2D(texture, v_uv0 + vec2(0, 0.5)).r;
            #endif
            #if INPUT_IS_GAMMA
                o.rgb *= (texture_tmp.rgb * texture_tmp.rgb);
                o.a *= texture_tmp.a;
            #else
                o *= texture_tmp;
            #endif
        #endif
        o *= v_color;
        ALPHA_TEST(o);
        #if USE_BGRA
            gl_FragColor = o.bgra;
        #else
            gl_FragColor = o.rgba;
        #endif
    }
    

    可以看到

    o*=v_color;
    

    如果字符纹理都是白色的,顶点颜色v_color如果传递过来相乘,是能够得到正确的颜色的


    那为啥creator不这么做呢?

    Creator\2.4.8\resources\engine\cocos2d\core\renderer\webgl\assemblers\label\2d\letter.js

    
     _getColor (comp) {
            WHITE._fastSetA(comp.node._color.a);
            return WHITE._val;
        }
    
        updateColor (comp) {
            let color = this._getColor(comp);
    
            super.updateColor(comp, color);
        }
    

    可以看到在组装数据的时候,会舍弃掉node.color的颜色,只保留透明度,看来还是有优化空间的

    混合有bug导致这么做


    相关文章

      网友评论

          本文标题:cocos creator2.4.8 合批的shader

          本文链接:https://www.haomeiwen.com/subject/wymsurtx.html