到目前為止吃衅,我們已經(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格式的模型肥卡。
同時(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)的紋理游两。
如下圖所示:
以其他格式定義的文件(例如圖像文件)可以存儲(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部分的頂級元素:
下面我對這些元素進(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)帕膜。