讀後筆記:用 Wave Function Collapse 打造 4,100 格程序化六角島嶼

本篇文章更新時間:2026/03/10
如有資訊過時或語誤之處,歡迎使用 Contact 功能通知或向一介資男的 LINE 社群反應。
如果本站內容對你有幫助,歡迎贊助支持


用 WFC 打造六角島嶼:從小骰子幻想到 WebGPU 的程序化世界

程序生成地圖的極限挑戰,從演算法到美術一次到位

編輯前言:原文作者 Felix Turner 在文章《Building a Procedural Hex Map with Wave Function Collapse》中,完整分享了他如何用 WFC、WebGPU、TSL,打造一個由 4,100 個六角格組成、兼具地形、河流、道路與海岸線細節的中世紀島嶼地圖。這篇筆記試著整理他的核心方法與實作心法。

核心觀點 (Key Takeaways)

  • WFC 在六角格上難度暴增:六邊形有 6 個邊,比方格多 50% 約束,造成組合爆炸與更高失敗率。
  • 大型地圖必須模組化求解:作者將地圖切成 19 个 hex grids,各自 WFC,再處理邊界矛盾。
  • 視覺不全靠 WFC:地表靠 WFC,森林、建築等「大尺度分佈」則交給噪聲(Perlin noise)。兩者分工讓地圖看起來更自然。

深入解析

作者從童年的 AD&D 隨機地城表啟蒙,延續到今天打造「可以被發現,而不是被設計」的程序化地圖。整個系統的核心,依舊是 WFC(Wave Function Collapse),但這一版面對的是更刁鑽的六角格世界。

六角格 WFC 的真正難題:組合爆炸

原文提到:

“Hex tiles have 6 edges instead of 4. That's 50% more constraints per tile.”

作者的 tile set 共有 30 種瓦片,每種有 6 個旋轉、5 種高度,最後形成一格最多「900 種可能狀態」。這也解釋了為何大地圖會頻繁失敗:每次 collapse 都可能連鎖出幾百個約束淘汰。

大型地圖的關鍵:Multi-Grid 與 Recovery System

全圖超過 4,100 格,如果一次 WFC,幾乎必然卡死。因此作者改用「19 個子地圖」各自求解,但邊界瓦片會互相施壓,結果常常是:隔壁已固定的邊界根本無法滿足當前子地圖的可能性。

作者提出三層恢復策略:

  • Layer 1:Unfixing — 把造成衝突的鄰居瓦片從「固定」改成「可重新計算」。
  • Layer 2:Local-WFC — 在問題區域重新跑一個半徑 2 的迷你 WFC,修補邊界。作者稱這是突破點,成功率大幅提升。
  • Layer 3:Drop and hide — 最後手段:把衝突瓦片直接換成「山」。山的 cliff edge 幾乎可和任何邊對上,看起來也自然。

這段特別有趣,因為作者坦白:

“Mountains are great — their cliff edges match anything, and they look intentional. Nobody questions a mountain.”

程式解不出來?那就把問題丟給地形。這種 pragmatism 十分實用。

三維高度:從 2D 變成 3D 的複雜度暴增

WFC 通常是平面,但此案加入 5 種高度等級、各種上坡下坡 tile,造成邊界不只比對材質,還得比對高度。錯配就會出現「河流逆流」或「道路撞上懸崖」。

作者強調 elevation 是失敗率來源之一,但同時也是地圖自然感的重要來源。

噪聲系統:不是所有東西都適合 WFC

作者原本嘗試用 WFC 放樹、放建築,結果森林散得像鹽巴、村莊也不成聚落。他說:

“WFC is great at local edge matching but terrible at large-scale patterns.”

於是森林與建築改用 Perlin noise:

  • noises 高 → 森林
  • 另一層 noises → 建築聚落
  • 邏輯再決定風車、港口、石陣等特殊建築位置

這讓整體分佈自然許多。

水系效果:最艱難的視覺挑戰

海水並不是一張藍色平面,而是層層效果疊起來:

  • 捲動的 caustic sparkles(用小紋理取代昂貴的 Voronoi)
  • 基於海岸距離的 sine wave 輻射波紋
  • 特別解決「海灣波紋變得太厚」的 cove mask

這些細節讓地圖呈現《Wind Waker》般的活力。

WebGPU + BatchedMesh 的性能優化

為了在手機上仍跑到 60fps,作者以兩個策略:

  • 每個子地圖只有 2 個 BatchedMesh(地形 + 裝飾)
  • 全場景使用同一套材質 + 小型顏色貼圖

這讓整張地圖的渲染呼叫數極低,將 GPU 資源留給 AO、DOF、顆粒等後製。

筆者心得與啟發

這篇文章的收穫不只是技術,更是一種心態。

首先,WFC 不是魔法。它會失敗,而且會常常失敗。作者的實務心得是:真正的工程成果,是建立一套「恢復機制」來處理這些失敗,不是指望演算法一次完美收斂。

其次,地圖的自然感,來自「演算法的分工」:

  • 小尺度邊界匹配 → WFC
  • 大尺度分佈 → Noise
  • 藝術化呈現 → Shader 與後製

單一技術不可能解決所有需求。把每個系統放到最適合的位置,才會有美觀與可控的成果。

最後我最有感的一句話,是作者對程序生成的浪漫:

“You hit a button, the map builds itself, and you discover what the algorithm decided to put there.”

這種「發現而不是設計」的樂趣,也是許多遊戲開發者與創作者熱愛程序生成的根本原因。

如果你正在製作地圖系統、程序化內容,或想導入 WFC,本篇原文絕對值得細讀。而如果你曾被大型 WFC 計畫卡住,作者這套 recovery system 非常值得參考。


Share:

作者: Chun

WordPress 社群貢獻者、開源社群推廣者。專注於 WordPress 外掛開發、網站效能最佳化、伺服器管理,以及 iDempiere 開源 ERP 導入與客製開發。曾參與 WordCamp Taipei 等社群活動,GitHub Arctic Code Vault Contributor。提供資訊顧問、WordPress 開發教學、主機最佳化與企業 ERP 整合服務。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *


文章
Filter
Apply Filters
Mastodon