缓冲区、缓冲区视图和访问器
一个例子buffer
,缓冲视图
,和accessor
对象已在最小glTF文件第节。本节将更详细地解释这些概念。
缓冲器
Abuffer
表示原始二进制数据块,没有固有的结构或含义。缓冲区使用uri
. 此URI可以指向外部文件,也可以是数据URI它直接在JSON文件中对二进制数据进行编码。这个最小glTF文件包含一个buffer
,包含44个字节的数据,编码在数据URI中:
"buffers" : [
{
"uri" : "data:application/octet-stream;base64,AAABAAIAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAA=",
"byteLength" : 44
}
],
a的部分数据buffer
可能必须作为顶点属性或索引传递给渲染器,或者数据可能包含蒙皮信息或动画关键帧。为了能够使用此数据,需要有关此数据的结构和类型的附加信息。
缓冲视图
从buffer
与bufferView
物体。A缓冲视图
表示一个缓冲区的数据的“切片”。此切片使用偏移量和长度(以字节为单位)定义。这个最小glTF文件定义为二bufferView
物体:
"bufferViews" : [
{
"buffer" : 0,
"byteOffset" : 0,
"byteLength" : 6,
"target" : 34963
},
{
"buffer" : 0,
"byteOffset" : 8,
"byteLength" : 36,
"target" : 34962
}
],
第一个bufferView
指缓冲区数据的前6个字节。第二个是指缓冲区的36个字节,偏移量为8个字节,如图所示:
浅灰色显示的字节是正确对齐访问器所需的填充字节,如下所述。
每个bufferView
另外还包含目标
财产。渲染器稍后可能会使用此属性对缓冲区视图所引用的数据的类型或性质进行分类。这个target
可以是一个常量,指示数据用于顶点属性(thirty-four thousand nine hundred and sixty-two
,代表ARRAY_BUFFER
),或者数据用于顶点索引(thirty-four thousand nine hundred and sixty-three
,代表ELEMENT_ARRAY_BUFFER
).
在这一点上buffer
数据被分成多个部分,每个部分由一个部分描述缓冲视图
. 但是为了在渲染器中真正使用这些数据,需要有关数据类型和布局的附加信息。
访问器
安accessor
对象引用缓冲视图
并且包含定义此的数据的类型和布局的属性bufferView
.
数据类型
访问器的数据类型编码在type
以及组件类型
属性。的价值type
属性是一个字符串,用于指定数据元素是标量、向量还是矩阵。例如,值可以是“标量”
对于标量值,"VEC3"
对于3D矢量,或“材料4”
对于4×4个矩阵
这个componentType
指定这些数据元素的组件的类型。这是一个GL常量,例如five thousand one hundred and twenty-six
(FLOAT
)或者five thousand one hundred and twenty-three
(UNSIGNED_SHORT
),表示元素具有浮动
或unsigned short
分别是组件
这些属性的不同组合可用于描述任意数据类型。例如最小glTF文件包含两个访问器:
"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 ]
}
],
第一个访问器引用bufferView
索引为0,它定义缓冲器
包含索引的数据。它type
是“标量”
,以及它的componentType
是five thousand one hundred and twenty-three
(UNSIGNED_SHORT
). 这意味着索引存储为标量无符号短
价值观
第二个访问器引用bufferView
索引1,它定义了缓冲器
包含顶点属性(尤其是顶点位置)的数据。它type
是“VEC3”
,以及它的componentType
是five thousand one hundred and twenty-six
(FLOAT
). 所以这个存取器用浮点组件来描述三维向量。
数据布局
的附加属性accessor
进一步指定数据的布局。这个计数
属性指示它由多少个数据元素组成。在上面的例子中,计数是3
对于两个访问器,分别代表三角形的三个索引和三个顶点。每个访问器还具有字节偏移量
财产。对于上面的例子,它已经0
因为只有一个访问者存取器
为每一个bufferView
. 但是当多个访问器引用同一个缓冲视图
,然后byteOffset
描述访问器的数据相对于缓冲视图
它所指的
数据对齐
被引用的数据accessor
可以发送到显卡进行渲染,也可以在主机端用作动画或蒙皮数据。因此存取器
必须根据类型数据的。例如,当componentType
一个存取器
是5126
(浮动
),则数据必须在4字节边界对齐,因为float
值由四个字节组成。这种对齐要求存取器
指其bufferView
以及潜在的缓冲器
. 具体来说,线形要求如下:
- 这个
byteOffset
一个存取器
必须可以被它的大小整除componentType
. - 的总和
byteOffset
访问器和字节偏移量
的bufferView
它所指的必须被它的大小整除组件类型
.
在上面的示例中byteOffset
的缓冲视图
索引1(指顶点属性)被选为8
,以便将顶点位置访问器的数据与4字节边界对齐。字节six
和7
的缓冲器
因此衬垫不携带相关数据的字节。
图5c演示了buffer
结构使用缓冲视图
对象,并使用accessor
物体
数据交织
存储在单个bufferView
可以存储为结构物阵列. 单曲bufferView
例如,可以以交错方式包含顶点位置和顶点法线的数据。在这种情况下字节偏移量
访问器的定义了各自属性的第一个相关数据元素的开始,并且bufferView
定义一个附加的byteStride公司
财产。这是访问器的一个元素的开始与下一个元素的开始之间的字节数。交错位置和法线属性如何存储在bufferView
如图5d所示
数据内容
安accessor
还包含最小
和max
汇总其数据内容的属性。它们是访问器中包含的所有数据元素的组件最小值和最大值。在顶点位置的情况下最小
和max
因此,属性定义边界框一个物体的。这对于确定下载的优先级或可见性检测非常有用。一般来说,这些信息对于存储和处理也是有用的量子化由渲染器在运行时取消量化的数据,但此量化的详细信息超出了本教程的范围。
稀疏存取器
在2.0版本中稀疏存取器是在glTF中引入的。这是一种特殊的数据表示,它允许非常紧凑地存储只有几个不同条目的多个数据块。例如,当存在包含顶点位置的几何体数据时,该几何体数据可用于多个对象。这可以通过参考相同的方法来实现accessor
从两个对象。如果两个对象的顶点位置基本相同,并且只有几个顶点不同,则无需将整个几何体数据存储两次。相反,可以只存储一次数据,并使用稀疏访问器仅存储与第二个对象不同的顶点位置。
下面是一个完整的glTF资产,在嵌入式表示中,显示了稀疏访问器的示例:
{
"scenes" : [ {
"nodes" : [ 0 ]
} ],
"nodes" : [ {
"mesh" : 0
} ],
"meshes" : [ {
"primitives" : [ {
"attributes" : {
"POSITION" : 1
},
"indices" : 0
} ]
} ],
"buffers" : [ {
"uri" : "data:application/gltf-buffer;base64,AAAIAAcAAAABAAgAAQAJAAgAAQACAAkAAgAKAAkAAgADAAoAAwALAAoAAwAEAAsABAAMAAsABAAFAAwABQANAAwABQAGAA0AAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAQAAAAAAAAAAAAABAQAAAAAAAAAAAAACAQAAAAAAAAAAAAACgQAAAAAAAAAAAAADAQAAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAQAAAgD8AAAAAAABAQAAAgD8AAAAAAACAQAAAgD8AAAAAAACgQAAAgD8AAAAAAADAQAAAgD8AAAAACAAKAAwAAAAAAIA/AAAAQAAAAAAAAEBAAABAQAAAAAAAAKBAAACAQAAAAAA=",
"byteLength" : 284
} ],
"bufferViews" : [ {
"buffer" : 0,
"byteOffset" : 0,
"byteLength" : 72,
"target" : 34963
}, {
"buffer" : 0,
"byteOffset" : 72,
"byteLength" : 168
}, {
"buffer" : 0,
"byteOffset" : 240,
"byteLength" : 6
}, {
"buffer" : 0,
"byteOffset" : 248,
"byteLength" : 36
} ],
"accessors" : [ {
"bufferView" : 0,
"byteOffset" : 0,
"componentType" : 5123,
"count" : 36,
"type" : "SCALAR",
"max" : [ 13 ],
"min" : [ 0 ]
}, {
"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
}
}
} ],
"asset" : {
"version" : "2.0"
}
}
渲染该资源的结果如图5e所示:
该示例包含两个访问器:一个用于网格的索引,另一个用于顶点位置。引用顶点位置的那个定义了一个附加的accessor.sparse
属性,其中包含有关应应用的稀疏数据替换的信息:
"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
}
}
} ],
这个sparse
对象本身定义计数
将受替换影响的元素。这个sparse.indices
属性引用缓冲视图
包含要替换的元素的索引。这个sparse.values
指的是缓冲视图
包含实际数据的
在本例中,原始几何数据存储在bufferView
索引为1。它描述了一个顶点的矩形数组。这个稀疏.index
请参阅bufferView
包含索引2的索引[8, 10, 12]
. 这个sparse.values
指缓冲视图
包含新顶点位置的索引3,即,[(1,2,0), (3,3,0), (5,4,0)]
. 应用相应替换的效果如图5f所示。