看板 GameDesign 關於我們 聯絡資訊
網頁版 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以外的地形資料可能要參考這個流程。 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 59.120.146.90 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/GameDesign/M.1593577256.A.B08.html
sampp1213205: 推一個 07/01 13:42
Lhmstu: 推個 07/01 14:45
biosphere: 推推 07/01 22:57
coolrobin: 未看先推 07/01 23:56
rickkcir: 推 07/03 10:48
※ 編輯: yekdniw (59.120.146.90 臺灣), 07/08/2020 10:10:06 ※ 編輯: yekdniw (59.120.146.90 臺灣), 07/15/2020 11:03:38