Buffer

一个Buffer表示了一个二进制数据块.

BufferView

BufferView是对Buffer的切分.切分通过byteOffsetbyteLength两个属性来定义.
同时,每个BufferView对象包括了一个target属性,用于对BufferView引用的数据进行分类.

"bufferViews" : [
{
"buffer" : 0,
"byteOffset" : 0,
"byteLength" : 6,
"target" : 34963
},
{
"buffer" : 0,
"byteOffset" : 8,
"byteLength" : 36,
"target" : 34962
}

上文对应BufferView

上图浅色部分(无意义部分)用于数据对齐.

  • 34962: ARRAY_BUFFER, 用于存储顶点数据
  • 34963: ELEMENT_ARRAY_BUFFER, 用于存储索引数据
部分target意义

Accessor

一个Accessor对象引用了一个BufferView对象,并定义了如何从BufferView中读取数据.

一个BufferView可以被多个Accessor对象引用,但一个Accessor对象只能引用一个BufferView对象.

"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 ]
}
],
  • count: 定义了数据元素的数量
  • type: 定义了元素的类型,如SCALAR,VEC3,VEC4
  • componentType: 定义了元素的格式,如5123表示FLOAT,5126表示UNSIGNED_SHORT
  • max: 定义了元素的最大值(疑似有误)
  • min: 定义了元素的最小值(疑似有误)
  • byteOffset: 定义了Accessor对象在BufferView中的偏移量

数据对齐

为了让accessor对象引用的数据能直接交给CPU或GPU处理,因此其引用的数据必须进行对齐.

对齐条件:

  • accessor对象的byteOffset能整除componentType对应类型
  • accessorbufferViewbyteOffset之和能整除componentType对应类型

数据交错

由于bufferView引用的数据可能以结构数组的形式存储,所以需要byteStride属性来定义结构数组的步长.

数据交错

稀疏访问器

当有多个3D对象只有少部分顶点位置数据不同时,可以通过稀疏访问器来节省内存.

通过稀疏访问器,只需要村塾3D队形的顶点位置数据一次,然后存储对象间不同的顶点位置数据即可.

"accessors" : [ 
...
{
"bufferView" : 1,
"byteOffset" : 0,
"componentType" : 5126,
"count" : 14,
"type" : "VEC3",
"max" : [ 6.0, 4.0, 0.0 ],
"min" : [ 0.0, 0.0, 0.0 ],
"sparse" : {
"count" : 3,
"indices" : {
"bufferView" : 2,
"byteOffset" : 0,
"componentType" : 5123
},
"values" : {
"bufferView" : 3,
"byteOffset" : 0
}
}
} ],

accessor对象中的sparse属性定义了稀疏访问器.

  • count : 定义了需要替换的数据元素数量
  • sparse.indices : 定义了用于替换的顶点索引数据
  • sparse.values : 定义了用于包含实际的数据