像素艺术家是我业余制作的一款小工具的代号,是一个集合像素画图片,像素画编辑一体的应用,在这里分享在程序性能调优的过程。
所有的物体创建/销毁都是基于池,也就避免了额外的GC开销,缩短CPU耗时。
每次用笔刷绘图的时候,当鼠标划过网格,都会记录位置,划过的这个位置就作为一个 Tile 渲染的基本点。 在这个点上再去生成一个mesh,进行染色,标注这里被画出了颜色。
由于需要渲染的Tile,是动态创建的,都具有自己的单独的Render,并且需要改变自己的颜色。
对于材质来说,就会在每次改变属性之后创建出新的instance,众所周知instance多drawcall就多。
这个问题,并不难解决,通过 MaterialPropertyBlock
去修改属性,可以避免instance的创建。
当使用 MaterialPropertyBlock
去处理材质属性修改后,画板的drawcall已经保持在一个极低的数量级了。
直到我准备给画板添加一个背景,也就是预创建tile,给画板一个背景色。这时候新的问题又出现了。
100x100的像素图编辑,就有一万个tile,需要去染色,虽然是公用材质,但是架不住节点多导致的CPU耗时过高。 这时候,我想起,既然最后需要导出到像素图片,为什么不直接将像素点写入图片呢?
随后,新增了一个实时渲染图,展示正在绘制的像素画状态。并且修改这个渲染tile的逻辑,每次要渲染tile的时候,不再进行mesh创建与render渲染,直接将像素写入实时渲染图。 至此,突破了之前的节点瓶颈,在512x512 ,也就是差不多2.6w像素的图片上,进行流畅的编辑。
在成功的在512x512的像素图上编辑的时候,我顺便也尝试了在1000x1000,2000x2000的像素图上进行编辑。 明显会觉得有点卡顿,分析了一下卡顿的原理,原来新的瓶颈在修改实时渲染图的频率上。 每次创建新的像素点,也就是画笔在滑动的时候路过的像素点,都会立即去做一个像素图的写入。
这个问题解决起来倒是不难,就是将实时像素图的写入频率降下来。 结合第一个优化版本的实现。每次玩家开始绘制与结束绘制之间,所有的像素点,都是用第一个优化版本,仍旧去创建tile,将这个过程产生的所有tile数据进行记录。 玩家手指抬起,结束一轮绘制,再将上一轮缓存的tile信息统一写入实时渲染图。并且回池所有的tile。
至此,在至少四百万的像素图编辑上表现得很丝滑,就如同在四百个像素点的编辑。
在增加了大贴图导入后,如果拖拽整个贴图会造成画面卡顿。原因是拖拽的是由unity的meshrender组成的画面。
画面有多少个像素点,就由多少个mesh(一个meshrender只渲染了一个像素点)。
这样数量上去了,也就又出现了性能瓶颈,为此改为了给mesh增加了一个支持贴图的材质球,匹配像素图进行缩放,将像素点都渲染到这个单位上,进行整体图片的预览,效率又上去了。
这里遇到一个问题,使用 MaterialPropertyBlock
进行针对 Texture 的drawcall 优化的时候,需要注意如果N个meshrender使用了的一个材质,但使用的并不是一张贴图,drawcall仍然会增加。
所以这边我记录玩家每次画笔下落与抬起,在期间,渲染玩家绘出的像素图,都是一张贴图。用以保证 MaterialPropertyBlock
能够正常生效。
当然这个效率优化并不会停止,就先写到这。
当然如果你想体验这个应用可以在下面链接访问:
https://px.vrast.cn/ (需要注意的是目前只适配的桌面浏览器)
https://vrast.cn/project/ (项目更新日志)
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有