GLTF
GLTF代表Graphics Language Transmission Format(图形语言传输格式)。这种跨平台格式已成为Web上的3D对象标准。简单来说,gltf通过json格式的文件来描述模型如何渲染导出。
上图是我自己画的思维导图,描述了json格式里每个变量之间的关系。
"buffers": [
{
"uri": "moltenDagger_data.bin",
"byteLength": 56076
}
]
我们先从整体来看,gltf的目的是为了导出模型数据,buffers定义了模型二进制的api以及读取的长度。
"bufferViews": [
{
"buffer": 0,
"byteLength": 7788,
"name": "bufferViewScalar",
"byteOffset": 0
},
{
"buffer": 0,
"byteOffset": 7788,
"byteLength": 24144,
"byteStride": 12,
"name": "bufferViewFloatVec3"
}]
buffers包含了所有的数据,但实际上我们的渲染过程要包括顶点,法线,纹理等等,所以将buffers通过bufferviews数组的定义,划分成不同的数据块,如上述代码,第一个用于描述大小,byteoffset描述的是从哪里开始读,从第一个二进制数据开始读,读7788个,第二个数据块从7788开始读,读24144个,用于描述一个三维的向量。很显然,如果有下一个数组,要从31932开始读。
{
"bufferView": 0,
"byteOffset": 0,
"componentType": 5123,
"count": 168,
"type": "SCALAR",
"name": "accessorIndices"
},
accessors用于描述bufferviews,我们只知道哪一个部分是三维,二维,四维,根据数据类型划分的数据块,accessors要根据功能划分数据块。bufferView是描述bufferviews的索引,其中byteOffset描述了相对于每个bufferview的起始位置,所以当我们真正要读二进制数据的时候,需要将两个byteOffset相加起来。
count是数据量的计数,比如这里是168个,type描述数据类型,其他的如Normal,VEC2,VEC3,也就是bufferviews里面的type应该是一致的。componentType描述了数据类型,用componentType除以count,可以直到每个数据的大小。同样,我们直到5123代表的类型长度,同样可以知道读取的数据长度。
name描述用途,其它的可能有Nornal,UVs等等。
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 1,
"TANGENT": 2,
"NORMAL": 3,
"TEXCOORD_0": 4
},
"indices": 0,
"mode": 4,
"material": 0
}
],
"name": "daggerGem_low"
},
{
"primitives": [
{
"attributes": {
"POSITION": 6,
"TANGENT": 7,
"NORMAL": 8,
"TEXCOORD_0": 9
},
"indices": 5,
"mode": 4,
"material": 1
}
],
"name": "daggerBlade_low"
},
{
"primitives": [
{
"attributes": {
"POSITION": 11,
"TANGENT": 12,
"NORMAL": 13,
"TEXCOORD_0": 14
},
"indices": 10,
"mode": 4,
"material": 2
}
],
"name": "daggerHandle_low"
}
],
meshes中的是primitives的数组,其中键值定义了功能,值定义了索引,比如POSITION是accessors中第一个成员描述的,可以推断,accessors应该有15个。
该数组有三个成员,也就是说渲染图元应该是三角形,和mode=4对应。
综上就是gltf如何导出模型的,buffers是总的数据,bufferviews根据数据类型分成了小块,accessors根据用途又分成了更小的数据块。primitives描述了一个图元应该具有哪些内容,告诉GPU,然后根据索引去连接对应的数据。