【渲染优化】Sand Blast 流沙俄罗斯

制作前言

大家好,我是98k ,最近兴趣来了,流沙俄罗斯方块-核心优化,

技术角度,一个好游戏,有好核心玩法外,拼的就是质感手感,

现今小游戏,同质化越来越严重,如何优化性能提升质感,是每个技术人必备的技能。

获取地址:高性能-流沙俄罗斯方块

在线体验:Sand Blast Tetris

效果展示

方案选择

在选用方案前,先了解下基本显示规格

底盘规格:80x120 = 9600 格子
形状规格:24x24 = 576 格子

方案1,使用多sprite,使用节点node方式

优点: 方块独立,动画方便

缺点:

  • 每个格子一个sprite , 节点太多,消耗性能

  • 三角面数( 9600 x 2 = 19200) ,更新数据大

方案2,使用单sprite,自定义组装mesh数据

优点:单个sprite,mesh数据顶点填充,性能有保证

缺点:

  • 三角面数( 9600 x 2 = 19200),更新数据大
  • 需要自定义 assembler,同时兼容原生,新手不适合

方案3,使用单sprite,回读texture控制显示数据

优点:

  • 仅需要一个sprite实现,没有节点消耗
  • texture 更新数据量小,9600 格子对应texture 9600像素
  • 支持原生和h5,不需要定制引擎,可以实现色块增删改查

缺点:动画制作效果花样,可控性相对sprite少( 如果你是shader高手,无视)

源码实现分析

本方案采用的是第三种方式,单sprite + texture控制数据,

流沙控制算法 -> 产生颜色data -> 上传textrue -> sprite读取texture显示

texture 数据的传输

原理很简单,更新同步方块颜色,

使用cocos引擎的纹理uploadData接口上传,

优化提示:data数据,标记脏区,本帧可以多次修改,最后一次提交 (减少硬件IO),更极限做法,可以进行最大区域收集,进行局部提交。

texture 数据的读取

没花色,没印花
8beffa9ea647a786a3e123c70292c86b

有花色,没印花
f758981cfeeb53297f298c903fcea9dc

有花色,有印花
c7e10979848f881bd52259df7506cadc

shader的实现

在shader中回读颜色 (效果增强,循环印花纹理)

优化提示:循环贴图做印花,只要单精灵就解决,日常必备优化基本操作

53817ce4-c1f1-4b4c-96cd-23cb683fb46e

花色的生成

纯色的显示效果,显示过于单调,流动感不强,

我们为每个主色,生成100个随机花色,提供查表使用

优化提示:日常查表(不是查水表) 是优化的基操,对于大量的颜色读取,可以预先生成查表数组。

流沙算法实现

下落算法

对当前位置,中下,左下,右下,的试探,

优先中下,交替检测左下,右下,保证均匀下落,

用户自由发挥,可以借助AI编写调整,写出更好感觉

对x偏移,y+1下探
0中下,-1左下,1右下
let directions = [[0, -1, 1], [0, 1, -1]]; //x轴偏移

消除算法

经典的BFS广度搜索(DFS深度搜索,色点多递归深度太长,弃用),对八个方向进行遍历,

let directions = [[0, 1], [0, -1], [1, 0], [-1, 0],[1,1],[1,-1],[-1,-1],[-1,1]];

在遍历过程中,记录x最小边缘minX,记录x最大边缘maxX,

当minX = 0,maxX=场景最大格数,

就是左右连通块,可以进行消除。

优化提示:flowCoord 记录活动的流沙像素,避免全局搜索连通性,优化性能。因为,大部分情况下,是少量表面的沙在流动。(另一种局部优化算法,记录活跃高度范围,也是可以的,优化讲究灵活)

体验关注

做功能容易 ,打磨细节,优化性能,是一个非常耗时间过程,

经过上面的优化,游戏性能效果,已非常可观(高刷120hz

移动触摸手感,动画交互效果,比较锁碎不再展开解读了.

详细源码,点击下面连接,限时优惠中

获取地址高性能-流沙俄罗斯方块

在线体验

欢迎添加个人微信
8eed28a05e787fde

优化必备:【 UI 合批优化】多纹理合批3.x
优化必备:【 Spine 合批优化】多纹理合批3.x

26赞

太牛逼了,拜读大作

简单介绍,日常基操

日常给好东西点赞 :heart: :heart: :heart: :heart:

和用 Graphics画的性能,差别大吗

刚看了下Graphics的assembler源码,

是基于mesh,可以间接等同第二种方案

想问下沙盘的texture格式使用的R8吗

RGBA8888

大佬,欢迎观摩

牛逼大佬啊

大佬牛逼啊

大佬是算完沙子的数据直接去查询颜色表,然后赋值到textureData里面吗。考虑全局沙子流动(假设几乎填满,底层消除,大部分的沙子就会参与到流动),那遍历次数是沙盘总数 * 每个沙子的像素数(9600 * 24 * 24),这边遍历次数应该是不太可能的吧,因为我现在也是在做这个游戏,感觉大佬代码写的很简洁想请教下。

每帧算完,被动刷新,

如果有变化会同步一次全像素数据,

全局沙子的游动,也就9600个像素。

下落检测,是有个优化技巧,(方块列深度&底盘列高度)

感谢大佬指教,大概明白了,我以为你的印花是附带到每个沙子的颜色块里面的(一开始没搞懂啥叫印花),我这边的需求就是不同颜色的沙子的边框(印花)对应不同的颜色,所以需要跟随沙子流动动态变化。

老友,什么时候回深圳

1赞

@wangzhe 举报楼主,发的链接携带个人微信二维码,根据版规,建议禁言

1.7 给出邮箱 / 微信 / QQ号等私人联系方式,用以售卖项目源码和美术资源的。

最近抽空,对 creator 2.x 原生和小游戏, 也进行了适配和支持

creator 2.x 版本已经支持

新版链接

膜拜大佬, :ok_man:

我也做了个,模仿的SandBlast,链接:Cocos Creator | SandPuzzle

你这个卖不卖大佬