目录
4. buffers, bufferViews, accessors
gltf采用json格式描述3D模型的结构,主要用来解决3D模型在网络中的高效传输问题。
1. Concepts
gltf 主要包括以下元素。
名称 | 含义 |
scenes, nodes | 场景基本结构 |
cameras | 相机 |
meshes | 三维几何 |
buffers, bufferViews, accessors | 数据块 |
materials | 材质 |
textures, images, samplers | 纹理,图片,采样器 |
skins | 蒙皮 |
animations | 动画 |
gltf中元素的关系图如下:
2. scenes, nodes
gltf中可以定义若干个场景(scenes),每个场景引用若干个节点(nodes),节点以树形结构的方式组织。
节点(nodes)可以包含坐标转换。该转换可以用平移(translation),旋转(rotation),缩放(scale)分别表示。
"nodes": [
{
"translation": [ 0,0,0 ],
"rotation": [ 0,0,0,1 ],
"scale": [ 1,1,1 ]
...
}
]
也可以通过4*4的矩阵(matrix)表示坐标转换。即:
"nodes": [
{
"matrix": [
1,0,0,0,
0,1,0,0,
0,0,1,0,
5,6,7,1
],
...
}
]
其中,矩阵(matrix)与表示平移(translation),旋转(rotation),缩放(scale)的矩阵之间,存在如下关系:
matrix = translation * rotation * scale
node还可以包含三维几何(mesh)和相机(camera)的信息。在渲染中,这些信息与上述变换矩阵相乘,就可以确定在场景中的位置。
"nodes": [
{
"mesh": 4,
...
},
{
"camera": 2,
...
},
]
3. meshes
三维几何(meshes)中可以包含多个片元(primitives)。 片元(primitives)包含了渲染需要信息。片元(primitives)中包含的信息如下:
字段 | 含义 |
---|---|
mode | 表示几何类型。如点(POINTS),线(LINES) , 或者三角形(TRIANGLES) |
attributes | 表示几何顶点信息。如位置(POSITION)和法线(NORMAL) |
indices | 表示几何顶点索引 |
material | 表示材质信息 |
三维几何(meshes)的例子如下:
"meshes": [
{
"primitives": [
{
"mode": 4,
"indices": 0,
"attributes": {
"POSITION": 1,
"NORMAL": 2
},
"material": 2
}]
}]
4. buffers, bufferViews, accessors
buffers包含了场景的几何数据,bufferViews是对buffers中数据的索引,accessors为bufferViews中的数据添加类型和布局。
4.1 buffers
buffers包含了场景的几何数据,一般是二进制数据的形式。buffers包含的字段如下:
字段 | 含义 |
---|---|
byteLength | 表示二进制数据的长度。 |
uri | 指向二进制数据的地址 |
二进制的几何数据有两种方式存储:一种是通过 base64的压缩后存入gltf文件中,此时字段uri的内容如下:
"buffers" : [
{
"byteLength" : 827640,
"uri" : "data:application/gltf-buffer;base64,AAAB..."
}
]
另一种单独存入以.bin为后缀名的文件中,然后以链接文件的方式接入gltf。此时字段uri的内容如下:
"buffers": [
{
"byteLength": 827640,
"uri": "gltf.bin"
}
]
4.2 bufferViews
bufferViews指向buffers中数据的一个片段。 bufferViews包含的字段如下:
字段 | 含义 |
---|---|
buffer | 表示一个二进制数据块,该块中存储了场景中的几何信息。 |
byteOffset | 表示相对buffer块起始位置的偏移。 |
byteLength | 表示了二进制数据的长度。 |
byteStride | 表示数据之间的间隔。 |
target | 表示opengl缓冲区的类型,如ARRAY_BUFFER,ELEMENT_ARRAY_BUFFER。 |
bufferViews的例子如下:
"bufferViews": [
{
"buffer": 0,
"byteOffset": 4,
"byteLength": 28,
"byteStride": 12,
"target": 34963
}]
4.3 accessors
accessors定义了bufferViews中的数据如何解释。accessors包含的字段如下:
字段 | 含义 |
---|---|
bufferViews | 指向一段二进制数据。 |
byteOffset | 表示相对bufferViews起始位置的偏移。 |
type | 表示数据类型,如"SCALAR","VEC2","MAT3"等。 |
componentType | 表示分量的数据类型,如unsigned short,float等。 |
count | 表示分量的个数。 |
min | 表示分量的最小值。数组的长度必须与分量的个数相同。 |
max | 表示分量的最大值。数组的长度必须与分量的个数相同。 |
accessors的例子如下:
"accessors": [
{
"bufferView": 0,
"byteOffset": 4,
"type": "VEC2",
"componentType": 5126,
"count": 2,
"min" : [0.1, 0.2],
"max" : [0.9, 0.8]
}]
示例
将上述三者结合起来,就可以准确的获取渲染所需的几何信息。如下图:
其中,bufferViews中的数据可以使用glBindBuffer绑定到openGL的缓冲区,accessor可以指定该缓冲区中定义了顶点的属性数据,并通过glVertexAttribPointer告诉顶点着色器(vertex shader)改如何解释和使用该缓冲区中的数据。
5. materials
材质(materials)描述物体表面的特征,它决定了渲染器该如何渲染该物体。
材质模型 Metallic-Roughness-Model 描述了物体表面材质的金属特征和粗糙程度,是gltf中默认的材质模型。其中,Metallic描述了材质的金属特征,取值在0到1之间。取值越靠近1,表示金属特征越强。Roughness则描述了材质的粗糙程度,取值在0到1之间。取值越靠近1,表示越粗糙。
5.1 pbrMetallicRoughness
材质模型Metallic-Roughness-Model是gltf默认使用的材质模型。在gltf中, 对象pbrMetallicRoughness 定义了该模型。
字段 | 含义 |
---|---|
baseColorTexture | 物体表面纹理。 |
baseColorFactor | 颜色RGBA。没有纹理时,该项定义了物体表面颜色。 |
metallicRoughnessTexture | 在颜色的blue分量中,存储了金属程度。在颜色的green分量中,存储了粗糙程度。 |
metallicFactor | 金属程度因子。 |
roughnessFactor | 粗糙程度因子。 |
pbrMetallicRoughness的例子如下:
"materials": [
{
"pbrMetallicRoughness": {
"baseColorTexture": {
"index": 1,
"texCoord": 1
},
"baseColorFactor": [ 1.0, 0.75, 0.35, 1.0 ],
"metallicRoughnessTexture": {
"index": 5,
"texCoord": 1
},
"metallicFactor": 1.0,
"roughnessFactor": 0.0
}
}]
material中通过纹理索引(index)和纹理坐标(texCoord)引用纹理。纹理索引(index)是纹理数组中元素的索引号。纹理坐标(texCoord)定义在图元(primitive)在顶点属性中。
6. cameras
有两种类型的相机:透视投影相机和正交投影相机。
6.1 perspective cameras
透视投影相机(perspective cameras)的定义如下:
字段 | 含义 |
---|---|
aspectRatio | 裁剪面的宽高比 |
yfov | 垂直夹角。可视空间顶面和底面的夹角。 |
zfar | 远裁剪面的位置 |
znear | 近裁剪面的位置 |
透视投影相机(perspective cameras)的示例如下:
"cameras": [
{
"type": "perspective",
"perspective": {
"aspectRatio": 1.5,
"yfov": 0.65,
"zfar": 100,
"znear": 0.01
}
}]
6.2 orthographic cameras
正交投影相机(orthographic cameras)的定义如下:
字段 | 含义 |
---|---|
xmag | 裁剪面宽度的1/2 |
ymag | 裁剪面高度的1/2 |
zfar | 远裁剪面的位置 |
znear | 近裁剪面的位置 |
正交投影相机(orthographic cameras)的示例如下:
"cameras": [
{
"type": "orthographic",
"orthographic": {
"xmag": 1.0,
"ymag": 1.0,
"zfar": 100,
"znear": 0.01
}
}]
7. textures, images, samplers
7.1 textures
材质(materials)中可以使用纹理(textures)指定物体表面的颜色和物理特征。纹理(textures)的定义的字段如下:
字段 | 含义 |
---|---|
source | 图片(images)数组的索引。 |
sampler | 采样器(samplers)数组的索引。 |
纹理(textures)的示例如下:
"textures": [
{
"source": 4,
"sampler": 2
}]
7.2 images
图片(images)的格式为jpg/png等,在纹理(texture)中引用。图片(images)有两种存储方式:
一种是通过base64的压缩成字符串,存入gltf;
"images": [
{
"uri": "data:image/png;base64,iVBORw0K..."
}
]
另一种以链接文件的方式接入gltf。
"images": [
{
"uri": "image01.png"
}
]
7.3 samplers
采样器(samplers)定义了图片放大或缩小时,如何获取颜色信息,类似于opengl中的设置纹理参数的函数glTexParameter。
采样器(samplers)定义的字段如下:
字段 | 含义 |
---|---|
magFilter | 纹理放大时,如何获取像素颜色。取值有Nearest或Linear |
minFilter | 纹理缩小时,如何获取像素颜色。取值有Nearest或Linear |
wrapS | 如何填充纹理图像左侧或右侧的区域。 |
wrapT | 如何填充纹理图像上方或下方的区域。 |
采样器(samplers)的示例如下:
"samplers": [
{
"magFilter": 9729,
"minFilter": 9987,
"wrapS": 10497,
"wrapT": 10497
}]