清华大学DirectX游戏编程第14章(全20章)



《清华大学DirectX游戏编程第14章(全20章)》由会员分享,可在线阅读,更多相关《清华大学DirectX游戏编程第14章(全20章)(23页珍藏版)》请在装配图网上搜索。
1、单击此处编辑母版标题样式,,单击此处编辑母版文本样式,,第二级二级二级二级二级二级二级二级二级二级二级,,第三级,,第四级,,第五级,,,*,,第,14,章 基本地形渲染,,本章将讲述如何实现一个简单的地形类。,,主要目标:,,学习如何生成渲染地形需要的高度信息,高度信息将用于在程序中模拟山峰、峡谷等自然地形。,,理解怎样生成代表地形的顶点和三角形数据。,,学习地形纹理设置和为地形打光的方法。,,学习如何在地形渲染中控制摄像机位置,模拟人在场景中行走和奔跑的效果。,,2,,14.1,高 度 图,高度图用来描述地形的高度信息。高度图实际上是一个数组,数组中的每个元素都存储着地形网格中对应顶
2、点的高度数据,,将高度图数据读入内存时,通常为图中的每个元素分配一个字节的内存,这样高度的范围就是,0~255,。,,图,14.2,展示了用作高度图的灰度图。,,3,,14.1.1,高度图的创建,,高度图可以通过程序生成,或者通过,Adobe Photoshop,这样的图像处理软件来制作。,,图,14.3,展示了用,Adobe Photoshop,创建的金字塔地形。,,,4,,14.1.2,读取,RAW,文件,,由于,RAW,文件中的数据仅仅是连续的字节块的集合,可以用下面的方法方便地得到其中的数据。这里变量,_,heightmap,是,Terrain,类的成员,其声明如下:,,参见教材,P2
3、09,,注意这里把存储,BYTE,数据的,vector,里的数据拷贝到存储,int,数据的,vector,里,这样就可以扩大高度数据,使其超出,0~255,的限制。,,5,,14.1.3,高度图的访问和修改,,Terrain,类提供下面两个方法来访问和修改高度图中的元素:,,int,,Terrain::getHeightmapEntry(int,row,,int,,col,),,{,,return _,heightmap[row,* _,numVertsPerRow,+,col,];,,},,void,Terrain::setHeightmapEntry(int,row,,int,,col,,
4、,int,value),,{,,_,heightmap[row,* _,numVertsPerRow,+,col,] = value;,,},,6,,14.2,生成地形几何数据,图,14.4,展示了地形的一些属性、术语和需要使用到的特殊顶点。,,Terrain,类的定义如下:,,参见教材,P211,,通过构造函数传入的值,可以计算出地形需要的其他变量:,,参见教材,P212,,顶点结构声明如下:,,参见教材,P212,,7,,14.2.1,计算顶点,,下面需要计算的是纹理坐标,参照图,14.5,,通过它可以看出,(u, v),纹理坐标和地形的顶点,(i, j),的对应关系:,,,,,,生成顶点
5、的代码如下:,,参见教材,P213,,8,,14.2.2,计算索引,——,定义三角形,,为计算三角网格中的顶点索引,只需从左上角到右下角遍历每个方格,然后计算组成这个方格的两个三角形的顶点索引值,参照图,14.6,。,,,9,,14.2.2,计算索引,——,定义三角形,,通过图,14.6,发现在第,i,行第,j,列的方格具有以下性质:,,参见教材,P215,,,生成索引值的代码:,,参见教材,P215,,,10,,14.3,纹 理,Terrain,类提供了两种方法来为地形加上纹理,较简单的方法是载入并使用一个先前做好的纹理图。,,Terrain,类中实现了下面的方法,把图片文件中的纹理数
6、据载入到,IDirect3DTexture9,对象中,并使用,_,tex,指针指向它。,Terrain::draw,方法在渲染地形之前将会设置,_,tex,的值。,,这里给出该函数的具体实现,其过程非常简单:,,参见教材,P216,,11,,14.3.1,用程序生成纹理数据,,另一种给地形贴上纹理的方法是用程序计算纹理数据,也就是说先创建一个“空”的纹理,然后在代码中按照一些预定义的参数来计算每一个纹素的颜色值。,,通过用,Terrain::genTexture,方法创建纹理:首先调用,D3DXCreateTexture,创建一个空的纹理,然后锁定最高级别的数据区,遍历每个纹素并设置它的颜色值
7、。,,Terrain::genTexture,方法也同时会计算,mipmap,纹理。用,D3DXFilterTexture,函数可以完成这个任务,,genTexture,方法的实现代码如下:,,参见教材,P216,,12,,14.4,光 照,Terrain::genTexture,方法里会调用,Terrain::lightTerrain,方法,这个方法为地形增加了光照效果,从而使渲染的真实感更强。,,为什么要照亮所渲染的地形呢,而且为什么不让,Direct3D,来处理光照呢?我们自己来进行这种计算会有如下的三个好处:,,不用保存顶点法线的信息,节省内存。,,由于地形一般是静态的,光源的位
8、置也不会改变,因此预先计算好光照,就可以省下,Direct3D,实时为地形计算光照的时间。,,顺便做一些数学练习,熟悉基本的光照理论,练习使用,Direct3D,的函数。,,13,,14.4.1,概述,,这项用来计算地形阴影的光照技术是最基础的技术之一,被称为散射光照技术。设置一个平行光源,并指定它的方向与从光源发出的光线的方向相反。,,从图,14.7,可以看到这个角度越大,方格就越背离光源,得到的光照就越少。,,通过光照向量和表面法线向量之间的角度关系,可以构建一个阴影因子,它的取值范围为,[0, 1],,并决定表面获得的光照量。,,14,,14.4.2,计算方格的阴影,,首先需要在方格表面
9、中找到两个向量,它们非零而且互相不平行,这就是图,14.8,中的,u,和,v,:,,,,通过,Terrain::computeShade,方法来计算指定方格的阴影因子。它的,3,个参数分别是指定方格的行数、列数和光源的方向:,,参见教材,P220,,15,,14.4.3,计算地形阴影,,只需简单地遍历每一个方格,为每一个方格计算对应的纹理元素的阴影因子,并用纹素中的颜色值乘以这个因子,这样就能使光照少的方格变得暗一些。,,下面的代码片段展示了,Terrain::lightTerrain,方法的重要部分:,,参见教材,P221,,16,,14.5,在地形上“行走”,为了得到,Y,轴高度,首先根据
10、摄像机的,X,、,Z,坐标找出当前所在的方格。通过,Terrain::getHeight,函数可以实现这个功能,它以摄像机的,X,、,Z,坐标为参数,返回摄像机所在地面的高度值。具体的实现如下:,,float,Terrain::getHeight(float,x, float z),,{,,//,通过,XZ,平面上的平移,使地形的起始位置回到原点,,x = ((,float)_width,/ 2.0f) + x;,,z = ((,float)_depth,/ 2.0f) - z;,,//,通过把,X,,,Z,坐标除以,_,cellSpacing,,使每个方格的宽度变成“单位,1”,,x /=
11、(,float)_cellSpacing,;,,z /= (,float)_cellSpacing,;,,17,,14.5,在地形上“行走”,,首先,通过,xz,平面上的平移,使地形的起始位置回到原点。图,14.9,为转换前后的地形对比:地形起点回到原点,方格宽度变为,1,,,+Z,轴指向下方。,,行数就是,x,的整数部分,列数就是,z,的整数部分。函数,floor(T,),将返回不大于,t,的最大整数。,,,18,,14.5,在地形上“行走”,,下面的任务就是找到摄像机,X,、,Z,坐标所在方格的高度,(Y,轴的高度,),。这就需要一些技巧了,因为方格可能在两个方向上都是倾斜的,请参看图,1
12、4.10,。,,图,14.11,展示了转化后的方格。,,,19,,14.5,在地形上“行走”,,图,14.12(b),展示了这个插值点,那么向量,(q +,dxu,+,dzv,),的,y,分量就是,X,、,Z,坐标处的高度值,,,,,Terrian::getHeight,最后一部分代码如下:,,参见教材,P224,,这里面,Lerp,函数实现的是基本的一维线性插值运算:,,float d3d::Lerp(float a, float b, float t),,{,,return a - (a*t) + (b*t);,,},,20,,14.6 Terrain,示例程序,本章的示例程序通过给定的
13、包含高度数据的,RAW,文件创建了一个地形,并计算其纹理和光照。,,首先,加入了下面的全局变量来描述地形、摄像机以及帧速计数器:,,Terrain *,TheTerrain,= 0;,,Camera,TheCamera(Camera::LANDOBJECT,);,,FPSCounter,*FPS = 0;,,下面是主要框架的代码:,,参见教材,P225,,21,,14.7,一些改进措施,你可以通过把地形分成一个矩阵,这种矩阵被称为“,Blocks”,。每一个,Block,代表了地形的一个矩形区域。此外,每一个,Block,也包含了这一个,Block,所代表地形区域的几何信息,(,这些数据存储在
14、这个,Block,自己的顶点,/,索引缓冲中,),。每一块,Block,都负责渲染它自身,——,也就是整个,Terrain,的一个部分。,,还有一种方法就是用,ID3DXMesh,接口来装载地形几何信息,然后用,D3DX,库的函数,D3DXSplitMesh,把地形网格分成各个小的网格。,,D3DXSplitMesh,的原型如下:,,参见教材,P227,,22,,14.8,小 结,可以用具有不同高度、不同颜色的三角形网格来创建高山和低谷,以此模拟一个真实的地形。,,高度图是一个储存了地形各个顶点高度数据的数据集合。,,可以用硬盘上的图片来为地形加上纹理,也可以用程序生成地形纹理。,,通过计算每个方格的阴影因子来标识这个方格究竟会有多亮,/,多暗。阴影因素由光线向量与方格的法线向量之间的角度来计算。,,让摄像机在场景中移动时,需要寻找当前所处的三角形。然后,计算三角形上的两个向量,这两个向量尾部相接,且与三角形的两边重合。通过一个左上角在原点的单位化方位的,x,坐标与,z,坐标为参数,在这些向量上进行线性内插,从而求出高度值。,,23,,
- 温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。