原图如图:
运行后效果如图:
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;
}
就能得到如图单张效果:
第二步写一个圆形遮罩的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 就完成了。
效果如图:
就完成最终效果。
源码:http://store.cocos.com/app/detail/4025