学习目标:
- 了解如何生成地形的高度信息,以实现自然地形中由山脉到山谷的平滑过渡
- 理解如何生成地形的顶点和面片数据
- 了解如何对地形映射纹理以及如何进行光照处理
- 了解如何将摄像机安置在地形中,以模拟观察者在该地形中的行走
地形网格其实就是一由XZ轴平面中以三角形珊格组成的网格面,但是方格面中的每个顶点都被赋予了一个高度值,这样该方格就可通过方格对应高度的平滑过渡来模拟自然地形中山脉到山谷的变换,当然,我们还需要对地形网格应用一些细致的纹理来表现出不同的场景,以模拟真实世界的场景
这里将引导实现一个 Terrain 类,该类使用了一种强力方法(也称蛮力),意思是说我们通过一个顶点缓存或索引缓存来保持整个地形的顶点或索引数据,然后进行绘制,对于小地形就能满足要求的游戏,借助支持硬件顶点运算功能的显卡就足以应付,但是对于需要庞大地形的游戏,可能需要做一些细节层次的调整或裁剪工作,因为该地形模型中巨大的数据量会使该强力算法不堪重负,接下来我们开始吧
高度图
我们用高度图来描述地形中的山谷或丘陵,高度图其实就是一个数组,该数组的每个元素都制定了地形方格中某一特定顶点的高度值,(另一种实现方法可能用该数组中的每个元素来指定每个三角形格栅的高度),通常将高度图视为一个矩阵,这样高度图中的元素就与地形栅格中的顶点一一对应
高度图被保存在磁盘中时,通常为其每个元素只分配一个字节的存储空间,这样高度图只能在【0,255】内取值,该范围足以反映地形中的高度变化,但在实际应用用,为了匹配3D世界的尺度,可能需要对高度值进行比例变换,这样就可能超出上诉区间,例如我们在3D世界中的度量单位为英尺,则0~255之间的高度值尚不足以表达任何我们感兴趣的目标点的高度,基于上述原因,当将高度数据加载到应用程序中时,我们重新分配一个 int 或 float 数组来存储这些高度值,这样我们就不必拘泥于 0~255 的范围,从而可以很好的匹配任何尺寸
高度图有多种可能的图形表示,其中一种就是灰度图,地形中某一点的海拔越高,相应的该点在灰度图中的亮度就越大。
创建高度图
高度图可自编程序来生成,也可用图像编辑软件来创建(如 Adobe Photoshop),使用图像编辑软件可能是最简便的方式,因为该类软件往往提供了可视化的交互环境,用户可随心所欲的创建自己所需的地形,此外,还可利用图像编辑软件提供的一些功能如过滤镜(滤波器)来创建一些有趣的高度图,一旦完成高度图的创建,我们需要将其保持为8位的RAW文件,RAW 文件仅连续存储了图像中以字节为单位的每个像素的灰度值,这样就使得这类文件的读取操作非常的容易,图像编辑软件可能会询问是否要为 RAW 文件增加一个头文件,请选择“否”
注意:
高度信息不一定非要用 RAW 格式的文件来存储,可根据需要选择任意一种格式,RAW 仅仅是我们所使用的图像格式中的一种,这里采用 RAW 格式时因为许多图像编辑软件都支持将图像导出为该格式,而这类文件的读取操作十分简单
加载 RAW 文件
由于 RAW 文件本质上是一个连续的字节存储块,我们用如下方法很容易地读取该字节块,注意,变量 _heightmap 是 Terrain 类的一个成员变量,其定义如下: