定义
glTF 是由科纳斯组织(Khronos Group)制定的一种 3D 内容互联网传输格式,大名鼎鼎的 OpenGL 也是由科纳斯组织所制定。
什么是 3D 互联网内容传输格式呢?
举一个大家熟知的例子,PNG 格式是针对 2D 内容的一种传输格式,而 glTF 便是针对 3D 内容的一种传输格式,PNG 格式的文件后缀为 .png,而 gltf 格式的文件后缀为 .gltf 或 .glb。
概念
说明 glTF 格式前,仍然使用 PNG 格式作为对照组。
PNG 格式如何描述 2D 内容?
2D 内容即为普通图像文件,PNG 或者其他图像存储格式都是通过存储图像的颜色信息来描述一张图像,值得一提的是,不论是 PNG 格式还是 JPG 格式,都不会存储精确到像素点的颜色信息,因为这会使得文件大小急速膨胀,所以本质上 PNG 格式和 JPG 格式都是一种图像压缩技术,作用是在可以接受的失真下存储一张图像。
当然也有精确到像素点的图像存储格式,比如 Windows 平台的 BMP 格式,这类文件被称为位图文件,以 .bmp 后缀结尾。
存储 2D 内容的技术很明显不能够被应用到 3D 内容上,因为 2D 图像中的场景和视角是固定的,用户看到的东西是确定的,2D 存储格式只需要描述清楚每个区块使用什么颜色即可,而 3D 内容,根据用户调整的视角不同,呈现出来的内容也不同,也就是说,3D 内容是可交互的,所以对于 3D 内容存储格式,仅仅存储原始的 3D 数据是行不通的,每种 3D 格式还需要额外制定一套交互规则。这样,当一个软件想要支持某种 3D 格式时,只需要按照对应的规则编写数据读取逻辑,即可呈现可交互的 3D 内容。
glTF 格式如何描述 3D 内容?
glTF 格式文件有两种后缀,.gltf 和 .glb,此处内容仅适用于以 .gltf 作为后缀的文件。
glTF 格式使用 JSON 格式存储 3D 内容,整个 3D 内容被包含在一个 JSON 对象中,对象中的包含多个数组元素,这些数组元素中包含着相应的 3D 元素,如所有网格都被包含在 meshes 元素中,所有材质都被包含在 materials 元素中,其中的 3D 内容通过相互引用,将 3D 内容之间的关系以一种树状的形式进行管理,并且,这些内容的原始数据并不会直接体现在 JSON 中,而是通过统一的元素 buffers 管理,这使得 glTF 格式文件简洁易读。
官方的 glTF 示例:
{
"asset": {
"version": "2.0"
},
"scene": 0,
"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,
1,
0
],
"min": [
0,
0,
0
]
}
]
}
这份 glTF 文件包含了 8 个元素:
元素名 | 作用 |
---|---|
asset | 交代文件使用的 glTF 格式版本和其他信息 |
scene | glTF 格式描述一个 3D 场景的起点,指定加载的场景 |
scenes | 包含多个场景,每个场景可引用若干个节点 |
nodes | 包含多个节点,每个节点可包含多种 3D 元素 |
meshes | 包含网格元素 |
buffers | 存储原始的 3D 数据,为 bufferView 提供数据 |
bufferViews | 包含数据视图,每个数据视图对应原始数据中的一个区间,用于将原始数据分割成多个片段,为 accessor 提供数据 |
accessor | 包含数据访问器,每个访问器对应一个数据视图,用于指定数据视图的读取方式,为元素提供数据 |
这份 glTF 文件中包含的 3D 元素有 scene,node,mesh,他们之间的引用关系可以组织成如下的树状结构:
这个树状结构非常简单,仅仅包含一个场景,并且场景中只包含一个节点,而这个节点中也只包含了一个网格,最终这份 glTF 文件描述了一个如下的 3D 场景: