基于DirectX的三维地形绘制及三维拾取方法的研究

2013-04-29 17:18朱玉君黄媛媛颜家康
科协论坛·下半月 2013年6期
关键词:游戏

朱玉君 黄媛媛 颜家康

摘 要:随着图形处理技术及显卡处理能力等的日益成熟,三维游戏已经成为游戏市场的主导。主要介绍基于Microsoft的一套功能丰富的底层API--DirectX的最基本的三维地形绘制过程以及三维世界中拾取的研究,为游戏学习者提供一种易于理解的方式来进行3D技术中难点的学习。

关键词:游戏 三维地形 三维拾取

中图分类号:TP391.9 文献标识码:A 文章编号:1007-3973(2013)006-101-02

1 引言

随着游戏玩家经验的积累和科技体验、审美能力的提高,传统的二维世界游戏已经无法满足人们享受娱乐的需求,游戏为了适应市场的需要,必须变革。从Directx1.0~Directx10的发展史可以窥见游戏世界的进化历程:从最初Directx1.0仅能够做的直接读取硬件信息,开发的游戏能实现对二维图像进行加速,Directx2.0中D3D部分的雏形到Directx7.0支持T&L技术,使得CPU从繁重的位置、灯光等计算中解放出来,使得没有高速的CPU也同样能流畅的跑起3D游戏直至Directx10统一了渲染架构,使得GPU更加高效,3D世界进一步拟真化。DirectX作为当今游戏底层API的引导者这一格局,也明示了3D游戏才是市场发展的趋势这一事实。因此,游戏学习者必须对3D游戏有所涉及。了解三维游戏场景中最基本的地形绘制,有利于学习者对三维游戏有直观的认识。拾取算法的研究,有助于游戏学习者对3D游戏的深入了解。

2 三维地形绘制

游戏场景通常会架设在起伏的山坡,绿地,沙滩,雪地,树林等自然环境中,这样的场景可增加游戏的逼真度和吸引力。友好精美的游戏场景无疑会使得游戏在竞争激烈的市场中获得第一眼优势。

2.1 地形高度图的创建、访问和修改

通过地理学习可知,一般用灰度图来表示地理位置上的海拔,颜色越深的就表示海拔越高,灰度图是高度图的一种表示类型。因此,进行三维地形绘制,我们使用一种最简单的方法,通过使用图形处理应用程序Photoshop来进行高度图(指定灰度图类型)的绘制,通过颜色的设置来表示你想要的地形起伏。高度图绘制完成之后,将文件保存为8位raw文件,因为raw文件连续存储了图像中以字节为单位的每个像素的灰度值,因此,高度只能在【0,255】区间内变化,对于普通地形,这个值足够平滑,若这个区间不足以表达我们要的地形,可以在高度图数据加载到程序中时对其进行一个比例变化,重新分配一个精度更高的类型来存储高度值。

使用地形类(Terrain)中定义的readRawFile成员函数对高度图文件进行读取。使用类中提供的两个函数getHeightEntry 和setHeightEntry函数对高度图中的值进行访问和修改。

2.2 创建地形的几何信息以及为每个顶点建立索引

一般灰度图创建时灰度图形与将要创建的地形的尺寸是相同的。高度图绘制完毕,就开始创建地形的几何图形,即对高度图中的每个值创建对应的顶点。Terrian类中通过其构造函数来完成创建过程。将要创建的几何地形图的基本信息通过构造函数的参数列表传递,参数包括已创建的raw文件字符串文件名,每行、每列的顶点数以及每个单元间距以及比例变化值,通过这些参数,还可以计算出地形的其他变量,如每行的单元数,每列单元数,地形几何图形的宽度和高度,总的顶点数以及其中三角形面片数目等。创建好地形的几何图形之后,就需要计算几何地形中的各个顶点具体的坐标值。可以假设已创建的地形几何图为一个方格棋盘,左上角的第一个顶点作为start,即第一个点,然后每隔每个单元间距,根据输入的每行每列的顶点数逐行生成顶点,一直到达右下角的end即最后一个顶点为止。Terrian类使用的computerVertices成员函数就是根据上述过程进行计算,通过计算就可以获得每个顶点的x和z坐标的定义,而每个顶点的y坐标的值这要根据所加载的高度图数据结构中的相应项来获得。计算机要使用图形中的每一个顶点,就必须为其添加索引,因此,需要为创建的地形图的每一个顶点创建索引。为计算三角形栅格各顶点的索引,只需要从上述所说的start顶点至end,依次遍历每一个地形几何图中的方格,并计算构成每个方格的三角形面片的定点索引。对于一个第i行、第j列的方格中的两三角形面片的顶点,通过通用公式:

