glTF 全称是 Graphics Language Transmission Format (图形语言传输格式),是一种针对 GL(WebGL,OpenGL ES 以及 OpenGL)接口的运行时资产传递格式,由澳大利亚的 Khronons 集团进行维护,并于 2017 年 6 月 5 日在GitHub上公布了 glTF 2.0 的规范,此文也是针对于 2.0 版本进行介绍的。
glTF 通过提供高效、可扩展、可互操作的格式来传输和加载三维内容,填补了 3D 建模工具与现代图形应用程序之间的空白,它已成为了 Web 上的 3D 对象标准(Web 导出的通用标准),可以说 glTF 是 3D 模型的 JPEG 格式,几乎每个 3D Web 框架都支持 glTF。随着 glTF 的不断发展,glTF 形成了自己庞大的生态系统,同时受到了各行业的大力支持。
glTF 小模型只是 Primitive 或 Entity 的其中一种类型数据,代码加载方式是一致的,这里单独拿出来讲解下他的.gltf 数据特性。
1. glTF 数据结构
glTF 的核心是一个 JSON 文件,另外还支持外部数据。具体而言,一个 glTF 模型可包括以下三部分内容:
- JSON 格式的文件(.gltf),其中包含完整的场景描述,并通过场景结点引用网格进行定义 。包括:节点层次结构、材质(定义了 3D 对象的外观)、相机(定义义了渲染程序的视锥体设置 )、mesh(网格)、动画(定义了 3D 对象的变换操作,比如选择、平移操作)、蒙皮(定义了 3D 对象如何进行骨骼变换)等;
- .bin 包含几何和动画数据以及其他基于缓冲区的数据的二进制文件;
- 图像文件(.jpg,.png)的纹理。
1.1 glTF 的 JSON 结构
场景对象以数组的形式存储在 JSON 文件中,可以使用数组中各个对象的索引来访问它们:
"meshes" :
[
{ ... }
{ ... }
...
],
"meshes" :
[
{ ... }
{ ... }
...
],
这些索引还用于定义对象之间的关系。上面的示例定义了多个网格对象,并且一个节点可以使用网格索引引用上面定义的其中一个网格对象:
"nodes":
[
{ "mesh": 0, ... },
{ "mesh": 5, ... },
...
}
"nodes":
[
{ "mesh": 0, ... },
{ "mesh": 5, ... },
...
}
下图概述了 glTF 的 JSON 部分的顶级元素:
下面我对这些元素进行简要说明:
- scene: glTF 格式的场景结构描述条目。它通过引用 node 来定义场景图;
- node: 场景图层次中的一个节点。它可以包含一个变换(比如旋转或平移),并且可以引用其他(子)节点 。此外,它可以引用网格和相机,以及描述网格变换的蒙皮;
- camera: 定义了用于渲染场景的视锥体配置;
- mesh: 描述了出现在场景中几何对象实际的几何数据。它是指 accessor 用于访问实际几何数据 material 的对象,并且是指在渲染对象时定义其外观的 ;
- skin: 定义了用于蒙皮的参数,参数的值通过一个 accessor 对象获得。
- animation: 描述了一些结点如何随时间进行变换(比如旋转或平移);
- accessor: 一个访问任意数据的抽象数据源。被 mesh、skin 和 animation 元素使用来提供几何数据、蒙皮参数和基于时间的动画值。它通过引用一个 bufferView 对象,来引用实际的二进制数据;
- material: 包含了定义 3D 对象外观的参数。它通常引用了用于 3D 对象渲染的 texture 对象;
- texture: 定义了一个 sampler 对象和一个 image 对象。sampler 对象定义了 image 对象在 3D 对象上的张贴方式。
更多详情,可查阅 glTF 2.0 规范以及 glTF 官方教程
1.2 glTF 相关工具推荐
浏览: BabylonJS 查看器浏览 gltfThreeJS 查看器浏览 gltfPlayCanvas 查看器浏览 gltf
数据处理:单体小模型转为 glTF 格式
2. glTF 的使用
供了两种方式加载 glTF 模型,分别是通过 Entity API 和 Primitive API 两个 API 实现的,使用方式差不多,仅类名不同。
核心代码如下:
//entity方式
var graphic = new mars3d.graphic.ModelEntity({
position: [116.35104, 30.86225, 374.4],
style: {
url: 'http://data.mars3d.cn/gltf/mars/fengche.gltf',
heading: 270,
scale: 30,
minimumPixelSize: 100
}
});
graphicLayer.addGraphic(graphic);
//primitive方式
var primitive = new mars3d.graphic.ModelPrimitive({
position: [116.35104, 30.86225, 374.4],
style: {
url: 'http://data.mars3d.cn/gltf/mars/fengche.gltf',
colorBlendMode: Cesium.ColorBlendMode.MIX,
heading: 270,
scale: 30,
minimumPixelSize: 100
}
});
graphicLayer.addGraphic(primitive);
//entity方式
var graphic = new mars3d.graphic.ModelEntity({
position: [116.35104, 30.86225, 374.4],
style: {
url: 'http://data.mars3d.cn/gltf/mars/fengche.gltf',
heading: 270,
scale: 30,
minimumPixelSize: 100
}
});
graphicLayer.addGraphic(graphic);
//primitive方式
var primitive = new mars3d.graphic.ModelPrimitive({
position: [116.35104, 30.86225, 374.4],
style: {
url: 'http://data.mars3d.cn/gltf/mars/fengche.gltf',
colorBlendMode: Cesium.ColorBlendMode.MIX,
heading: 270,
scale: 30,
minimumPixelSize: 100
}
});
graphicLayer.addGraphic(primitive);