日历

最新评论及回复

最近发表

Search

我在这里: 首页 » Alchemy3D » 浏览文章: 地形实现
« Introduction of Alchemy3D(一)深度缓冲和Alpha混合 »

地形实现

想想顺便连地形一起放上来吧。由于时间比较赶,目前Alchemy3D的地形引擎是基于三角形网格的。

 
HeightMap简介
现实中的地形是真实的,不是由三角平面模拟的,但是3D图形图像处理中常常使用三角形来代替地形的表面,每个三角形的顶点高度在山脉到山谷之间转换,模拟自然地形,如图所示。在这个过程中,还将应用纹理展示沙滩、丘陵和雪山。
HeightMap技术的灵感来源于等高地图的绘制,如图所示,是一幅等高地图,它通常用来描绘高低起伏比较大的地形。
例如,飞行员必须了解哪里有高海拔的障碍物、山川、湍流的方向等,以便安全地飞行。从空中往下看,陆地上可能很平坦,但事实上等高线是展开的,没有相当的理解力和想象力,许多人并不能很好地领会地图实际提供的信息。
高度从平面图上无法立体地显现,所以用有规律的间隔来表示海拔,通常根据测量方法的不同一般间隔为50英尺或10m,同等位置的点被连成线,即等高线。
许多情况下这些等高线聚在图上形成封闭的环线,有些部分为不规则的心形,不时会凸出来一点。如果它们突然中断与其他线相冲突,则表示有高度的突然变化,事实上为悬崖或很深的落瀑。
自然界中能看到的惟一等高线只有沿着海岸的水平线(由于海潮的变化,事实上那也不是完全意义上的等高线),但可以把等高线想象成如同水平桌面的边线,如果把衣物或其他东西堆在桌面上,就如同小山峰或其他形状。
在这些等高线之间具体地形如何,都没有表示出来。等高线之间也不一定就是斜坡,可能是洞穴、凸起的岩石,以及其他各种高度变化在10m之内的地势。从等高线的相应位置,可以简单地猜测出地表大概会是如何变化的。
等高线地图可以形象地反映山体的情况,如图所示是实际山体与等高线地图的对应表示。等高线地图在军事、旅游、探矿中有着广泛的应用。
等高线之间的间隔只是表明同一理论高度下地平线上点之间的距离,并非是地面山坡上点间的实际距离,它们只是用来表明相应的位置,并非根据地平面的比例。
常见的一种错误想法是,一群等高线是按地图绘制比例缩小的地面高度——要知道典型的旅行地图比例是1∶50000,10m在图上只有0.02mm。图上间距5mm的等高线在地表面的距离为250m,而不是实际代表的10m落差,差距是1∶25。
理解等高线,就可以说掌握了一半的HeightMap技术。在3D地形渲染中,采用数组的形式来保存高度信息(数组内容可以通过高度图读取,图片上的一个像素或者一个区域代表同一高度),根据高度信息在不同的位置绘制多边形,从而通过2D图像展示出3D地形场景。
高度图可以使用画图板或者图像编辑器Adobe Photoshop产生。使用图像编辑器可能更容易,它能够帮助创建想要的交互地形,另外也可以通过图形编辑特性,例如过滤,创建有趣的高度图。
海岛地图的原理
从上面对等高图的阐述,可以知道,地形是真实世界的一个模型,有平原、山脉、河流、悬崖和丘陵等。以抽象角度来看,可以简单地认为地形仅仅是高度上的变化。
例如,一个草原就是一个高度基本为常数的地形(除了可能有一些起伏和山丘外);一个山区或者鸿沟是高低落差比较大的地形;一条河流就是由一个高地势平原和穿过它的曲线组成,这个曲线比它周围的地形高度稍低。
如图所示,是一系列的高度地图,简单来看,它是一个像素的集合,每个像素都是在灰度上0~255之间变化,0是黑色,255是全白,读者也可以自己绘制高度地图。可以判断,明暗反差越大,地势高低起伏也越大。

说明
在灰度图像中,像素灰度级用8b表示,所以每个像素都是介于黑色和白色之间的256(28=256)种灰度中的一种。灰度图像只有灰度颜色而没有彩色。通常所说的黑白照片,其实包含了黑白之间的所有灰度色调。从技术上来说,就是具有从黑到白的256种灰度色域(Gamut)的单色图像。

在Alchemy3D中,如果不使用高程图,将自动使用PerLin噪音进行高程图进行计算生成。
地图元素图元
要将高度地图转换为场景,只需要读取图片的像素,然后根据像素的值设置平面的高度,最常用的平面是四边形。因为四边形是规则的,可以采用数组方便地统一创建和管理(并且能实现地图的无缝)。四边形由两个三角形组成,多个四边形组成了场景地图。
这里说明一下Alchemy3D地形引擎并不是采用元素图元,而是单个三角形组成网格的形式,做到更精确化的地形坡度。

我们知道 ,每个三角形决定一个面,而每个面的多项式是:

ax+by+cz+d=0

其中a,b,c是平面的法向量x,y,z,d为平面的法向量与三角形第一个向量的点积的负数形式.

我们的目的就是求出a,b,c,d,然后把当前x,z代入多项式即可求出高度y.

而要求a,b,c,d关键需要知道平面的法向量,但是三角形我们已经知道,由此我们就很轻易得得到了y值.

这里还有一个问题,如图所示:

 

高度我们有了,但是方向却不知道,怎么办呢?

其实很简单,只要一步

entity.lookAt( entity.position, normal )

  • 相关文章
  • quote 3.sfsdfsd
  • 怎么使用都不知道,对外行人来说还是不明白怎么使用这个工具.
  • 2010-7-9 17:13:26 回复该留言

发表评论

为了防止SPAM,含链接的评论需要审核后才能显示。

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。