同学们,肯定会觉得博主本人最近更新很慢,越来越佛学,逐渐躺平。只能说工作榨干了我。有点时间我就想着收集点资料写些什么,在我看来一个GISER一定要成系统的理论或者说系统学习的思维。在此我刚好晚上收集些资料,关于三维数据格式的系统介绍,在此和大家分享。

1、引言

如果问现在开源社区最火热的三维GIS引擎是什么?那答案一定是Cesium!得益于良好的架构设计,使得Cesium能够同时承载多源异构的三维GIS数据。其中,Cesium中的所有三维数据都以3D Tiles的格式进行组织和调度。了解3D Tiles的格式细节,能够帮助开发者了解Cesium的调度机制,从而在使用Cesium过程中更加得心应手。

本文将对3D Tiles的格式做非常详细的分析,尽可能帮助读者了解3D Tiles的方方面面。以下将先对3D Tiles做一个整体介绍,然后分别对四种不同的瓦片文件进行单独地说明。

2、3D Tiles总览

前面说过,三维GIS数据是多源异构的,常见的就有:倾斜摄影模型、点云模型、人工模型和BIM模型。每张数据都有自己的特点:

  • 倾斜摄影模型范围大,整体数据量也大

  • 点云模型没有网格,都是稀疏的点

  • 人工模型网格比较稀疏,可是纹理特别多

  • BIM模型范围小,但是对象特别多

如果希望三维引擎能够承载这些各自特点鲜明的数据,最好能够将它们转化为一种统一的三维格式,而Cesium提出的解决方案就是3D Tiles。

图片

在深入分析3D Tiles之前,我们先来看看“3D Tiles”这个名字。“3D”很好理解,毕竟Cesium是一个三维GIS引擎。“Tiles”是瓦片的意思,每个GIS人应该都很熟悉。因此,3D Tiles就是希望成为三维GIS中的瓦片数据。

在二维地图中,瓦片是由一张一张图像组成,比如jpg、png、tif等等。与之相互呼应,3D Tiles中的瓦片也也是由一个个文件组成,不同点在于,3D Tiles中的瓦片并非是图像,而是具体的三维数据。(其实读者可以思考一下为什么?)。3D Tiles中的瓦片文件分为四种,每种瓦片的名称及应用场景如下表所示。

类型

用途

Batched3D Model (b3dm)

适用所有三维模型,包括倾斜摄影、人工和BIM

Instanced3D Model (i3dm)

实例化三维模型

Point  Cloud (pnts)

点云

Composite(cmpt)

将上述三种文件合并成一个文件,优化传输

这四种瓦片文件中只包含几何和属性数据,但对于数据量比较大的三维数据,比如倾斜摄影,我们还需要数据对应的索引,才能在渲染过程中根据视点实时调度可见的数据进行渲染。在3D Tiles中这个索引是名叫tileset.json的文件。

虽然3D Tiles有四种瓦片类型,但是其对应的json文件是一样的。这里先对json索引的结构进行介绍,再分别对四种瓦片进行说明。打开任意一个tileset.json,可以发现每一个对象基本包含如下内容:

图片

boundingVolume:对应瓦片的空间范围,可以用包围盒、包围球、区域表达。其中,包围盒和包围球对应的是三维坐标,在Cesium中就是ECEF坐标系;而区域则可以通过经纬度和高度来定义一个曲面范围,比较适用瓦片跨度比较大的情况。

图片

geometricError:控制每个瓦片的LOD显示范围,可类比osg中的pixel size。一份三维数据中,从根节点瓦片到最下层的叶节点瓦片,其geometricError会逐渐减小至0,即每个叶节点的geometricError都是0。geometricError越大,就可以在离模型越远的地方看到模型。当geometricError等于0时,只有离模型非常近的情况下才能看到模型。

refine:瓦片的LOD策略。我们在浏览倾斜摄影的时候,先看到的是上层的粗糙数据,然后我们将镜头拉近可以发现粗糙层被更加精细的模型替代。这种LOD策略叫做Replacement,即两种不同精细度的模型之间是不兼容的,同时只能看到一种。Cesium在Replacement的基础上提出Additive,就是镜头拉近之后,之前显示的模型并没有消失,而是和现在新加载的模型共存。

