地形绘制基础

地形绘制基础

高度图其实就是一个数组,该数组的每个元素都指定了地形方格中某一个特定顶点的高度值。(另外一种实现方式可能用该数组中的每个元素来指定每个三角形栅格的高度)。我们将高度图视为一个矩阵,这样高度图中的元素就与地形栅格中的顶点一一对应。

高度图被保存在磁盘中,我们通常为其每个元素只分配一个字节的存储空间,这样高度只能在区间 [0, 255] 内取值。高度图有多种可能的图形表示,其中一种是灰度图。地形中某一点的海拔越高,相应地该地点在灰度图中的亮度就越大。

 

1.       高度图

1)        创建高度图

但我们创建图像时,便指定了一副灰度图。一旦完成高度图的创建,我们需要将其保存为 8 位的 RAW 文件。 RAW 文件仅连续存储了图像中以字节为单位的每个像素的灰度值。这就使得这类文件的读取操作非常容易。

注意:高度信息不一定非要用 RAW 格式的文件来存储,可根据需要选择任意一种格式。 RAW 仅仅是我们所使用的图像格式中的一种。

 

2)        加载 RAW 文件

由于 RAW 文件本质上是一个连续的字节存储块,我们可用如下方法读取该字节块。

 

 

 

注意:我们将字节型向量复制到一个整型向量中。这样,我们就可以对高度值进行比例变换从而突破 0~255 的限制。

该方法唯一的限制就是所要读取的 RAW 文件中包含的字节数至少要与地形中的顶点综述一样多。所以如果要从一个 256 * 256 RAW 文件中读取数据,相应地,只能创建一个至少有 256 *256 个顶点的地形。

 

3)        访问和修改高度图

 

 

 

这些方法允许我们通过行和列索引引用高度图中指定的项,这些方法隐藏了如何访问由线性数组表示的矩阵。

2.       创建地形几何信息

 

 

 

1)        顶点的计算

为了计算三角形栅格的各个顶点,我们只需要自顶点 start 起,逐行生成每个顶点,保持相邻顶点的行列间隔为单元间距,直至到达顶点 end 为止。这样就给出了 x z 坐标的定义。

 

注意:本例程中开辟了一个很大的顶点缓存用来存储整个地形中的所有顶点,由于硬件的限制,这样就可能会有问题。例如, 3D 设备都预设了最大图元数和最大顶点索引值。可以通过检查 D3DCAPS9 结构的 MaxPrimitiveCount MaxVertexIndex 成员变量,来获知图形设备为上述值所指定的上限。

 

为了计算纹理坐标,下图给出了一个简单的纹理图像,从中我们可以看出与地形中位于( i, j )的顶点相对应的纹理坐标( u, v )可由下述公式计算得到:

 

 

 

 

2)        索引的计算

为计算三角形栅格各顶点的索引,我们只需自左上角起直至右下角,依次遍历每个方格,并计算构成每个方格的三角形面片的顶点索引。

 

 

 

 

计算的关键是推导出一个用于求出构成第 i 行、第 j 列的方格的两个面片的顶点索引的通用公式。借助上图,我们可自行推导出该公式,我们发现,对于处在( i, j )位置的方格,有:

 

3.       纹理映射

纹理映射有两种方式:

Ø          加载一个已创建好的纹理文件,然后再应用该纹理数据。

Ø          另外一种是按顺序逐个计算出纹理内容,即我们首先创建一个“空”纹理,然后再基于一些已定义的参数计算出纹理元的颜色。在地形绘制中,该参数为地形的高度该方法首先用 D3DXCreateTexture 创建一个空纹理,然后再将顶层纹理(因为有多层纹理)锁定。至此,开始遍历每个纹理元并对其上色。上色的依据是坐标方格所对应的近似高度。思路是:地形中海拔较低的部分上色为沙滩色,中等海拔的部分上色为绿色的丘陵颜色,高海拔的部分上色为雪山的颜色。我们用坐标方格中左上角顶点的高度值近似表示该方格的整体高度。

为每个纹理元上色后,我们还可以依据太阳光(用方向光模拟)到达纹理元对应的坐标方格时的入射角来调整每个纹理元的明暗度。

 

4.       光照

1)        概述

我们在计算地形的明暗时用到的光照技术很基本,也很常用,即漫射光。光的方向向量应为单位向量。

接下来为地形中的每个坐标方格就算光向量和该方格的面法向量之间的夹角。

由下图可见,上述夹角越大,坐标方格的朝向偏离光源就越大,其所接收到的光照就越少。反之,上述夹角越小,坐标方格的朝向偏离光源就越小,其所接收到的光照就越多。而且,一旦光向量与面法线的夹角超过 90 度,方格表面便接收不到任何光照。

 

 

 

借助光向量和方格的面法向量之间的角度关系,我们可以构造一个位于区间 [0, 1] 内的明暗因子,以表示方格表面所接收到的光照量。这样,我们就可以用一个接近于 0 的因子值来表示这两个向量的夹角很大。当一种颜色与该因子相乘时,颜色值就趋近于 0 ,从而呈现出较暗的视觉效果。反之,接近于 1 的因子值表示这两个向量夹角很小,所以当一种颜色与该因子相乘时,该颜色基本保持了原来的亮度。

2)        坐标方格的明暗度计算

为了计算光源方向的单位向量与方格的法向量之间的夹角,我们首先需要求出方格的法向量。通过计算向量的叉积就可以求出。但我们需要先找出与该方格共面的两个非零的互不平行的向量。

 

 

3)        对地形进行着色

一旦我们了解了如何对一个特定的坐标方格进行着色(也称明暗处理),我们就可以对地形中的所有方格着色了。我们只需要遍历每个坐标方格,计算其明暗因子,然后将该方格对应的纹理元的颜色于该因子相乘。

5.       在地形中“行走”

地形创建好之后,我们还想移动摄像机以模拟我们在场景中的行走过程。为了实现这一点,我们首先需要根据给定的 x z 坐标找到我们所处的坐标方格。

首先,我们进行平移变换,将顶点 start 平移至坐标原点。然后通过缩放因子为单元间隔的负倒数的比例变换将坐标方格的单元间隔归一化。这样,我们就转换到了一个新的参考系中,其中 z 轴方向向“下”。当然,程序代码并没有改变坐标系框架本身,我们只是将 z 轴正方向理解为向下。下图以图形化的方式展示了该变换过程:

 

 

 

可以看出,经过变换的坐标系与矩阵的顺序保存了一致。即左上角为原点,列索引和行索引分别沿着向右方向和向下方向递增。这样,由于目前单元间距为 1 ,我们便可迅速求出当前我们所处的坐标方格的行列索引。

既然我们已经知道了当前所处的坐标方格,就可以求出构成该方格的 4 个顶点的高度。

此时,我们当前所处的方格位置以及构成该方格的 4 个顶点的高度均已知。现在我们来求摄像机位于任意的位置( x, z )时,坐标方格单元的高度。为了求取该高度,我们首先需要判断摄像机当前位于哪个坐标方格内。注意,记坐标方格都是由两个三角面片的组合来绘制的。为了求出摄像机当前所处的三角形面片,我们需要对当前所处的坐标方格进行变换,使其左上角的顶点与坐标原点重合。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值