清华大学DirectX游戏编程第14章(全20章)_第1页
清华大学DirectX游戏编程第14章(全20章)_第2页
清华大学DirectX游戏编程第14章(全20章)_第3页
清华大学DirectX游戏编程第14章(全20章)_第4页
清华大学DirectX游戏编程第14章(全20章)_第5页
已阅读5页,还剩18页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、2,第14章 基本地形渲染,本章将讲述如何实现一个简单的地形类。 主要目标: 学习如何生成渲染地形需要的高度信息,高度信息将用于在程序中模拟山峰、峡谷等自然地形。 理解怎样生成代表地形的顶点和三角形数据。 学习地形纹理设置和为地形打光的方法。 学习如何在地形渲染中控制摄像机位置,模拟人在场景中行走和奔跑的效果。,3,14.1 高 度 图,高度图用来描述地形的高度信息。高度图实际上是一个数组,数组中的每个元素都存储着地形网格中对应顶点的高度数据 将高度图数据读入内存时,通常为图中的每个元素分配一个字节的内存,这样高度的范围就是0255。 图14.2展示了用作高度图的灰度图。,4,14.1.1 高

2、度图的创建,高度图可以通过程序生成,或者通过Adobe Photoshop这样的图像处理软件来制作。 图14.3展示了用Adobe Photoshop创建的金字塔地形。,5,14.1.2 读取RAW文件,由于RAW文件中的数据仅仅是连续的字节块的集合,可以用下面的方法方便地得到其中的数据。这里变量_heightmap是Terrain类的成员,其声明如下: 参见教材P209 注意这里把存储BYTE数据的vector里的数据拷贝到存储int数据的vector里,这样就可以扩大高度数据,使其超出0255的限制。,6,14.1.3 高度图的访问和修改,Terrain类提供下面两个方法来访问和修改高度图

3、中的元素: int Terrain:getHeightmapEntry(int row, int col) return _heightmaprow * _numVertsPerRow + col; void Terrain:setHeightmapEntry(int row, int col, int value) _heightmaprow * _numVertsPerRow + col = value; ,7,14.2 生成地形几何数据,图14.4展示了地形的一些属性、术语和需要使用到的特殊顶点。 Terrain类的定义如下: 参见教材P211 通过构造函数传入的值,可以计算出地形需要的

4、其他变量: 参见教材P212 顶点结构声明如下: 参见教材P212,8,14.2.1 计算顶点,下面需要计算的是纹理坐标,参照图14.5,通过它可以看出(u, v)纹理坐标和地形的顶点(i, j)的对应关系: 生成顶点的代码如下: 参见教材P213,9,14.2.2 计算索引定义三角形,为计算三角网格中的顶点索引,只需从左上角到右下角遍历每个方格,然后计算组成这个方格的两个三角形的顶点索引值,参照图14.6。,10,14.2.2 计算索引定义三角形,通过图14.6发现在第i行第j列的方格具有以下性质: 参见教材P215 生成索引值的代码: 参见教材P215,11,14.3 纹 理,Terrai

5、n类提供了两种方法来为地形加上纹理,较简单的方法是载入并使用一个先前做好的纹理图。 Terrain类中实现了下面的方法,把图片文件中的纹理数据载入到IDirect3DTexture9对象中,并使用_tex指针指向它。Terrain:draw方法在渲染地形之前将会设置_tex的值。 这里给出该函数的具体实现,其过程非常简单: 参见教材P216,12,14.3.1 用程序生成纹理数据,另一种给地形贴上纹理的方法是用程序计算纹理数据,也就是说先创建一个“空”的纹理,然后在代码中按照一些预定义的参数来计算每一个纹素的颜色值。 通过用Terrain:genTexture方法创建纹理:首先调用D3DXCr

6、eateTexture创建一个空的纹理,然后锁定最高级别的数据区,遍历每个纹素并设置它的颜色值。 Terrain:genTexture方法也同时会计算mipmap纹理。用D3DXFilterTexture函数可以完成这个任务,genTexture方法的实现代码如下: 参见教材P216,13,14.4 光 照,Terrain:genTexture方法里会调用Terrain:lightTerrain方法,这个方法为地形增加了光照效果,从而使渲染的真实感更强。 为什么要照亮所渲染的地形呢,而且为什么不让Direct3D来处理光照呢?我们自己来进行这种计算会有如下的三个好处: 不用保存顶点法线的信息,