当然,聪明的读者肯定发现,这种策略并不适合倾斜摄影数据。那它适合什么呢?答案是BIM。考虑一个场景,我们飞在天空中远远地看着一栋建筑,这时候只能看清屋顶和墙壁,也就是建筑物的大致轮廓结构。随着距离的拉近,我们开始看到墙上的门窗、阳台等细节,但这时候墙壁和屋顶也仍然存在。Additive这种策略就是为了这种应用场景而设计的:离的远的时候,能看到很多建筑,但是每栋楼只显示屋顶和墙壁等轮廓结构;镜头拉近后视野变小,这时候就将视野中建筑物的细节展示出来。通过这种方式,即使不对模型做简化,也可以实现在有限内存情况下,对较大数据量BIM模型的流畅渲染。

图片

content:瓦片的范围和瓦片文件的uri。引擎可以根据uri找到具体的瓦片文件,然后提交渲染管线进行渲染。

children:瓦片的子节点,其类型也是tile。正是通过这种层层嵌套的结构,才构建起来HLOD(分层LOD)的树形结构,以加速渲染引擎在渲染过程中的视锥裁剪。

图片

3、B3DM文件介绍

B3DM是3D Tiles中应用最广泛的瓦片格式。一个B3DM文件的组成如下图所示。

图片

其中,前28个字节是B3DM的header,存储瓦片的一些描述信息,分别为:

  • magic:瓦片对应的标识,即"b3dm"。

  • version:瓦片的版本,现在是1。

  • byteLength:整个瓦片文件的字节数量。

  • featureTableJSONByteLength:featureTable中JSON的字节数量。

  • featureTableBinaryByteLength:featureTable中二进制块字节数量。

  • batchTableJSONByteLength:batchTable中JSON的字节数量。

  • batchTableBinaryByteLength:batchTable中二进制块字节数量。

从B3DM文件的第29个字节开始,是其Body部分,分别存储Feature Table、Batch Table和Binary glTF。其中,Feature Table存储一些数据的信息,如瓦片中顶点的数量、三角形的数量等等。Batch Table则是为了区分瓦片中各个模型而存在的,例如一个B3DM中可能包含1000个三角形,而这些三角形分别属于10个对象,则如果点击其中一个三角形查询其所属对象的属性信息,就可以通过在BatchTable中存储每个顶点所属对象的ID来实现。

图片

Body中最后一部分是glTF,即每个B3DM中都内嵌一个glTF模型,其中存储具体的顶点、法线、纹理等等。关于glTF的介绍本公众号将在后续进行更新,在此先不做展开。读者只要知道,B3DM中真正的模型都是存储在glTF中就可以。

4、I3DM文件介绍

I3DM用于存储实例化模型,即同一个模型通过旋转、平移和缩放分布在场景中的不同位置。比如,场景中有一千颗相同的树,你当然可以通过将这棵树存储1000次,但是这样就造成存储空间的浪费,而且占用GPU数据传输的带宽,影响渲染效率。相比之下,如果这个模型只存储一次,然后存储1000个4*4的变换矩阵,就同时解决上述两个问题,这就是模型实例化的目的。

图片

与B3DM相似,I3DM的文件也是有Header和Body两部分组成,其中除了magic对应的字符串改成“i3dm”之外,两者并没有区别,在此不再展开。值得一提的是,上述提到的4*4变换矩阵存储的位置是Feature Table。Cesium读取i3dm后,会根据Feature Table中存储的变换信息来做模型的实例化。

图片

5、PNTS文件介绍

PNTS文件专门用于存储点云数据,其文件组成同样分为两部分:Header和Body。不过,与B3DM和i3DM不同点在于,其Body中并没有内嵌一个glTF文件。那点云的坐标和颜色存储在哪里呢?答案是Feature Table。PNTS中将点云完全存储在Feature Table中,一方面是因为点云本身比较简单,只有坐标和颜色,没有必要用glTF这么复杂的格式去存储;另一方面,glTF本身只能存储网格模型,对点云这种离散的模型是不支持的。

图片

6、CMPT文件介绍

CMPT是一个混合文件,其存在的意义在于将上述几种文件合并成一个文件。这样做可以将一些较小的文件合并成一个大文件,从而减少文件请求的次数,提高数据在网络上传输的效率。其文件头也比较简单,只有16个字节,其中tileLength存储文件中所有瓦片加起来的字节数量,tiles中存储的是所有瓦片拼接成的二进制块。

图片

图片

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