[程式] Import RealWorld Landscape to UE4

楼主: yekdniw (yekdniw)   2020-07-01 12:20:42
网页版
https://yekdniwue.blogspot.com/2020/06/import-realworld-landscape-toue4.html
简介
从真实世界地形资料汇入游戏引擎是蛮常见的需求,
这次刚好有机会在UE4试试看这个功能,
没想到遇到地形交界处接不起来的问题,
最后找到问题点,所以顺便分享作法。
https://www.youtube.com/watch?v=_9ob8FcnYY4
本篇文章使用的流程。
不过过程中有遇到问题,所以写了这篇文章想要补充不足之处。
以下是简化版的流程:
下载地形资料并转换为引擎可汇入的heightmap png档。
1. 到https://viewer.nationalmap.gov/basic/下载地形资料
2. 到https://github.com/MacroPolo/real-terrain下载python script
3. 解压缩地形资料档,放到real-terrain的input资料夹内
4. 如果电脑没安装python,安装python
5. 在命令列输入python real-terrain.py [档案名称].img (注1.)
6. real-terrain的output资料夹内就会有输出好的png档。
在UE4汇入地形档:
1. 创一个新地图,WorldSettings设定Enable World Composition为true
2. Levels->Create New,产生新的子地图
3. Models->Landscape->Manage->New Landscape->ImportFromFile
4. Heightmap File选择前一个步骤6输出好的png档
5. 地形汇入完成。
6. 在World Composition视窗调整地图到想要的位置。
以上是基本流程,不包含太多的细节,一些接口是从哪边叫出来的就请参考影片。
在我的实验中,用上面的流程汇入一块地形档是不会有任何问题的。
但是当我汇入两块地形档放进UE4后,发现两块地形接不上,有严重的高低差问题。
修正地形接缝问题
经过一番追查,最后我找到几个项目要特别处理,才能把地形接起来。
1. 最大高度要一致。
2. height map分辨率要符合引擎的规范。
最大高度要一致
以我的范例来说,我有两张地图档49_361跟49_362。
在使用real-terrain转换的过程,会显示这个地形档的最小高度与最大高度
举例来说
这是49_361的结果
>>> Extracting elevation information from input DEM.
Minimum elevation: 0m
Maximum elevation: 180m
Elevation range: 180m
这是49_362的结果
>>> Extracting elevation information from input DEM.
Minimum elevation: 0m
Maximum elevation: 154m
Elevation range: 154m
real-terrain会将地形最小高度与最大高度normalize为uint16,值域是0到65535,
所以两张地形分开处理的话,
49_361转出来的最大值是180m高,49_362转出来的最大值只有154m,但是值都是65535。
为了解决这个问题,代表在汇入地形的时候,
需要找到所有汇入的地形档的最大高度与最低高度。
然后用整体最大/最低高度作为基准餐数,提供所有地形档转换。
以上面的范例,最低高度就是0m,最大高度就是180m。
强制所有地形档以预先算好的最高/最低值做转换
这部份要修改一下python程式码
使用任何文字编辑器开启real-terrain.py
找到_find_elevation_range(self):内

