批处理三维模型
开发人员
Patrick Cozzi, @pjcozzi
Tom Fili, @CesiumFili
翻译
- ChrisWang, @ecnuzlwang
概况
批处理三维模型(Batched 3D Model) 支持离线批处理异质三维模型(比如城市中的建筑物),能高效地流化到网络客户端进行渲染和交互。高效的原因是:它将大量模型转换成单个请求,然后在尽量少的WebGL绘制命令下渲染。使用3D Tiles规范的核心语言,每个模型都是一个要素。
单个模型的属性(如ID)使得每个模型在应用运行时能被辨认和更新(控制显隐和高亮颜色等操作)。属性可以用于查询一个网络服务,来获取元数据,比如用建筑物的ID获取它的地址。或者通过一个属性实时地改变模型的样式,比如通过属性值改变模型高亮颜色。
批处理三维模型(简称batch)是一个小字节序(little endian)的二进制大对象(binary blob)以ArrayBuffer的类型传入JavaScript。
格式
一个瓦片由两部分组成:一个文件头(header),和一个紧随其后的文件体(body)。
图1:批处理三维模型格式(虚线代表可选填部分)
文件头
文件头有20个字节,包含以下字段:
字段名 |
数据类型 |
描述 |
magic |
4-byte ANSI string |
"b3dm". 该字段表明该arraybuffer是批处理三维模型瓦片 |
version |
uint32 |
批处理三维模型格式的版本号。现在是1。 |
byteLength |
uint32 |
整个瓦片的大小,包括头文件,以byte为单位。 |
batchLength |
unit32 |
在瓦片中的要素数量,也就是模型个数 |
batchTableByteLength |
uint32 |
Batch Table的大小(字节),0就代表没有表格 |
TODO: Link to Cesium code for reading header
文件体紧跟文件头,由 Batch Table 和 Binary glTF两个部分组成。
Batch Table
在二进制glTF部分,每个节点都分配了一个短的batchId 属性,范围在0到模型数量减1之间。batchId 指示该节点属于哪个模型。这使得模型能被批量处理,也可以被单独识别。
batch table将每个batchId 映射到每个模型的属性上。Batch
table(如果存在的话)紧跟文件头,长度和batchTableByteLength 记录的字节数相等。
batch table是一个UTF-8 编码的JSON格式字符串。可以通过JavaScript
API中的TextDecoder 提取出来,再用JSON.parse转换成JavaScript 对象。
batch
table对象里的每个属性都是一个长度为header.batchLength的数组。数组中的元素可以是任何有效的JSON数据类型,包括对象和数组。元素也可以是null。
节点的batchId 用于匹配每个数组中的元素,提取出对应的属性。比如,下面的batch table包含两个模型的属性信息。
{
"id" : ["unique id", "another unique id"],
"displayName" : ["Building name", "Another building name"],
"yearBuilt" : [1999, 2015],
"address" : [{"street" : "Main Street", "houseNumber" : "1"}, {"street" : "Main Street", "houseNumber" : "2"}]
}
batchId = 0 的模型的属性是:
id[0] = 'unique id';
displayName[0] = 'Building name';
yearBuilt[0] = 1999;
address[0] = {street : 'Main Street', houseNumber : '1'};
batchId = 1 的是:
id[1] = 'another unique id';
displayName[1] = 'Another building name';
yearBuilt[1] = 2015;
address[1] = {street : 'Main Street', houseNumber : '2'};
二进制 glTF
glTF 是WebGL的运行资产格式。Binary
glTF 是将glTF定义在二进制容器中的拓展模块。批处理三维模型使用KHR_binary_glTF处理glTF
1.0的模型。
二进制glTF在b3dm文件中的位置是在batch
table的后面。在arraybuffer中的位置是从头开始第12 +
batchTableByteLength个字节往后的内容。它可以将图形,材质和动画全都嵌入内容中,也可以对部分或者全部内容索引外部文件资源。
上文提到过,每个节点都有一个batchId 属性指示节点属于哪个模型。举个例子,三个模型的节点数据如下所示(这应该是arraybuffer对象中的样式):
batchId: [0, 0, 0, ..., 1, 1, 1, ..., 2, 2, 2, ...]
position: [xyz, xyz, xyz, ..., xyz, xyz, xyz, ..., xyz, xyz, xyz, ...]
normal: [xyz, xyz, xyz, ..., xyz, xyz, xyz, ..., xyz, xyz, xyz, ...]
节点不需要按照batchId 的顺序排列,所以下面的样式也是可以的:
batchId: [0, 1, 2, ..., 2, 1, 0, ..., 1, 2, 0, ...]
position: [xyz, xyz, xyz, ..., xyz, xyz, xyz, ..., xyz, xyz, xyz, ...]
normal: [xyz, xyz, xyz, ..., xyz, xyz, xyz, ..., xyz, xyz, xyz, ...]
需要注意的是一个节点不能够对应多个模型,如果需要的话,需要复制节点,然后分配不同的batchId。
batchId 由glTF技术参数语言(glTF technique parameter
semantic) BATCHID定义(在b3dm文件中glTF部分)。在顶点着色器中属性名为a_batchId,声明语句如下:
attribute float a_batchId;
在运行时可以用a_batchId获取batch中的单个模型,借此实时修改顶点着色器,比如修改节点颜色。
如果模型存在Batch
Table,则 a_batchId
属性(包括glTF参数语言中的BATCHID)是必须填写的;否则就可以省略。
虽然没有硬性要求,客户端在高精度渲染过程中会发现CESIUM_RTC 拓展模块非常有用。
文件扩展名
.b3dm
MIME Type
*TODO, *#60
application/octet-stream
致谢
- Jannes Bolling, \@jbo023