1.地貌制作概述
本节先以一些策略游戏里的地貌为例,解释它们的地图地貌,之后提出一个简单的地貌模型,以下是该地貌模型应用到地形上的预览

1.1.一些游戏中的地貌
游戏《欧陆风云4》的地图相关资源暴露比较充分,在 Europa Universalis IV / map 文件夹下存放了大量与游戏地图构建相关的纹理资产、地貌图集、区域划分等文件。
在map\terrain文件中列出了所有的地形种类,所有地形都有对应的色彩表。常用的地形颜色有:平原(86 124 27),丘陵(0 86 6),海岸线(255 247 0),山脉(65 42 17),沼泽/湿地(75 147 174),草原(200 214 107),沙漠(200 214 107)。
这里采用的方式是地形以纯色对应,输出一张简单地貌图,即下图。在这张简单地貌图中已有大致的地貌样式,地图效果也勉强可以。但仅仅是简单的纯色图还是太单调了,可以使用更多的操作来提升地图效果。通常来讲有很多的做法,如叠加噪声让地表看起来起伏不平,叠加纹理贴图等。

下图是游戏地图里的秋季地貌,混合了地形纹理之后进行导出。可以从图中看出terrain.bmp即纯色地图的概貌,在纯色地图的基础上叠加地形纹理,再做colorgrading之类的操作即可得到下图。当然,按下图的精细度,仅有上面的步骤还是不行的,如果只考虑程序化生成,还需要叠加高度图、法线图等:

下图是游戏地貌的图集资产,这些纹理会叠加到地形图上。地形底色如上方所说是纯色对应。使用纯色作为有很多好处,如做季节、天气变化效果时,可以根据一张额外的混合贴图修改地图底色,省去很多操作。

当然,上面只是对EU4游戏的简单分析,要做出完整的EU4地图效果,仅有上面的是远不够的。如果你对欧陆风云4的自定义地图感兴趣,可以看看以下的wiki:
https://www.eu4cn.com/wiki/%E5%9C%B0%E5%9B%BE%E4%BF%AE%E6%94%B9
1.2.游戏地貌简单建模
如果只让美术/地编人员制作地图,那么地图效果毫无疑问会十分棒,但为了地图制作流程化与规范化考虑,PCG是必不可少的(毕竟你也不想看到美术累死吧)。程序化生成地图的方案在许多游戏里必不可少,而每类游戏又会有不同的地图需求,程序化生成方案需要具体定制。
继续以Paradox公司为例,P社有两种游戏引擎,Europa和Clausewitz(克劳塞维兹)。2000年的P社的第一款游戏欧陆风云1使用Europa引擎,2007年P社又推出了Clausewitz引擎,使用C++开发,目前支持DX11,该引擎以只用cpu0著称(祖宗之法不可变!)。P社引擎以构建3D视图的游戏大地图著称,适配其一直在开发的策略游戏。
扯的有些远了,但总的来讲,做地貌时应依据需求决定组件的轻重,以下提供一个简单的地貌建模方法。我们可以考虑基于真实地理知识,为游戏中的地貌建模。通常来讲,地貌受三个因素影响:海拔,湿度,温度。而海拔主要通过温度来影响地貌,所以也可以说只有温度、湿度两个要素
我们可以按照以下理念确定地形:
-温度越低的地方越偏冷色调,越高的地方偏暖色调;
-湿度越高的地方绿色越重,否则就越干旱,黄色更重;
-每种地形均是纯色,可以使用插值来丰富下表现;
基于此,我们简单地根据温度、湿度做个地形颜色对应图,如图所示:

一个地点的高度可以由高度图得出,湿度图、温度图可以由真实地理数据得出,或者手刷(通过绘图工具即可),使用时获取到数值即可,然后映射到地形纯色

上面的地貌模型参考了hex的地貌构建思想,链接为(这位大佬的其他博客也很不错):
http://www-cs-students.stanford.edu/~amitp/game-programming/polygon-map-generation/
1.3.简单地貌模型应用
以下实践上述提出的模型:
建立湿度、温度-模型的映射关系(下方的颜色数组很混乱,读者可自行更改地形颜色):
1 | public class LandformDataModel { |
导出地貌图:
1 | public bool ExportFlipVertically = true; |
执行上述的导出逻辑后,可以获得如下的地貌图:

如果需要自定义地形颜色,更改颜色后,又可以得到不一样的地貌图

将该地貌贴图应用于地形上(因为只是应用一张贴图,shader逻辑并不复杂,此处不放),效果图如下:


2.混合纹理方案概述
本节不涉及项目内代码,简要讨论下混合纹理大地图的方案,它是经典的大世界地图解决方案,适合处理纹理量大时的地形。
通常来讲,当我们需要混合多个地形纹理时,有如下的方案
-直接使用一张BlendTexture存储权重,例如BlendTexture四个通道RGBA各自存储对应的纹理图的权重值。是比较直观又简单的方法,支持四张纹理混合
-使用纹理的A通道存储权重,即为每张贴图多添加一个A通道存权重(透明度),叠加得到最终颜色
上述的方案在地形纹理规模扩大的时候弊病会显得很严重,如果有n张纹理,就需要有n/4张索引贴图,采样n+n/4,如果算上法线则更加严重。所以目前的游戏制作主流方案会采用一张IndexTexture+纹理图集来减少采样次数,采样时先获取索引再去找到图集对应纹理(2次)。

如果要实践该方案,那么这个方案需要:
-4*4的纹理图集:对应16种地形
-indexTexture:RGBA四通道分别存储一种纹理的索引,对应blenderTexture
-blenderTexture:RGBA四通道存储纹理的混合权重值
计算过程:Color = TexArray[indexTex.R]*blendTex.R + TexArray[indexTex.G]*blendTexG + TexArray[indexTex.B]*blendTex.B + TexArray[indexTex.A]*blendTex.A
目前没有代码,之后再来尝试该方案