self.min_elevation = blabla
self.max_elevation = blabla
改为
self.min_elevation = '0'
self.max_elevation = '180'
然后重新用real-terrain.py转换地形档就可以得到相同值域的height map。
Height map分辨率要符合引擎的规范
做了上面的步骤,我以为地形要能接上了,结果如下图1与图2,
依然没有接上,观察了一阵子觉得应该不是高低差问题,而是整个接缝处本来就不连续。
但是原始height map的png档又是接得起来的(用绘图软件将拼起来看)。
所以初步把问题排除是real-terrain产生的图有问题,将问题范围限缩到UE4。
图1. Gap between landscapes without normalize height. (Top view)
图2. Gap between landscapes without normalize height. (Side view)
后来在搜寻的过程中找到这个页面
https://docs.unrealengine.com/en-US/Engine/Landscape/TechnicalGuide/index.html#recommendedlandscapesizes
里面有描述到UE4对height map的图片是有规范的。
而我从real-terrain输出的原图大小是10012*10012,
明显比UE4最大的8129*8129还要大。
所幸real-terrain也支援图片的缩放,
所以只要将执行指令改为
python real-terrain.py -s 8129 [档案名称].img
就可以了。
在输出的output资料夹就会多一个_scaled.png档。
使用这个png档在UE4汇入后,接缝处终于正常了。如图3.与图4.
图3. Almost no gap after adjust. (Top view)
图4. Almost no gap after adjust. (Side view)
使用real-terrain输出多个tile map
我本来的问题其实在前面就结束了,不过有觉得地形有点太大张想要细切。
又看到UE4好像有另一个可以import tiled map的接口,
于是继续试试看能不能把两个大地形档再细切。
这部份其实还是着重在延伸real-terrain的程式。
利用real-terrain输出tile map
首先先学习如何利用real-terrain输出tile maps。
一样要注意UE4的height map图片规范,这里就以每个tile是2017*2017为范例。
python real-terrain.py -t 2017 [档案名称].img
基本上这个指令就会把地形档以2017*2017为单位进行分割。
但是可惜的是,原图10012以2017是没办法整除的。最后会留下1944*2017的非正方形图。
所以我们要先把原图缩放到2017的倍数,再进行分割。
先缩放再分割
这部份也需要修改python程式码,因为real-terrain在分割的时候只吃原始图档。
现在我们需要先缩放,再对缩放的结果分割。
找到函式_generate_tile(self)的段落,里面的
img = Image.open(self.output_full)
改成
img = Image.open(self.output_scale)
然后在命令列输入
python real-terrain.py -s 8068 -t 2017 [档案名称].img
就能产生出各个tiled maps。
到UE4的Levels->Import Tiled Landscape选择刚才所有输出的tiled png档。
如图所示
图5. Import tiled Landscape from Levels.
会发现UE4除了图片规范之外,批次汇入tile maps还有命名规则。
如图所示,命名规则是[档案名称]_X[数字]_Y[数字]
图6. Name rule when import tiled landscape.
符合Import TileMap命名规范
所以回到real-terrain.py,
找到函式_generate_tile(self)的段落,把里面的
img_slice.save(self.output_tile + "_heightmap_tile_{}-{}.png".format(x, y))
改成
img_slice.save(self.output_tile + "_heightmap_tile_X{}_Y{}.png".format(x, y))
输出来的图片应该就是正确的了。
以上就是整个从真实地形档汇入UE4所遇到的各个问题与解决过程。
简单列一下重点就是:
1. png档大小要符合UE4规范
2. 所有地形档在汇出png的时候要用统一的最大高度/最小高度。
3. 为了达到这个目的,修改real-terrain是必要的。
4. 简单的方法就是算好最大/最小高度后硬写在程式码内,
5. 如果需要更正式的制程的话可能就要修改更多程式码。
6. 或是使用付费的工具World Machine、World Creator来作。
7. 如果要输出tiled maps,要修改tile的输入是scaled的image,
也要修改输出的命名规则。
注1.
如果跳以下错误讯息
ModuleNotFoundError: No module named 'PIL'
可以输入pip install Pillow 安装
如果还是跳错
输入Python pip install Pillow
参考资料
https://www.youtube.com/watch?v=_9ob8FcnYY4
本篇文章使用的流程。
不过过程中有遇到问题,所以写了这篇文章想要补充不足之处。
https://viewer.nationalmap.gov/basic/
USGS的下载处,提供多种精细度的资料下载。
https://github.com/MacroPolo/real-terrain
将USGS的地形资料转换成16 bit PNG heightmap的python程式
支援IMG, ArcGrid以及GeoTIFF档
也支援图档的scale,或是将整个大地图细切为多个tile。
python程式本身也写得简单易懂。
用这支程式可以取代GlobalMapper的部分功能。
https://terraformpro.com/tutorials/
有非常详细而且完整的产生真实世界地形的图文说明
里面的范例还包含地形材质的汇入,铁道,道路、河流等等的汇入
唯一的可惜之处就是使用了几个付费软件
包含GlobalMapper (处理地形资料)与
UE4的plugin Procedural Landscape Ecosystem
铁道、道路、河流等Vector的汇入仰赖GlobalMapper之外,
也要用该Blog自己写的plugin汇入进UE4
但是这个Plugin好像只维护到4.19
https://docs.unrealengine.com/en-US/Engine/Landscape/TechnicalGuide/index.html
Unreal对landscape的基本说明。
里面最重要的就是Recommended Landscape Sizes了,
不管是要用Import TiledLandscape,还是直接Import landscape。
height map都要照这里面的规范制作。否则会错误或是直接无法汇入。
https://www.youtube.com/watch?v=K41WMgJUFEk
使用OpenTopography(地形资料)加上L3DT(heightmap处理),
汇入真实地形到UE4的影片教学。
本篇文章没有使用到这个流程,不过要拿US以外的地形资料可能要参考这个流程。
作者: sampp1213205 (佛朗Sam哥)   2020-07-01 13:42:00
推一个
作者: Lhmstu (lhmstu)   2020-07-01 14:45:00
推个
作者: biosphere (别)   2020-07-01 22:57:00
推推
作者: coolrobin (泳圈)   2020-07-01 23:56:00
未看先推
作者: rickkcir (多果汁)   2020-07-03 10:48:00

Links booklink

Contact Us: admin [ a t ] ucptt.com