查看原文
其他

程序丨如何在移动端实现大规模草渲染?

日音 腾讯GWB游戏无界 2022-08-30

先上最终效果:



在群里经常看到草的问题,也会和他们一起讨论。结果现在不得不自己也开始做了,就想把一些东西给汇总一下, 然后看做出来效果如何。


按照做拼接地表的经验,我一开始就打算使用程序生成网格,通过尽量多的顶点去做,尽量不适用alpha test.原因在于使用了alphatest之后,early z就 无效了,但对于草来说,early z应该是特别重要的可以提升性能的点。


不过为了看效果,一开始还是用最简单的方式,用程序生成了一个大网格,放上贴图,看上去是这样:



首先在手机上测试了一下,法线帧率堪忧,如果视角再平一点,估计就卡了,目前这样子大概有8w个面,还可以接受。因为后面本来就有优化策略,所以打算还是继续先做效果。草肯定不会这么均匀,我先打乱下草的分布。


感觉有点差强人意,真实的草不应该是这么杂乱,而且打乱之后变稀疏了,就更丑了。调整下疏密度,稍微舒服了点, 这里觉得颜色太单一,但又不想通过额外的参数来控制颜色变化,想了一下其实可以通过顶点色或者顶点索引。顶点索引需要在shader里多几步计算,考虑到性能,还是先往顶点色里塞,如果后续需要做其他东西,我觉得可以通过uv2来塞额外数据。



考虑到自然风,打算模仿一个dx 草下面的一个算法:






最终我只采纳了windStrength的部分,ripple部分在面数不够的情况下,草扭曲的样子不是很好看。



然后开始优化性能,首当其中的就是alpha test,因为为了风场动画,顶点本来就不少了,于是干脆直接用硬边。


性能从10帧跳到24帧,确实提高很多,硬边也还可以接受,然后发现另一个问题,就是手机上跑久了很抖,应该是数值过大引起的,需要将大数值取余。这样做了之后基本可以达到要求了。暂时先不考虑性能的进一步优化,因为我发现是我的手机太差了,换了台手机其实帧率可以到60帧。我更想处理的是和草的交互,因为图中这个球其实是压着草的,但因为没有交互,看上去很奇怪。


但在这之前还是需要处理一个问题,就是草是单面的,从其他方向看就会是一条线,一般是用billboard技术,但对我这种做法却不适用,因为billboard的重点是中心点,而我这么一大片网格,中心点和草是没啥关系的。于是我就换了一种做法,堆了两层草。用十字星的形式,这样的坏处是增加了面数,但好处也很明显,让整个草看上去更加自然。


接下来要处理交互了。


想了一下方案,首先草根据对应rt里的坐标读取像素,根据像素确定歪的方向,并且做歪曲。那么如何得到这张rt呢?


第一步是球的正面下压,我的想法是根据不同朝向,分别转成颜色值并显示出来,最终渲染到rt中。


shader代码如下:



然后是运动轨迹,原理一样,只不过需要通过运动动态创建网格,效果如下:



这样rt就是用摄像机从正上方去看它,一切都很完美了。 


实际测试的时候发现一个大问题,就是如果草只有一部分顶点被压住,那么草会扭曲成很难看的样子,解决方案是把草的位置浓缩成一个点,草上面的所有顶点都用浓缩的这个点来判断,这样草的位置就一致了。



最后是插件地址:

https://www.assetstore.unity3d.com/en/?stay#!/content/132241


今日推荐  

·如何打造细致的2D捏脸系统?

·如何从零开始开发一个实时联机游戏?

·如何让美术开发更高效?腾讯游戏学院品鉴会路演游戏《单程票》分享

↓↓↓点击阅读原文,了解更多。

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存