地形生成需要大量的矩阵协同工作,来生成地形的高度,纹理等信息,这在引擎或游戏生成地形的模块中都是基本前提。
表面上看地形是由等距离的顶点构成的简易网格,但是实际的地形生成需要的网格顶点更加复杂。地形网格是用一种连续细节层次算法构造的,也称为CLOD(Continuous Level of Detail),可以简单认为这是一个动态的多边形网格,它提供了更多顶点的区域,有更多的细节。通过这种技术,地形的存储就得到了优化,使得平坦的区域可以用相对较少的顶点来表示。如下图所示:
上图为Unity中的地形刷绘,可以看到平坦区域网格会更加稀疏,而山坡等复杂位置,网格与顶点会更加密集。这就是CLOD技术在地形上的应用。根据CLOD的定义来讲,可能会觉得技术细节实现起来比较复杂,但是我们可以把复杂问题简单化,如何做呢?可以把整块地形当作一个2D区域,如下图所示:
接下来需要做的就是将地形作为包含高度值的2D矩阵来看待。如下图:
这样的矩阵叫做HeightMap(高程图),通常会看到它们以这样的灰度图表示。
有点像噪声图有没有?图中的颜色越白,那个区域的顶点就越高。如下图所示:
而黑色代表的就是低洼的地形点。黑白只是HeightMap的感官表现,内部表示就是我们看到的2D数值矩阵,矩阵中的每个值(浮点数或整数)对应了可视高度图灰度的大小,正常情况下这些值的范围在0~1之间,0代表最低点,1代表最高点。他们代表着一种可以与最大高度值组合,来设置地形实际物理高度值比例的方式。例如,如果HeightMap中的某个值是0.5,而最大地形高度是500,那么地形网格,代表对应那个点的顶点将被设置为250。如下图:
因此,我们可以定义不同的地形最大高度并使用相同的HeightMap,来创建不同的地形景观,如图所示:
注意:虽然使用了相同的HeightMap,但是由于实际的最大地形物理高度不同,所以CLOD所计算生成的网格并不一致。但是无论地形多大都还是应该视为一个正方形的2D矩阵。
因为地形网格是呈方形的,所以HeightMap的分辨率宽和高是一致的,而地形分辨率的计算方式是沿地形边沿的方格数来计算的。一般为了提高效率,分辨率的值一般为2的倍数,但是比较令人迷惑的一点是地形HeightMap的分辨率是1加上地形分辨率512,所以HeightMap分辨率的最终结果是(513,513)。如下图所示:
为了理解这一点,假设有个小地形,是两两成对的,所以地形分辨率为(2,2),如图所示。
但是HeightMap的分辨率并不能直接等同于(2,2)。是因为方块网格是由顶点所组成的,也就是它的宽和高各自都有3个顶点,如下图:
上面说到HeightMap矩阵中的每个值对应的是地形网格中的顶点,所以(2,2)的网格数对应的(3,3)的顶点数,最终HeightMap的分辨率也就等于(3, 3)。
上图可以看到,高度图中的值必须与每个维度中的顶点数对齐。
另外再来看看影响地貌的其它方式。比如,我们有下面几张植被图,它们需要在不同的地形区域显示不同的植被外貌,并展示他们混合的方式,实现方式在这一章中不会做过多的介绍,这些内容将会在后面做详细讲解。