《魔兽世界》地形研究
发表于2015-12-28
《魔兽世界》地形的惊艳之处,主要在于无缝连接的世界和精细的渲染效果,借助WoWmapview源码及能以线框模式查看D3D程序的分析工具,可以对其实现略窥一二。
一、组织方式
《魔兽世界》采用分块的地形,这是它实现无缝地图的基础。
从WoWmapview源码来看,整块地形对应一个MapWorld,这块地形可以是整块卡利姆多大陆,整块东部王国,如果你在战场中,它还可以仅是这块战场地图。每个MapWorld分为64x64个MapTile。每块MapTile又进一步分为16x16个MapChunk。
在任何时刻,程序总是保存着玩家所在的及其周围的3x3个MapTile,随着玩家的移动,这些MapTile会被动态更新,新的MapTile被加载以替换被卸载的旧MapTile。为了提高调度效率,魔兽引入了Cache机制,Cache中保存着最多16个MapTile数据。需要加载新的MapTile时,首先会在Cache中查找;卸载的旧MapTile也不会被立刻删除,而是保存在Cache中以备再次调用。由于一段时间内玩家的活动范围通常不会有太大变化,这一Cache策略在应用中表现的非常出色。这是无缝地图的基本原理。
作为魔兽地形的基本渲染单元,每个MapChunk包含9x9+8x8个地形顶点,顶点布局如下图示。
为了提高渲染效率,魔兽采用二级静态LOD。即渲染时刻,根据每个MapChunk和相机的距离,使用两种精度的顶点索引。这是魔兽线框模式下位于虚空风暴地图边缘时的截图。
参考截图,第一级顶点索引方式可能是这样的。
很难根据线框模式下的魔兽世界判断出其第二级顶点索引方式。游戏中,采用低视野设置,远处的MapChunk会被视锥剪裁掉;采用高视野设置,远处的MapChunk仍会采取一级顶点索引进行绘制。实际上,我从没在实际游戏中见过采用二级顶点索引绘制的地形块。你可以参考WoWmapview,或者采用自己的二级顶点索引方式。一般情况下,二级顶点索引的索引个数会比一级索引减少一半。
魔兽世界的地形是支持挖洞的。深入地底的矿洞,矮人村落中带有地下室的堡垒,都要用到这个功能。每个MapChunk支持挖4x4个洞,挖洞信息用一个int类型保存在MapChunk中,低16位对应4x4个洞每一个是否打开,高16位对应洞的类型。下面是丹莫罗深入地面的矮人地堡截图,可以较清晰地看到与地堡相接部位地形上所挖的洞。
水体信息也是保存在MapChunk中的。对应MapChunk的顶点,每块水体的顶点分布及其索引如下图。
每个MapChunk保存了覆盖其上的水体信息的一系列flag值,这些flag值包含了水体各个单元是否开启,水体颜色,水体类型等。下图是途径暮色小溪时的截图,紫色的水体展示了水体顶点分布及索引方式。
二、渲染技巧
魔兽采用多层地形纹理混合的方式来渲染地形,这也是各游戏普遍采用的方式。一般情况下,魔兽使用4张地形贴图和一张混合贴图,混合贴图的R、G、B通道表示前3次混合的权重,A通道表示是否为阴影。地形贴图一般在MapChunk单方向上重复张贴8次;而通常尺寸为64x64的混合贴图,仅重复一次,即每一个MapChunk对应一张混合贴图。这张64x64的贴图,在混合地形时,为地形的混合精细度提供了足够的保障。
尚不清楚出于何种考虑,魔兽中保存了反映当前WorldMap粗略高度的一个64x64的顶点列表,对应64x64个MapTile。渲染之初,使用当前雾的颜色作为输出色,首先渲染这个列表。这样做可能的一个原因,是当游戏视野设置很低时,稍远处的地形会被剪裁掉,而这个顶点列表在雾的配合下,提供远处的地形填充,不至于出现地形截断的效果。
接着,针对活动的3x3个MapTile逐一进行绘制。在每个MapTile中,使用四叉树管理其下的MapChunk,每个MapChunk根据相机和自身的实际距离,选择采用如下渲染策略:
1、距离很远。采用二级顶点索引,使用NoDetail渲染策略。仅设置雾颜色为顶点色,不考虑纹理采样和光照处理。
2、距离适中。采用二级顶点索引,使用Detailed渲染策略。光照,纹理混合,阴影等均会处理。
3、距离较近。采用一级顶点索引,使用与情况2相同的Detailed渲染策略。
最后是水体的渲染。魔兽WLK之前的水体,基本上是采用30张水面轮替形成水波荡漾状来实现的。而在资料片《大灾变》中,加入了实时渲染的水体效果。
上述魔兽世界地形渲染的基本技巧,尚不能得到实际游戏中那种令人印象深刻的地形效果。影响地形渲染效果的诸多因素当中,光照其实占了很大部分比重,处理好光照模型,渲染出来的地形会有意想不到的效果。正如厨师的秘制配方一样,魔兽地形画龙点睛之处在于高光贴图。
由于环境光和直射光只能为地形顶点提供无差别的基本明暗效果,反射光作为能根据顶点位置不同而不同的差异性光照,被引入到魔兽地形的光照模型中。而单纯引入反射光又会使得地形看起来像涂了一层釉一样,所以魔兽将地形纹理的Alpha通道,作为其对应的高光贴图,控制该点反射光的强度。值得一提的是,魔兽的水体渲染的光照处理,也采用了与此极为类似的方式。这样的简单技巧已经足够将魔兽的地形渲染提升到像素级光照的精度,实际上,它在魔兽细腻天成的地形效果中,扮演者关键性的作用。
三、Demo
得空实现了一个初步Demo,作为上述研究的验证及总结。它支持无缝地图,并且使用了文中提到的所有渲染技巧。
这是展示地形混合、挖洞、二级静态LOD的截图。美工略显拙劣,每个MapChunk都采用了同样的混合纹理和高度图,所以会看到相同外貌的地形块多次重复。
这是展示地形光照效果的截图,高光贴图的使用大大提高了地形的精细度,经常出入奥山战场的玩家,应该对这种岩石的冷峻反光效果深有感触。
这是展示水体效果的截图,遍布艾泽拉斯世界的大小水体,基本上都带有这种波光粼粼的魔兽烙印。
Demo源码暂不公布,将会在进一步改善后作为成熟方案运用到实际项目中。Demo中用到的技巧,在本文中皆有论述,原理也比较简单,大家可自行尝试。
这是我所烘焙出的最好的地形;)