太強了!外國小哥花16個月用Three.JS打造了一個無縫切地圖的3D開車遊戲

語言: CN / TW / HK

外國一位小哥耗時16個月打造的3D版賽車遊戲,這兩天忽然火了起來。

圖片

只需一個瀏覽器,就能駕車從森林、海灘,“無縫切換”到廣袤的沙漠甚至平原。甚至還可以選擇春夏秋冬或者白天黑夜的環境風格。

圖片

在不想自己開車的時候,竟然還可以開啟自動駕駛模式,感受一波“AI飆車”的快樂。

網友們也是嗨得不行:此情此景怎能少得了經典BGM逮蝦户(Deja Vu) 代碼片段

下面我們來看看它究竟是怎麼實現的。

他是怎麼實現的!

這個遊戲完全使用Three.js來開發,經大帥測試,這個遊戲可以在大部分網頁瀏覽器中運行,甚至在移動端上也有着非常優秀的表現。

此外,開發者還給出了不同級別的渲染設置來保證性能,玩家可以自由選擇適合自己設備的配置。是【模糊粗糙】還是【細節豐富】,豐儉由君哦~

除了開頭提到的隨意切換地點、季節和天氣以外,這個賽車遊戲也可以隨意切換各種車型和視角。

圖片

那麼這個賽車遊戲中“任意變幻”的環境到底是如何生成的?

生成高度圖

  • 使用類似於PerlinNoise的算法生成無限平鋪的高度圖,並加以修改以實現更為逼真的山景。
  • 使用Alea這個庫來生成偽隨機數。http://www.npmjs.com/package/alea

規劃道路

  • 公路的起點要選擇整個地形世界中不太陡峭,也不能太深的某個地方。將這裏作為道路中線的第一個點。
  • 選擇一個方向來測試周圍的高度圖用以評估橫向和縱向的梯度。
  • 然後,使中線向一個坡度最小的方向移動10米。這個點的信息被寫一個雙向鏈表中,每個點位信息都包含坡度,道路寬度,曲率等元數據。
  • 實現一個永無止境的道路,以距離車輛位置15KM的地平線為界,這是開發過程中耗時最久,讓小哥掉了最多頭髮的一個問題。
  • 使用二次貝塞爾曲線以1m的單位做路線的平滑處理。

圖片

地面環境

  • 為了進一步提升性能,靠近道路和遠離道路的地塊使用了不同網格密度來處理。
  • 道路被渲染為一個簡單的矩形網格,由3個高細節塊和9個低細節塊組成,每個長100m,隨着車輛的前進而循環。

圖片

圖形

  • 地面紋理採用世界座標UV,並混合PerlinNoise以改變植被的顏色。
  • 基於坡度混合懸崖面紋理和頂點位移。
  • 小哥一開始想實現動態陰影貼圖,但過於複雜從而放棄後選擇採用一種更簡單的方案,就是在樹木的下方應用深色紋理,造成有陰影的視覺假象。
  • 所有樹葉都由簡單的精靈圖和幾何體組成,將多種變化存儲在一個紋理圖中,該紋理使用頂點着色器中的噪聲採樣。

圖片

物理系統

  • 每個輪子都單獨結合重力,摩擦力和地面法線來獨立計算物理上動力學的特性。以此來解決車輛底盤的位置問題。
  • 道路兩側的圍擋沒有真正的採用物理碰撞算法,而是使用距離檢查來解決。
  • 物理特性的計算極其消耗性能,為此小哥去除了樹木,指示牌等其他東西物理特性的計算。

優化

  • 通過合併相近網格的幾何圖形,非常細緻的管理實例化對象從而節省提升渲染效率。
  • 車輛在道路中的進行情況會被不斷追蹤計算,並依據遠景能見度來釋放不可見的元素並使其重複使用。
  • 提供一系列和質量有關的設定以滿足不同設備上的渲染。

開源了嗎?

目前這款遊戲還沒有開源。不過小哥表示,雖然沒有開源整個項目的計劃,但後續可能會開源部分子系統,如圖形MOD接口等。

圖片

對於這款遊戲的未來,小哥也立下了幾個flag,包括在環境上,開發更多的越野地點、加入更多環境細節,包括建築、動物、植物陰影、燈光效果等;

賽車上,加入更多的賽車皮膚和車輛類型;天氣上,細化天氣類型(下雨、下雪、颳風等),也進一步改善已有天氣的效果;

功能上,將來會加入競爭模式和全球排行榜(包括限時競速、比拼距離等),同時對系統進一步進行優化,未來適配手柄、賽車模擬器等。

碼上掘金體驗

代碼片段

和往期分享的threejs項目一樣,這個賽車遊戲的本地項目代碼大帥也已經備份到AwesomeSites倉庫中的pack02裏了。

http://github.com/ezshine/AwesomeSites

雖然不是源碼,但依然具有學習和參考的價值~


  • 我是大帥老猿,微信公眾號同名。
  • 加本人微信交流,個人微信:dashuailaoyuan
  • 👍🏻:覺得有收穫請點個贊鼓勵一下!
  • 🌟:收藏文章,方便回看哦!
  • 💬:評論交流,互相進步!