您好,欢迎来到二三四教育网。
搜索
您的当前位置:首页移动端草海的渲染方案(二)

移动端草海的渲染方案(二)

来源:二三四教育网

书接上文

前文介绍了Unity内置 Terrain 刷草的一些缺陷,并且介绍了3款插件:

下面就简单介绍一下这几款插件的做法,以及我们的选择。

如何刷草

参考一下 TerrainData 的API,我们可以通过脚本获取刷草信息,然后自己来做渲染。

沿用 Terrain 的刷草方式有兼容性上的好处,但是这里就强迫你必须选择 Terrain 来做地表了。

比如下图,我不但在地表刷了草,也在Cube上刷了草。

image

GPU Instancing

渲染大面积草,GPU Instancing 是非常合适的。

然而,Unity的渲染方案是把地表分成一个一个的 Patch,每个 Patch 的草合并成一个大的Mesh,以此来降低 Drawcall,但是 多个Patch 的渲染是无法通过 GPU Instancing 提速的。

我们看一下 GPU Instancing 需要满足的条件:

Use GPU Instancing to draw (or render) multiple copies of the same Mesh
at once, using a small number of draw calls. It is useful for drawing objects such as buildings, trees and grass, or other things that appear repeatedly in a Scene.

这里每个 Patch 生成的Mesh显然是不同的......

当然,我们可以突破这个限制。

既然要求 相同的Mesh,那我们可以 把Mesh的计算从CPU移到GPU:把影响 Mesh差异 的因素 ( 比如 Noise高度 ) 编码到纹理,然后在 顶点着色器 采样纹理再把这些差异应用到顶点。

这样我们就可以用相同的Mesh来渲染,即满足 GPU Instancing 的开启条件,又可以满足表现上的多样性,顺带把前文提到的 运行时合并Mesh产生的CPU峰值 也优化掉了。

uNature 为例,场景依然会被栅格化,如下图:

image

这里的 蓝色格子 类似 TerrainPatch,处于同一个 紫色格子 内的蓝色格子是可以通过 GPU Instancing 来渲染提速的。

如果不考虑 LOD密度 的差异,每个 蓝色格子 的Mesh是一样的,最终表现上的差异被编码到了 顶点uv 以及 GrassMapHeightMap 这2张纹理中去了。

HeightMap 一览:

image

具体的编码方式我就不细说了,大家可以参考源码。

事实上,Unity在 2018.3 及以后的版本,对 Terrain 的渲染也加了 GPU Instancing 的支持,原理和我上面说的差不多:

When enabled, Unity transforms all of the heavy terrain data, like height maps and splat maps, into textures on the GPU. Instead of constructing a custom mesh for each terrain patch on the CPU, we can use GPU instancing to replicate a single mesh and sample the height map texture to produce the correct geometry. This reduces the terrain CPU workload by orders of magnitude, as a few instanced draw calls replace potentially thousands of custom mesh draws.

不过,一直到我目前在用的版本 2019.3,Unity对于 地形草(Terrain Detail) 的渲染方式还是老样子......

GPU Instancing 的 API

关于 GPU Instancing,如果通过脚本来操作,Unity提供了如下2个接口:

  • Graphics.DrawMeshInstanced

  • Graphics.DrawMeshInstancedIndirect

考虑到移动设备的兼容性,我们一般会选择 Graphics.DrawMeshInstanced 这个接口,不过 Graphics.DrawMeshInstanced 有一个最大数量 1023 的限制:

Note: You can only draw a maximum of 1023 instances at once.

如果我们以每一株草为单位来渲染,很容易就会突破这个限制。

image image

每个相同颜色的格子属于同一个 Drawcall,和 uNature9宫格 管理方式并不相同。

我们的选择

好了,插件就介绍到这里。

  • 作者已经很久没有更新了。
  • 代码有不少bug。
  • 针对移动端还要做很多优化。

无论如何,二次开发是必不可少的。

不过,有了 GPU Instancing,大面积的草海已经变得可行了。下面会继续介绍草海的其他渲染技巧以及模仿 塞尔达 的一些好玩的效果。

个人主页

好了,拜拜。

Copyright © 2019- how234.cn 版权所有 赣ICP备2023008801号-2

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务