three-tile 介紹
three-tile 是一個開源的輕量級三維瓦片庫,它基于threejs使用typescript開發,提供一個三維地形模型,能輕松給你的應用增加三維瓦片地圖。
![]() | ![]() | ![]() |
---|---|---|
![]() | ![]() | ![]() |
源碼:https://github.com/sxguojf/three-tile
示例:https://github.com/sxguojf/three-tile-example
1. three-tile是什么?
- three-tile 是 webgis?不,它的gis功能很弱,僅提供了三維地圖模型和地理坐標轉換功能。
- three-tile 是基于cesium、mapbox等的二次封裝嗎?不,它是基于 threejs 自主實現的。
- three-tile 更像是游戲開發中的LOD地形,但它可以使用地圖服務商提供的地形和影像瓦片數據渲染地圖。
- three-tile 的地圖被封裝為一個普通的 Mesh,能輕松添加進 threejs 應用中。
- three-tile 的核心實際與地圖無關,它就是一個LOD模型,地圖只是其典型應用之一。
2. 開發初衷
-
市面上的三維 webgis 框架不少,如 cesium、MapBox.gl 等,功能強大,但這些地圖作為重量級框架,它包攬了三維場景、攝像機、模型、燈光等一切,想深度定制難度較大,另外,它們本身占用資源太多,功能一多速度難以滿足需求。
-
三維地形也是游戲引擎中的重要功能之一,但主流的游戲引擎地形數據要么隨機生成,要么美工手工設計,地形制作工作量較大。當然,unity3d、unreal4等游戲引擎,也有一些插件可以導入真實地形,但通用性較差,操作復雜。
是否能將真實地圖數據與游戲的三維地形結合,提供一個使用瓦片地圖服務的輕量級三維地形模型? OK,這就是three-tile的開發初衷。
3. 3D開發技術選型
- webgl: web下3D開發必備,但直接基于webgl開發很繁瑣,選擇一個3D引擎能大大節省開發時間。
- threejs: 封裝了webgl,使用簡單,國內具有非常好的生態。
- babylonjs: 封裝了webgl,大廠出品,ts編寫,支持webgpu,但國內生態不如threejs。
- unity3d: 游戲引擎,可用C#、JavaScript開發,但主要用于游戲,web端支持較差。
- unreal: 游戲引擎,主要用于游戲,只能做桌面版。
綜合比較,如果開發web版的3d地圖,選擇threejs和babylon.js更加適合,考慮個人開發影響力太小,需要借助其它框架生態,那threejs是首選。
當然,如果確實有需求,我覺得用babylon或unity3d也可以考慮。目前還是使用threejs開發。
4. 典型應用場景
4.1 給現有應用增加地形
在threejs示例中,大部分簡單應用使用一個平面作為地面,如果能把平面換為真實地形,立馬增色不少:
![]() | ![]() |
---|---|
three.js examples (threejs.org) | three-tile demo (sxguojf.github.io) |
![]() | ![]() |
---|---|
three.js examples (threejs.org) | three-tile demo (sxguojf.github.io) |
![]() | ![]() |
---|---|
three.js examples (threejs.org) | three-tile demo (sxguojf.github.io) |
![]() | ![]() |
---|---|
three.js examples (threejs.org) | three-tile demo (sxguojf.github.io) |
而這一切使用three-tile僅需三步:
- 定義地圖數據源
- 創建地圖模型
- 用地圖替換原來的平面
4.2 簡單的webgis
當然,你如果要把three-tile當做一個簡單三維gis也未嘗不可,地圖模型可直接使用主流瓦片數據源,渲染出逼真的地形;提供地理坐標(經緯度海拔高度)到三維場景坐標的轉換,將地圖元素(模型、標簽)疊加在指定位置;通過鼠標鍵盤控制攝像機,實現地圖縮放、平移、旋轉和漫游;內置mapbox、bing、goole、arcgis、天地圖、高德、騰訊等瓦片地圖支持,也可以自行擴展支持其它瓦片地圖服務。
![]() | ![]() | ![]() | ![]() |
---|---|---|---|
![]() | ![]() | ![]() | ![]() |
4.3 游戲開發
如果你想將three-tile用于游戲開發,也可以試試,它完美支持threejs內置的各種控制器,僅更換控制器,即可實現第一人稱、飛行等游戲功能,在真實地圖上開戰效果應該不錯。由于地圖是實時下載的,如果對地圖加載中的空白塊不爽,可以通過調整地圖的數據緩存和渲染緩沖區大小參數,以空間換時間緩解這個問題。
![]() | ![]() | ![]() |
---|---|---|
three-tile demo | three-tile demo | three-tile demo |
4.4 數據可視化
目前,three-tile在生產環境的應用主要是數據可視化:
![]() | ![]() |
---|---|
three-tile demo | |
![]() | ![]() |
three-tile demo |
總之,three-tile僅提供一個地形Mesh,利用threejs的強大生態實現各種炫酷的效果。如果你是threejs開發者,值得一試。
5. 特點
- 輕量級:地圖以一個三維模型方式提供,使用它不會對已有程序架構產生任何影響。
-
依賴少:整個框架僅有 threejs(R165)一個依賴。
-
速度快:對資源占用做極致優化,核顯也能輕松跑到 60FPS。
-
使用簡單:熟悉 threejs 基本上沒有學習成本。
-
擴展性強:數據、模型、紋理、材質、渲染過程均能根據自己需要擴展和替換。
6. 局限性
能力有限,three-tile目前還有一些短板,期待有興趣的開發者參與。
-
地圖未使用球面坐標系:為了保持庫的簡潔,地圖模型使用笛卡爾坐標,地球并不是個球,而是投影到了平面。
為什么不做成球,一方面是為了開發簡單,另一方面使用球面坐標系,threejs內置的大部分幾何體、著色器都需要修改,如BoxGeometry,它的邊不能是直線,而要與地球曲率相適應,threejs的生態完全不適用了。開始的開發計劃,就是打算做個平面地圖,畢竟從太空才能看出來地球是個球,但無法滿足貪婪的用戶需求,好吧,搞個偽球體把多余的部分遮住,遠看像個球就行了。
-
存在z-fight問題: 受計算精度影響,在遠距離觀察時,webgl分不清物體的前后遮擋,即存在讓所有三維開發者頭痛的z-fight問題。
既想在數萬公里看地球,又要貼地看清地面的小汽車,z-fight不可避免,雖然可以使用logarithmicDepthBuffer緩解,但這個縮放范圍實在太大了,上萬公里高空webgl已經無法分清你的模型距地0.1公里還是0.2公里,它會不停閃爍。能否參考cesium使用分段渲染的方式解決?但three-tile初衷是只是做一個模型,不涉及模型外的東西,如果z-fight確實對你的應用影響較大,那可以試試分段渲染。
-
貼地功能未實現:three-tile最大的短板是貼地功能,目前貼地是使用射線法計算地形高度,但效率太低,線、面的貼地計算量太大無法完成。
cesium使用深度緩沖區對模型進行剪裁實現,真是腦洞大開!我也嘗試使用深度緩沖區使用著色器進行三維模型重建,但無奈未能成功。
-
暫未做移動端匹配:要改的太多,暫沒有精力。