Cesium開發(fā)基礎(chǔ)篇 | 05glTF介紹及加載

到目前為止吃衅,我們已經(jīng)介紹了如何利用Cesium顯示影像數(shù)據(jù)派桩、地形高程數(shù)據(jù)、矢量數(shù)據(jù)贵少,以及空間可視化方面的幾何數(shù)據(jù)(Entity)呵俏,感興趣的同學(xué)可以閱讀我前面寫的文章。在三維數(shù)據(jù)方面滔灶,Cesium支持模型文件glTF普碎,以及三維瓦片數(shù)據(jù)3D Tiles。本次我們先從glTF說起录平,3D Tiles的講解留給下一章節(jié)麻车。

glTF介紹

glTF全稱是 Graphics Language Transmission Format (圖形語言傳輸格式),是一種針對GL(WebGL斗这,OpenGL ES以及OpenGL)接口的運(yùn)行時(shí)資產(chǎn)傳遞格式动猬,由澳大利亞的 Khronons 集團(tuán)進(jìn)行維護(hù),并于2017年6月5日在GitHub上(https://github.com/KhronosGroup/glTF)公布了glTF 2.0的規(guī)范表箭,此文也是針對于2.0版本進(jìn)行介紹的赁咙。glTF通過提供高效、可擴(kuò)展、可互操作的格式來傳輸和加載三維內(nèi)容彼水,填補(bǔ)了3D建模工具與現(xiàn)代圖形應(yīng)用程序之間的空白崔拥,它已成為了 Web 上的3D 對象標(biāo)準(zhǔn)(Web導(dǎo)出的通用標(biāo)準(zhǔn)),可以說glTF是3D 模型的JPEG格式凤覆,幾乎每個(gè)3D Web框架都支持glTF链瓦。隨著glTF的不斷發(fā)展,glTF形成了自己龐大的生態(tài)系統(tǒng)盯桦,同時(shí)收到了各行業(yè)的大力支持慈俯。所以,如果有人要為你提供3D 模型俺附,你就可以要求他們提供glTF格式的模型肥卡。

glTF生態(tài)系統(tǒng)
glTF行業(yè)支持

同時(shí),Cesium官方GitHub中也提供了obj轉(zhuǎn)glTF的源碼庫事镣,感興趣的可以前往這里https://github.com/CesiumGS/obj2gltf查看步鉴。

目前,glTF 3D模型格式有兩種:
*.gltf: 基于JSON的文本文件璃哟,可使用文本編輯器輕松編輯氛琢,通常會(huì)引用外部文件,例如紋理貼圖随闪、二進(jìn)制網(wǎng)格數(shù)據(jù)等阳似;
*.glb: 是二進(jìn)制格式,通常文件較小且自包含所有資源铐伴,但不容易編輯撮奏。

要獲取glb文件,可以直接從3D建模程序中導(dǎo)出它們当宴,也可以使用工具將gltf轉(zhuǎn)換為glb畜吊。在線轉(zhuǎn)換工具推薦 MakeGLB (https://sbtron.github.io/makeglb/),當(dāng)然户矢,如果您使用的是VS Code編輯器玲献,建議安裝 glTF Tools 擴(kuò)展工具,能夠非常方便的查看glTF的數(shù)據(jù)結(jié)構(gòu)梯浪、glTF和glb互轉(zhuǎn)等捌年。

glTF場景描述結(jié)構(gòu)

glTF的核心是一個(gè)JSON文件,另外還支持外部數(shù)據(jù)挂洛。具體而言礼预,一個(gè)glTF模型可包括以下三部分內(nèi)容:
JSON格式的文件(.gltf),其中包含完整的場景描述虏劲,并通過場景結(jié)點(diǎn)引用網(wǎng)格進(jìn)行定義 逆瑞。包括:節(jié)點(diǎn)層次結(jié)構(gòu)荠藤、材質(zhì)(定義了3D對象的外觀)、相機(jī)(定義義了渲染程序的視錐體設(shè)置 )获高、mesh(網(wǎng)格)、動(dòng)畫(定義了3D對象的變換操作吻育,比如選擇念秧、平移操作)、蒙皮(定義了3D對象如何進(jìn)行骨骼變換)等布疼;
.bin包含幾何和動(dòng)畫數(shù)據(jù)以及其他基于緩沖區(qū)的數(shù)據(jù)的二進(jìn)制文件摊趾;
圖像文件(.jpg,.png)的紋理游两。

如下圖所示:


glTF場景描述結(jié)構(gòu)

以其他格式定義的文件(例如圖像文件)可以存儲(chǔ)在通過URI引用的外部文件中砾层,并排存儲(chǔ)在GLB容器中,或使用數(shù)據(jù)URI直接嵌入到JSON中贱案,一個(gè)有效的glTF模型必須指定其版本肛炮。

glTF的JSON結(jié)構(gòu)

場景對象已數(shù)組的形式存儲(chǔ)在JSON文件中,可以使用數(shù)組中各個(gè)對象的索引來訪問它們:

"meshes" : 
[
    { ... }
    { ... }
    ...
],

這些索引還用于定義對象之間的關(guān)系宝踪。上面的示例定義了多個(gè)網(wǎng)格對象侨糟,并且一個(gè)節(jié)點(diǎn)可以使用網(wǎng)格索引引用上面定義的其中一個(gè)網(wǎng)格對象:

"nodes": 
[
    { "mesh": 0, ... },
    { "mesh": 5, ... },
    ...
}

下圖概述了glTF的JSON部分的頂級元素:

glTF地JSON結(jié)構(gòu)

下面我對這些元素進(jìn)行簡要說明:
scene: glTF格式的場景結(jié)構(gòu)描述條目。它通過引用node來定義場景圖瘩燥;
node: 場景圖層次中的一個(gè)節(jié)點(diǎn)秕重。它可以包含一個(gè)變換(比如旋轉(zhuǎn)或平移),并且可以引用其他(子)節(jié)點(diǎn) 厉膀。此外溶耘,它可以引用網(wǎng)格和相機(jī),以及描述網(wǎng)格變換的蒙皮服鹅;
camera: 定義了用于渲染場景的視錐體配置凳兵;
mesh: 描述了出現(xiàn)在場景中幾何對象實(shí)際的幾何數(shù)據(jù)。它是指accessor用于訪問實(shí)際幾何數(shù)據(jù)material的對象菱魔,并且是指在渲染對象時(shí)定義其外觀的 留荔;
skin: 定義了用于蒙皮的參數(shù),參數(shù)的值通過一個(gè)accessor對象獲得澜倦。
animation: 描述了一些結(jié)點(diǎn)如何隨時(shí)間進(jìn)行變換(比如旋轉(zhuǎn)或平移)聚蝶;
accessor: 一個(gè)訪問任意數(shù)據(jù)的抽象數(shù)據(jù)源。被mesh藻治、skin和animation元素使用來提供幾何數(shù)據(jù)碘勉、蒙皮參數(shù)和基于時(shí)間的動(dòng)畫值。它通過引用一個(gè)bufferView對象桩卵,來引用實(shí)際的二進(jìn)制數(shù)據(jù)验靡;
material: 包含了定義3D對象外觀的參數(shù)倍宾。它通常引用了用于3D對象渲染的texture對象;
texture: 定義了一個(gè)sampler對象和一個(gè)image對象胜嗓。sampler對象定義了image對象在3D對象上的張貼方式高职。

更多詳情,可查閱glTF 2.0規(guī)范(https://github.com/KhronosGroup/glTF/tree/master/specification/2.0/)以及glTF官方教程(https://github.com/KhronosGroup/glTF-Tutorials/tree/master/gltfTutorial

下面是一個(gè)最小巧的glTF格式文件的內(nèi)容辞州,它描述了一個(gè)簡單的三角形怔锌。

{
  "scenes" : [
    {
      "nodes" : [ 0 ]
    }
  ],
  
  "nodes" : [
    {
      "mesh" : 0
    }
  ],
  
  "meshes" : [
    {
      "primitives" : [ {
        "attributes" : {
          "POSITION" : 1
        },
        "indices" : 0
      } ]
    }
  ],

  "buffers" : [
    {
      "uri" : "data:application/octet-stream;base64,AAABAAIAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAA=",
      "byteLength" : 44
    }
  ],
  "bufferViews" : [
    {
      "buffer" : 0,
      "byteOffset" : 0,
      "byteLength" : 6,
      "target" : 34963
    },
    {
      "buffer" : 0,
      "byteOffset" : 8,
      "byteLength" : 36,
      "target" : 34962
    }
  ],
  "accessors" : [
    {
      "bufferView" : 0,
      "byteOffset" : 0,
      "componentType" : 5123,
      "count" : 3,
      "type" : "SCALAR",
      "max" : [ 2 ],
      "min" : [ 0 ]
    },
    {
      "bufferView" : 1,
      "byteOffset" : 0,
      "componentType" : 5126,
      "count" : 3,
      "type" : "VEC3",
      "max" : [ 1.0, 1.0, 0.0 ],
      "min" : [ 0.0, 0.0, 0.0 ]
    }
  ],
  
  "asset" : {
    "version" : "2.0"
  }}

glTF相關(guān)工具推薦

glTF在線驗(yàn)證: http://github.khronos.org/glTF-Validator/
瀏覽-Sketchfab: https://sketchfab.com/(需要注冊賬號,并且要上傳模型才能瀏覽)
瀏覽-PlayCanvas查看器: https://playcanvas.com/viewer
瀏覽-ThreeJS查看器: https://gltf-viewer.donmccurdy.com/
瀏覽-BabylonJS查看器: https://sandbox.babylonjs.com/
gltf轉(zhuǎn)glb: https://sbtron.github.io/makeglb/
obj2gltf: https://github.com/CesiumGS/obj2gltf
FBX2glTF: https://github.com/facebookincubator/FBX2glTF
COLLADA2GLTF: https://github.com/KhronosGroup/COLLADA2GLTF

Cesium加載glTF模型

Cesium提供了兩種方式加載glTF模型变过,分別是通過 Entity API 和 Primitive API 兩個(gè) API 實(shí)現(xiàn)的埃元。核心代碼如下:

var position = Cesium.Cartesian3.fromDegrees(-120.05, 44, 0);
    var heading = Cesium.Math.toRadians(45);
    var pitch = 0;
    var roll = 0;
    var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
    var orientation = Cesium.Transforms.headingPitchRollQuaternion(
      position,
      hpr
    );
    var model_entity = viewer.entities.add({
      name: "gltf模型",
      position: position,
      // 默認(rèn)情況下,模型是直立的并面向東媚狰。
      // 通過 Quaternion 為 Entity.orientation 屬性指定值來控制模型的方向岛杀,控制模型的航向,俯仰和橫滾崭孤。
      orientation: orientation,
      model: {
        show: true,
        uri: "./data/models/DracoCompressed/CesiumMilkTruck.gltf",
        scale: 1.0, // 縮放比例
        minimumPixelSize: 128, // 最小像素大小
        maximumScale: 20000, // 模型的最大比例尺大小类嗤。 minimumPixelSize的上限
        incrementallyLoadTextures: true, // 加載模型后紋理是否可以繼續(xù)流入
        runAnimations: true, // 是否應(yīng)啟動(dòng)模型中指定的glTF動(dòng)畫
        clampAnimations: true, // 指定glTF動(dòng)畫是否應(yīng)在沒有關(guān)鍵幀的持續(xù)時(shí)間內(nèi)保持最后一個(gè)姿勢

        // 指定模型是否投射或接收來自光源的陰影 type:ShadowMode
        // DISABLED 對象不投射或接收陰影;ENABLED 對象投射并接收陰影;CAST_ONLY  對象僅投射陰影;RECEIVE_ONLY  對象僅接收陰影
        shadows: Cesium.ShadowMode.ENABLED,
        heightReference: Cesium.HeightReference.NONE,
      },
    });
    // viewer.trackedEntity = entity; // 相機(jī)保持在實(shí)體上
   var origin = Cesium.Cartesian3.fromDegrees(-120, 44.0, 0);
    // 創(chuàng)建一個(gè)本地的東北向上坐標(biāo)系,其原點(diǎn)為經(jīng)度-120度裳瘪,緯度44.0度土浸。
    // 可以隨時(shí)更改模型的modelMatrix屬性以移動(dòng)或旋轉(zhuǎn)模型。
    var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(origin);
    var model = viewer.scene.primitives.add(
      Cesium.Model.fromGltf({
        url: "./data/models/DracoCompressed/CesiumMilkTruck.gltf",
        modelMatrix: modelMatrix,
        minimumPixelSize: 128,
        maximumScale: 20000,
      })
    );
    model.readyPromise.then(function (model) {
      // Play all animations when the model is ready to render
      model.activeAnimations.addAll();
    });

這里簡單說一下 modelMatrix 屬性彭羹,該屬性類型是 Matrix4 黄伊,即4x4轉(zhuǎn)換矩陣,用于將模型坐標(biāo)轉(zhuǎn)換為世界坐標(biāo)派殷,也就是為模型創(chuàng)建一個(gè)局部坐標(biāo)系还最。正如示例中的代碼那樣,為模型創(chuàng)建了一個(gè)本地的東北向上坐標(biāo)系毡惜,其原點(diǎn)為經(jīng)度-120度拓轻,緯度44.0度。在 Cesium 調(diào)試器面板中勾選顯示參考框架经伙,能夠很清晰的看到該模型對應(yīng)的X扶叉、Y、Z軸以及原點(diǎn)帕膜。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末枣氧,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子垮刹,更是在濱河造成了極大的恐慌达吞,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件荒典,死亡現(xiàn)場離奇詭異酪劫,居然都是意外死亡吞鸭,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門覆糟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來刻剥,“玉大人,你說我怎么就攤上這事滩字⊥傅校” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵踢械,是天一觀的道長。 經(jīng)常有香客問我魄藕,道長内列,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任背率,我火速辦了婚禮话瞧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘寝姿。我一直安慰自己交排,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布饵筑。 她就那樣靜靜地躺著埃篓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪根资。 梳的紋絲不亂的頭發(fā)上架专,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機(jī)與錄音玄帕,去河邊找鬼部脚。 笑死,一個(gè)胖子當(dāng)著我的面吹牛裤纹,可吹牛的內(nèi)容都是我干的委刘。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼鹰椒,長吁一口氣:“原來是場噩夢啊……” “哼锡移!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起吹零,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤罩抗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后灿椅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體套蒂,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡钞支,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了操刀。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片烁挟。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖骨坑,靈堂內(nèi)的尸體忽然破棺而出撼嗓,到底是詐尸還是另有隱情,我是刑警寧澤欢唾,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布且警,位于F島的核電站,受9級特大地震影響礁遣,放射性物質(zhì)發(fā)生泄漏斑芜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一祟霍、第九天 我趴在偏房一處隱蔽的房頂上張望杏头。 院中可真熱鬧,春花似錦沸呐、人聲如沸醇王。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽寓娩。三九已至,卻和暖如春滥朱,著一層夾襖步出監(jiān)牢的瞬間根暑,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工徙邻, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留排嫌,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓缰犁,卻偏偏與公主長得像淳地,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子帅容,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容