小伙伴说我的拼图游戏用Mask不能合批...

引言

哈喽大家好,我是亿元程序员。

不知道小伙伴们还记不记得笔者上次通过Mask实现拼图游戏的圆角效果。

那期文章一发出去就收到了很多小伙伴们的评论,其中呼声比较高的:

当然也有很多小伙伴说现在手机性能都相对来说比较高了,没必要纠结手表能不能玩:

笔者觉得还是可以优化一下的,不然写文章都没有素材了,建议大家不要学。

言归正传,本期带大家一起来看看,在Cocos游戏开发中,如何通过Shader实现能够合批的拼图游戏,将DC从400多降到个位数

本文源工程可在文末获取,小伙伴们自行前往。

回顾一下

上期笔者讲解了如何通过Mask实现圆角拼图,有很多小伙伴提出了不能合批的问题,先简单科普一下:

合批就是将多个需要绘制的图形元素合并在一起,然后一次性提交给GPU进行渲染。

这样做可以显著减少CPU调用图形API绘制命令的次数,也就是降低DrawCall

笔者把上一次的拼图改成10*10,也就是100张拼图时,DC高达404,差点就找不到了:

怎么来的?我们简单分析一下:

其中:

  • Mask2个。

  • Sprite1个。

  • Graphics: 1个。

所以总数高达4*100,也就是400DC

那我们要怎么才能合批,把DC降下来?

不用Mask

既然MaskGraphics占大头,我们只能换个方式了。

image

上期我们讲到,实现圆角效果除了Mask以外,还可以通过Shader或者自定义Mesh来完成,本期我们通过Shader来完成。

如上图通过Shader实现圆角效果的原理也比较简单,把拼图块分成以下4个部分:

  • 1.图片部分:保留原图片纹理。

  • 2.白框部分:设置白色。

  • 3.黑框部分:设置黑色。

  • 4.框外部分:设置透明。

我们只需要通过距离判断当前像素处于以上4个部分的哪一个部分,即可完成Shader的编写。

下面我们一起来进行圆角Shader实战。

圆角Shader实战

下面开始实战,本次实战不代表最优解,欢迎小伙伴们评论区一起探讨,这部分比较枯燥,小伙伴们可以直接拉进度条

1.创建Shader

我们依旧在资源管理器中搜素sprite,找到builtin-sprite这个Shader,然后Ctrl+C/V到我们的assets目录下。

image

2.添加properties

想要计算像素处于哪一部分,我们需要通过一些列的参数来计算判断。

3.定义uniform

在片段着色器中接收参数(是否圆角、是否有边框、uv范围、纹理大小、圆角半径、黑框宽、白框宽、黑框内嵌等等)。

image

4.计算各层的边界位置

在片段着色器中计算各层的边界位置:

  • 黑框外层边界(最外层):

  • 黑框内层边界(白框外边界):
    image

  • 图片层边界(白框内边界):
    image

5.计算各层的中心点和半尺寸

计算各层的中心点和半尺寸,同时计算各层的圆角半径。

6.计算当前像素到各层边界的距离

通过SDF方法计算出像素到各层边界的距离。

得出像素处于哪一层:

7.根据距离判断像素属于哪一层,并设置颜色

最后根据距离判断像素属于哪一层,并设置颜色,即可完成对应的效果。

8.应用

创建材质并且应用到sprite

最后我们通过Pass直接设置uniform完成参数的传递。

9.效果演示

一顿操作猛如虎,通过上述的操作,我们成功去掉了MaskGraphics画线,DC也成功降了下来:

虽然DC已经是之前的四分之一,但是拼图碎片之间为什么没有合批?

材质不同

根据合批的要求,需要相同的材质和纹理,从上面来看,虽然我们用的是同一张纹理,但是材质是单个碎片单独new出来的:

image

因此首要的第一步,我们需要把材质改成同一个。

1.共享材质

声明一个静态的唯一的材质sharedMaterial

image

2.提取公共常量

公共的,所有碎片都一致的变量,还是按照原方式传递,不会打断合批。

image

3.特殊部分

对于每个碎片的边和圆角标志,因为它们都不相同,如果使用同一个材质,通过原方式传递,会导致所有的碎片的边框一样。

这里我们借助sprite.color去传递这部分参数,不会打断合批。

image

4.color通道中解码数据

解码标志位,拿到我们传递的参数。

5.效果演示

拿到参数后,圆角和边框算法和原来保持一致,运行后即可看到我们的效果,DC成功降到了个位数。

完整效果

结语

以上就是通过Shader实现能够合批的拼图游戏的实战,不知道我说明白没有。

一个拼图游戏都出了这么多期了,还有什么素材可以继续?

本文实战完整源码已加更到亿元Cocos小游戏实战合集(9/10),不占份数,已经拥有的小伙伴可以直接更新。

13赞

太好了收藏先

太厉害了.

:smiling_imp:可以找个低端机试试,没准shader的还不如mask的 哈哈~

必须点赞,最喜欢看技术贴了。

mark 一下回头自己尝试一下

太强了顶顶顶

还是你们公司好,做的游戏项目,还能发出来分享

强!!除了强,我也只能说宇宙无敌强了!

刚看标题,还以为是用mask去实现,然后解决了合批问题 :joy: