多个方形头像遮罩圆形头像+合批

原图如图:
head_list
运行后效果如图:
@4`HILO2G7X%UI6{EFCC~DM
draw call 只有3,成功实现合批
第一步图片分割:
图片分割需要继承sprite 重写 updateUVs 方法 如下

updateUVs (sprite: SplitSprite) {

    if (!sprite.spriteFrame) return;

    const renderData = sprite.renderData!;

    const vData = renderData.chunk.vb;

    let col_ratio = 1.0/sprite.col_count;

    let row_ratio = 1.0/sprite.row_count;

    //左上角

    vData[3] = sprite.col_index * col_ratio;

    vData[4] = (sprite.row_index + 1) * row_ratio;

    //右上角

    vData[12] = (sprite.col_index + 1) * col_ratio;

    vData[13] = (sprite.row_index + 1) * row_ratio;

    //左下角

    vData[21] = sprite.col_index * col_ratio;

    vData[22] = sprite.row_index * row_ratio;

    //右下角

    vData[30] = (sprite.col_index + 1) * col_ratio

    vData[31] = sprite.row_index * row_ratio;

}

就能得到如图单张效果:
RMAJZR73DQI08C79ZHOIY
第二步写一个圆形遮罩的shader
代码如下:
//归一化

float normalize(float value, float min, float max) {

    return (value - min) / (max - min);

}

  #if USE_MASK

//  创建圆

//  center : 圆心

//  uv : 小图的uv

//  radius: 半径

//  blur:边缘模糊宽度

float createCircle(vec2 center,vec2 uv,float radius,float blur){

    //当中心点的距离

    float dis = distance(center,uv);

    #if USE_BLUR

    //smoothstep 平滑过渡, 这里也可以用 step 代替。

    float val = smoothstep(radius + blur,radius,dis);

    # else

    float val  = step(dis,radius);  

    # endif

    return val;  

}

#endif

     

vec4 frag() {

  vec4 color = vec4(1.0,1.0,1.0,1.0);

    #if USE_TEXTURE

      color = texture(cc_spriteTexture, uv0);

    #endif

    #if USE_MASK

      //每个小图宽度

      float width = 1.0/_col_count;

      //第几列的图

      int col_index = int (uv0.x /width);

      float x = uv0.x - width * float(col_index);

      x = normalize(x,0.0,width);

      float height = 1.0/_row_count;

      int row_index = int (uv0.y /height);

      float y = uv0.y -  height * float(row_index);

      y = normalize(y,0.0,height);

      vec2 center = vec2(0.5);

      vec2 uv = vec2(x,y);

      color.a = createCircle(center,uv,_radius,_edgeBlur);

    #endif

    return color;

}

然后创建材质 把材质拖入sprite 就完成了。

效果如图:
I~(QU0ORPA(3%YEXKY}YOD
就完成最终效果。
源码:http://store.cocos.com/app/detail/4025

6赞

可以分享下怎么做的么

2.0版本的可以用吗。

mark
mark

这个的前提条件是图集是一个nxn的网格状的图集。这种思路我以前也想过,在这种限制好了图集格式的情况下,通过传入当前这个头像的行列号,计算换算后的uv来做出可以合批的圆形裁切。

学习了…期待更多分享

单个头像考虑动态生成类似的纹理

现在已经实现远程头像的合批

已经购买,发现处理不了图片本身是长方形的情况

整个设计的头像是正方形,长方形需要调整部分参数即可。

如果是本地的,找个脚本或者找美术帮你切成圆的。 如果是需要上传到远程,可以找类似阿里云的图片裁剪加工

这样不可以合批的

阿里云访问链接直接就变成圆形了, 怎么不能合批了, 连mask开销都省掉了