△ABC ={i*每行顶点数+j,i*每行顶点数+j+1,(i+1)*每行顶点数+j}

△CBD={(i+1)*每行顶点数+j,i*每行顶点数+j+1,(i+1)*每行顶点数+j+1}

即可求得每个顶点的索引值。Terrian类中的computerIndices成员函数就是基于这样的算法为几何地形中的每个顶点添加的索引值。

2.3 对地形进行纹理映射和光照处理

为了使创建的地形更加细致真实,需为创建的地形图增加纹理和光照。Terrian类的纹理映射方式是加载一个已经创建好的纹理文件,应用其纹理数据,使得最终的地形呈现出沙滩、草地或者雪山等有纹理文件决定的样貌。在场景中,通过添加成员函数lightTerrian来实现光照。使用漫反射光照,来显示地形明暗,使场景更加逼真。

3 三维拾取

拾取操作是指当在屏幕上用鼠标点击某一个图元时,应用程序能返回改图元的某些信息,拾取到图元,也就意味着我们对拾取到的对象具有了控制权。当鼠标在屏幕上点击一个物体想选中,这个点和3D世界中的物体分属不同的空间,如何判断显示屏上的这个点就对应着3D场景中的那个物体呢,拾取算法,就是完成这个判断的。

3.1 坐标转换

描述好了几何学上的3D场景和设置了虚拟照相机,我们就要把这个场景转换成2D图像显示在显示器上。在这个过程中,涉及到几个坐标系(空间)的转换:自身坐标系(建模空间)--世界坐标系--观察坐标系--投影窗口--显示屏,分别通过世界变换、视图变换、透视投影及视口变换实现转换。经过所有转换,就完成了3D场景在显示屏上可见。

3.2 拾取的实现

由拾取的定义可知,拾取算法的过程,其实就是坐标系逆向转换的过程。判断的实质是,从观察坐标系原点出发,与经转换后的屏幕上的点,形成一条射线,若这条射线与物体三角网格相交,这说明拾取成功。

3.2.1 窗口的转换

鼠标点击屏幕上的一个点,Windows API中的GetCursorPos函数会自动获得该点的坐标,根据屏幕上的坐标,通过视口变换矩阵的逆矩阵得到投影窗口上的坐标。

3.2.2 拾取射线的计算

在观察坐标系中,拾取射线是一条从观察坐标原点的发出的射线,因此,只要在确定一点就可以获取这条射线在观察坐标系中的表示。我们假设这个点就是透视投影平截头体近切面上的一点。此时,我们的这个点已经通过变化到了投影窗口,通过GetTransform函数,求得投影矩阵,根据投影坐标=观察坐标*投影矩阵关系,求得该点在观察坐标系中坐标。已知原点及线上一点,即可在观察空间中求的拾取射线。

3.2.3 统一射线与物体的坐标系

上述计算出的射线是在观察坐标系中,未完成相交,我们将射线与物体放在同一个坐标系中,即世界坐标系中。

3.2.4 射线与物体的相交运算

利用D3D提供的扩展函数D3DXIntersect函数,即可完成相交测试。

4 结束语

3D游戏的引擎发展迅猛,为3D游戏提供了坚强的发展后盾,3D游戏也必将顺应市场需求,不断地改进,做出更加酷炫的3D游戏。本文通过对3D地形绘制及拾取算法的简短介绍,希望能够对读者了解3D游戏有所帮助。

参考文献:

[1] Frank D.Luna.Introduction to 3D Game Programming with DirectX 9.0[M].

[2] 透视投影变换理论推导[OL].http://www.scouvr.com//D3D/201102/33407_2.shtml.

猜你喜欢
游戏
夜间游戏
游戏
送信游戏
数独游戏
疯狂的游戏
爆笑游戏
第八章直接逃出游戏
第八章 直接逃出游戏
游戏五计算
游戏四换牌