7、节省内存。 由于地形一般是静态的,光源的位置也不会改变,因此预先计算好光照,就可以省下Direct3D实时为地形计算光照的时间。 顺便做一些数学练习,熟悉基本的光照理论,练习使用Direct3D的函数。,14,14.4.1 概述,这项用来计算地形阴影的光照技术是最基础的技术之一,被称为散射光照技术。设置一个平行光源,并指定它的方向与从光源发出的光线的方向相反。 从图14.7可以看到这个角度越大,方格就越背离光源,得到的光照就越少。 通过光照向量和表面法线向量之间的角度关系,可以构建一个阴影因子,它的取值范围为0, 1,并决定表面获得的光照量。,15,14.4.2 计算方格的阴影,首先需要在方格

8、表面中找到两个向量,它们非零而且互相不平行,这就是图14.8中的u和v: 通过Terrain:computeShade方法来计算指定方格的阴影因子。它的3个参数分别是指定方格的行数、列数和光源的方向: 参见教材P220,16,14.4.3 计算地形阴影,只需简单地遍历每一个方格,为每一个方格计算对应的纹理元素的阴影因子,并用纹素中的颜色值乘以这个因子,这样就能使光照少的方格变得暗一些。 下面的代码片段展示了Terrain:lightTerrain方法的重要部分: 参见教材P221,17,14.5 在地形上“行走”,为了得到Y轴高度,首先根据摄像机的X、Z坐标找出当前所在的方格。通过Terrai

9、n: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 /= (float)_cellSpacing; z /= (float)_cellSpacing;,18,14.5 在地形上“行走”,

10、首先,通过xz平面上的平移,使地形的起始位置回到原点。图14.9为转换前后的地形对比:地形起点回到原点,方格宽度变为1,+Z轴指向下方。 行数就是x的整数部分,列数就是z的整数部分。函数floor(T)将返回不大于t的最大整数。,19,14.5 在地形上“行走”,下面的任务就是找到摄像机X、Z坐标所在方格的高度(Y轴的高度)。这就需要一些技巧了,因为方格可能在两个方向上都是倾斜的,请参看图14.10。 图14.11展示了转化后的方格。,20,14.5 在地形上“行走”,图14.12(b)展示了这个插值点,那么向量(q + dxu + dzv)的y分量就是X、Z坐标处的高度值 Terrian:g

11、etHeight最后一部分代码如下: 参见教材P224 这里面Lerp函数实现的是基本的一维线性插值运算: float d3d:Lerp(float a, float b, float t) return a - (a*t) + (b*t); ,21,14.6 Terrain示例程序,本章的示例程序通过给定的包含高度数据的RAW文件创建了一个地形,并计算其纹理和光照。 首先,加入了下面的全局变量来描述地形、摄像机以及帧速计数器: Terrain *TheTerrain = 0; Camera TheCamera(Camera:LANDOBJECT); FPSCounter *FPS = 0;

12、下面是主要框架的代码: 参见教材P225,22,14.7 一些改进措施,你可以通过把地形分成一个矩阵,这种矩阵被称为“Blocks”。每一个Block代表了地形的一个矩形区域。此外,每一个Block也包含了这一个Block所代表地形区域的几何信息(这些数据存储在这个Block自己的顶点/索引缓冲中)。每一块Block都负责渲染它自身也就是整个Terrain的一个部分。 还有一种方法就是用ID3DXMesh接口来装载地形几何信息,然后用D3DX库的函数D3DXSplitMesh把地形网格分成各个小的网格。 D3DXSplitMesh的原型如下: 参见教材P227,23,14.8 小 结,可以用具有不同高度、不同颜色的三角形网格来创建高山和低谷,以此模拟一个真实的地形。 高度图是一个储存了地形各个顶点高度数据的数据集合。 可以用硬盘上的

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论