我n年前写的一篇文章,(网络上可以找到),我简化了一下,作为科普知识介绍给大家,有兴趣的朋友可以初步了解一下三维地形的形成过程,HiPiHi中的地形生成比这要复杂得多,但基本原理是相通的。
引言
在虚拟世界中要求虚拟场景具有很高的逼真度,其中的三维地形逼真度是关键之一。然而三维地形的生成和绘制需要巨大的计算量,实景地形的生成还需要地形数据库的支持,在运算能力非常有限的PC机中实时生成逼真的实景三维地形一直是业界的一个难题。三维地形的生成方法经过了多年的探索,现已形成一系列优秀的算法,这里介绍入门算法,其他高级算法都是在这个基础上改进的。
1 算法实现过程
Direct3D中,三维绘图使用DrawPrimitive方法,DrawPrimitive方法将三维模型分解为基本的点,线,和三角形面三种,三维地形生成法中将地形全部分解成三角形,使用DrawPrimitive方法绘制一系列三角形,从而绘制出整个地形。DrawPrimitive绘制三角形的方法有三种,第一种是绘制离散的三角形,每个三角形分别指定三个顶点,这种方法适合绘制零散的三角形,对于绘制成片的三角形效率较低。第二种是绘制三角形序列,第一个三角形指定三个顶点,其余的三角形只需要指定一个顶点,另外两个取前一个三角形的最后两个顶点,这样绘制的三角形全部连接在一块儿,适合于绘制成片的三角形。第三种是绘制三角形组成的扇形,以第一个顶点作为所有三角形个公共顶点,为成一个扇形,该方法只适合绘制扇形类的面。本地形生成方法采用第二种方法,但将地形中所有的三角形的顶点坐标按首尾相接方式排列起来以适合于第二种绘制三角形方法很难,幸运的是Direct3D提供了顶点索引的绘图方法,只要将待绘制顶点的编号传递给DrawPrimitive的姊妹函数DrawIndexedPrimitive,就可以完成和 DrawPrimitive一样的功能。顶点在内存中采用数组的方式存储,因此顶点编号是顺序编号。因此只要提供一个使三角形的顶点按首尾相接的索引序列,就可以完成高效的绘图。
三维地形生成的过程如下:
第一步:初始化一个正方形网络(如图1),假如为64×64个方格,每个正方形网格用两个三角形表示。网格的边长由地面大小决定,比如网格边长为5米,地面大小即为5×64=320米。(网格的边长小,生成的地面就小,网格的边长大,生成的地面就大,但地面的逼真度降低,试验表明采用5米比较合适)。
图1 正方形网格示意图(4×3)
按这种方式做完的正方形网是一张平面(坐标y均为0),它表示的地面将是一片平地,不含高度信息。
地形的高程数据存贮在一个图片文件里,该图形文件按实际地形高程测绘,使用图形中的红色分量表示地面的海拔高度,红色分量从0~255共有256级,这样地面的高度也有256级,这样的精度对于娱乐领域的三维地形已经足够。本方法中,为进一步提高地形的真实度,还在地形中融入了水面的效果,只要将高程图的红色分量指定为0,将生成水面而非地面,要指定为陆地,红色分量范围为1~255。高程图中的绿色分量用来指定是否有树林,绿色分量越大,表示树林越密,同时这片土地将呈现为草地效果,但绿色分量不可滥用,因为绘制树木很费时间,树木过多将降低程序地实时性,一般将可见地树木数量限制在500棵以内。典型地高程图 如图2
图2 典型高度图
图中为了直观,将红色成分为零的区域绘制成蓝色,可以明显的看到水域部分构成了一条河流和两个湖泊。
要使地面逼真,地面还应该贴上一层纹理图,纹理图可以是典型地面的照片,或用图像处理软件制作而成。为了正确贴上纹理图,应该该顶点指定纹理坐标,因显示存储器是很有限的,所以纹理图不可能很大,相对于巨大的地面来说,纹理图显得非常不足,因此纹理图要重复使用,就好像贴地砖一样,贴在地面上,这样带来的问题是地面上的纹理呈现周期性,就好像真的是地砖铺的一样,而且纹理图的拼接处会出现难看的裂纹,要减少这些现象,首先纹理图不能太小,其次纹理图的边缘要做特殊处理,使纹理拼接的时候不出现裂缝(这种图叫做可拼接图,广泛用于网页的底纹),典型的地面纹理图如图3。
到现在为止地面还是一张平面,还没有将高度数据写到顶点坐标里。高度数据顺序存贮在图像文件里。可以根据地面的水平坐标去高度图像中寻址,获取高度数据,高程数据加入网格中后如图5所示。
为了提高绘制速度,对地形网格中每一小组网格都进行一次可见性判断,如果网格位于可视区内(屏幕内),就绘制该网格,否则不绘制。
2结束语
本文介绍的三维地形生成算法为典型的基于高度图的均匀网格地形生成算法,具有学习三维地形生成算法的入门指导作用。试验证明,在配置为PIII 667MHz,128MB内存,Matrix G400显示卡的计算机中以分辨率为1024×768运行,速度达到35帧/秒以上。