3dtiles 翻译

Introduction

在3dTiles中,tileset是以空间数据结构(tree,树形结构)组织的tiles集合。每个tile以一个包围体来完全封装它的内容。树(tree)具有空间一致性;子tiles的内容完全在父包围体中。为了灵活性的考虑,树可以是具有空间一致性的任何空间数据结构,包括K-D树,四叉树,八叉树以及网格。

 

 

为了支持规律划分的地形、不与经度或纬度线对其的城市以及任意的点云等各种数据集的紧凑的体积,bounding volume可以是定向的bounding box,bounding sphere或者以最小和最大经度、纬度、高程定义的地理区域。

TODO每种bounding volume类型的截图。

Tile参考一个或多个特征,比如3D模型表示的建筑或树木,点云中的点,矢量数据集合中的多边形、多边线以及点。这些特征可以批处理成简单的特征从根本上减少了客户端的加载时间和WebGL绘制调用的开销。

Tile metadata

Tile的元数据,非实际的内容,以JSON 定义,例如

{

  "boundingVolume": {

    "region": [

      -1.2419052957251926,

      0.7395016240301894,

      -1.2415404171917719,

      0.7396563300150859,

      0,

      20.4

    ]

  },

  "geometricError": 43.88464075650763,

  "refine" : "ADD",

  "content": {

    "boundingVolume": {

      "region": [

        -1.2418882438584018,

        0.7395016240301894,

        -1.2415422846940714,

        0.7396461198389616,

        0,

        19.4

      ]

    },

    "url": "2/0/0.b3dm"

  },

  "children": [...]
}

属性boundingVolume.region是长度为6的数组,它以WGS84 / EPSG:4326坐标系定义了地理区域边界,顺序是[west, south, east, north, minimum height, maximum height]。经度和纬度以弧度表示,高程表示位于WGS84椭球平面上或下的米数表示。除了region, 其他的bounding Volume,比如box和sphere可能会用到这个属性。

属性geometricError是一个非负数,以米为单位定义了由于tile渲染但是其children未被渲染引入的误差。在运行时,几何误差用于计算屏幕空间误差(Screen-Space Error ,SSE),比如以像素测量误差。SSE决定了层次细节(Hierarchical Level of Detail ,HLOD)细化,比如如果tile在当前视野下已充分细化,那么它的children应该考虑进来。

属性viewerRequestVolume是可选的(上面没有展示出来),它定义了一个volume,使用与boundingVolume相同的模式,在tile的内容被请求、基于geometricError提取, 条件是观察者必须在viewerRequestVolume之内。参见Viewer request volume段落

属性refine是字符串,要么是ADD,要么是REPLACE,ADD表示添加操作, REPLACE表示替换操作。tile集合的根tile必选,其他tile是可选的。当refine被省略,集成父tile的属性。

属性content是一个对象,它包含关于tile的内容和链接的元数据,属性content.url以绝对路径或相对路径指向tile的内容。上面的例子中,2/0/0.b3dm 是TMS分片模式,{z}/{y}/{x}.extension, 但这不是必须的,参见roadmap Q&A.

在tileset.json文件中,url用来创建tileset。参见External tilesets.

content.url的文件扩展名不是必需的。内容的tile格式可以在magic属性中确定,或作为外部tileset,如果内容是json。

content.boundingVolume 定义了可选的包围体,类似顶层的boundingVolume属性。但是与顶层的包围体属性不同的是content.boundingVolume是紧密的bounding volume封闭的是tile的内容。它用于替换操作。boundingVolume提供空间一致性,content.boundingVolume enables tight view frustum culling.下图展示了CanaryWharf的根tile,红色表示boundingVolume包围了tileset的整个区域,蓝色表示content.boundingVolume包含了根tile的4个特征(模型)。

Content是可选的。当content未被定义,tile的bounding volume仍然用于剔除。

 

属性transform是可选的,它定义了4x4仿射变换矩阵,仿射变换将Tile的content, boundingVolume,和viewerRequestVolume转换为Tile transform 章节描述的那样。

属性children是对象数组,它定义了子tiles。如下图所示

 

Coordinate System and Units

3D Tiles 使用right-handed Cartesian坐标系统,即,x、y、z的矢量积。3D Tiles定义了z轴来弥补平面笛卡尔坐标系统。Tileset的全局坐标系统通常是WGS84坐标系统,但是不是必须的,比如发电厂模型使用没有空间信息的建模工具、采用局部坐标系统来充分描述。

b3dm 和 i3dm tiles 嵌入 glTF。glTF采用right-handed坐标系统,y轴在上。默认情况下,嵌入模型被认为是Y轴向上的,但是为了支持各种元数据,包括直接以WGS84坐标系定义的模型,嵌入的 glTF模型可以使用tile.json文件中的asset.gltfUpAxis 属性定义x轴向上,y轴向上, 或 z轴向上。一般来说,在运行时,将glTF资源转为z轴向上,从而与bounding volume分层的z轴向上的坐标系统一致。

所有直线距离的单位是米。

所有角度单位是弧度。

3D Tiles不显示地存储制图坐标(经度、纬度、高程)。这些值是隐性的,在WGS84坐标系,由于不需要非仿射坐标变换,GPU可以高效地渲染。3D Tiles的tileset可以包含具体

的元数据,比如制图坐标,但是这种语义不是3D Tiles的一部分。

 

Tile transform

为支持局部坐标系统,比如,建筑tileset在城市tileset中,它有自己的坐标系统,点云tileset在建筑中,它也有自己的坐标系统,每个tile都具有可选的transform属性。

属性transform是4x4 仿射变换矩阵,以column-major order顺序存储,从Tile的局部坐标系转换为父Tile的坐标系统,或根tileset的坐标系统。

Transform属性使用于:

  1. tile.content
    1. 每个特侦的位置
    2. 每个特征的法线
  2. tile.boundingVolume
  3. tile.viewerRequestVolume

属性transform不适用于geometricError,比如,transform定义的比例不是几何误差的比例

transform未被定义,默认是单位矩阵:

[

1.0, 0.0, 0.0, 0.0,

0.0, 1.0, 0.0, 0.0,

0.0, 0.0, 1.0, 0.0,

0.0, 0.0, 0.0, 1.0

]

从每个tile的局部坐标系统转为tileset的全局坐标系统,自顶向下遍历tileset然后乘以子tile的转换矩阵,像计算机图形学中的传统场景图,或分层节点。

下面的JavaScript代码,展示了如何计算使用Cesium's Matrix4Matrix3 类型。
 

function computeTransforms(tileset) {

    var t = tileset.root;

    var transformToRoot = defined(t.transform) ? Matrix4.fromArray(t.transform) : Matrix4.IDENTITY;

    computeTransform(t, transformToRoot);
}

function computeTransform(tile, transformToRoot) {

    // Apply 4x4 transformToRoot to this tile's positions and bounding volumes

    var inverseTransform = Matrix4.inverse(transformToRoot, new Matrix4());

    var normalTransform = Matrix4.getRotation(inverseTransform, new Matrix3());

    normalTransform = Matrix3.transpose(normalTransform, normalTransform);

    // Apply 3x3 normalTransform to this tile's normals

    var children = tile.children;

    var length = children.length;

    for (var k = 0; k < length; ++k) {

        var child = children[k];

        var childToRoot = defined(child.transform) ? Matrix4.fromArray(child.transform) : Matrix4.clone(Matrix4.IDENTITY);

        childToRoot = Matrix4.multiplyTransformation(transformToRoot, childToRoot, childToRoot);

        computeTransform(child, childToRoot);

    }
}

举一个计算tileset变换的例子(上面代码中transformToRoot),考虑:

 

每个tile计算的变换是:

T0: [T0]
T1: [T0][T1]
T2: [T0][T2]
T3: [T0][T1][T3]
T4: [T0][T1][T4]

在tile变换前(在仿射变换后乘前),tile的content属性中的位置和法线也有tile-specific类似变换 。例如:

  • b3dm和i3dm瓦片嵌入glTF,它们定义了自己的节点层次,每个节点具有一个变换,这些变换在tile的变换前处理
  • i3dm的特征表定义了实例的位置,法线,和缩放。他们用于创建4x4仿射变换矩阵实例,该矩阵在tile.transform前应用于每个实例。
  • 属性压缩,比如,i3dm特征表中POSITION_QUANTIZED, pnts,vctr,pnts中的OCT16P,应该在其他任何变换解压缩。

因此,以上例子全计算变换如下

T0: [T0]
T1: [T0][T1]
T2: [T0][T2][pnts-specific Feature Table properties-derived transform]
T3: [T0][T1][T3][b3dm-specific transform, including the glTF node hierarchy]
T4: [T0][T1][T4][i3dm-specific transform, including per-instance Feature Table properties-derived transform and the glTF node hierarchy]

Viewer request volume

瓦片的viewerRequestVolume可以用于结合异构数据集,并可以与外部瓦片集结合。下面的例子包含了一份b3dm瓦片的建筑数据,以及建筑里面的pnts瓦片的的点云数据。点云瓦片的boundingVolume是半径为1.25的sphere。该点云瓦片还有一个更大的、半径为15的sphere类型的viewerRequestVolume。由于geometricError是0,当viewer在由viewerRequestVolume定义的大sphere中,点云瓦片的content才被初始请求和渲染。

 

"children": [{

  "transform": [

     4.843178171884396,   1.2424271388626869, 0,                  0,

    -0.7993325488216595,  3.1159251367235608, 3.8278032889280675, 0,

     0.9511533376784163, -3.7077466670407433, 3.2168186118075526, 0,

     1215001.7612985559, -4736269.697480114,  4081650.708604793,  1

  ],

  "boundingVolume": {

    "box": [

      0,     0,    6.701,

      3.738, 0,    0,

      0,     3.72, 0,

      0,     0,    13.402

    ]

  },

  "geometricError": 32,

  "content": {

    "url": "building.b3dm"

  }

}, {

  "transform": [

     0.968635634376879,    0.24848542777253732, 0,                  0,

    -0.15986650990768783,  0.6231850279035362,  0.7655606573007809, 0,

     0.19023066741520941, -0.7415493329385225,  0.6433637229384295, 0,

     1215002.0371330238,  -4736270.772726648,   4081651.6414821907, 1

  ],

  "viewerRequestVolume": {

    "sphere": [0, 0, 0, 15]

  },

  "boundingVolume": {

    "sphere": [0, 0, 0, 1.25]

  },

  "geometricError": 0,

  "content": {

    "url": "points.pnts"

  }

}]

TODO: screenshot showing the request vs. bounding volume

关于request volumes想了解更多, 请 参见e sample tilesetdemo video

tileset.json

tileset.json 定义了瓦片集. 下面是tileset.json的子集, 用于 Canary Wharf (tileset.json):

{

  "asset" : {

    "version": "0.0",

    "tilesetVersion": "e575c6f1-a45b-420a-b172-6449fa6e0a59",

    "gltfUpAxis": "Y"

  },

  "properties": {

    "Height": {

      "minimum": 1,

      "maximum": 241.6
    }

  },

  "geometricError": 494.50961650991815,

  "root": {

    "boundingVolume": {

      "region": [

        -0.0005682966577418737,

        0.8987233516605286,

        0.00011646582098558159,

        0.8990603398325034,

        0,

        241.6
      ]

    },

    "geometricError": 268.37878244706053,

    "content": {

      "url": "0/0/0.b3dm",

      "boundingVolume": {

        "region": [

          -0.0004001690908972599,

          0.8988700116775743,

          0.00010096729722787196,

          0.8989625664878067,

          0,

          241.6

        ]

      }

    },

    "children": [..]
  }
}

tileset.json顶级对象具有4个属性:asset,properties,geometricError, 以及root

Asset对象包含描述整个瓦片集的元数据的属性。Version属性定义了3D Tiles的版本。版本定义了tileset.json的JOSN概要、瓦片格式的基础集合 。tilesetVersion属性可选,它定义了瓦片集的应用版本,比如,当已经存在的瓦片集需要更新时使用。gltfUpAxis属性可选,它瓦片集中glTF模型的up-axis。

Properties属性是包含对象的对象,for瓦片集中每个per-feature属性。本tileset.json片段描述了3D建筑,因此每个瓦片包含了建筑模型,每个建筑模型包含了高度属性(参见 Batch Table)。属性中每个对象的名字与per-feature属性的名字匹配,定义了最小、最大的数值,这些值非常有用,举个例子,比如为样式创建颜色斜面。

geometricError定义了瓦片集不被渲染的几何误差,非负数,单位为米。

Root属性是对象,它使用上面章节描述的JSON定义了根瓦片。root.geometricError和tileset.json顶级geometricError不一样。tileset.json顶层geometricError是tileset不被渲染时的geometricError,root.geometricError是root tile渲染时的误差。

root.children 是对象数组,定义了子瓦片。每个子瓦片的boundingVolume被父瓦片的 boundingVolume完全包含,通常,它们的geometricError小于父瓦片的geometricError。对于叶子瓦片,数组的长度为0,那么children未被定义。

参见 schema 了解完整的tileset.json.

参见 Q&A below 了解 tileset.json 如何规模地描述大量的瓦片。

External tilesets

创建树的一个节点,瓦片的content.url可以指向外部的瓦片集(另外的tileset.json)。

这样可以将每个城市存在各自的瓦片集中,然后用各城市的瓦片集来组成去求的瓦片集。

 

 

When a tile points to an external tileset, the tile

当瓦片指向外部的瓦片集,瓦片

  • Cannot have any children, tile.children must be undefined or an empty array.
  • 不能拥有任何子瓦片,tile.children必须未定义或是空数组
  • 具有各种属性,匹配外部瓦片集的根瓦片:
    • root.geometricError === tile.geometricError,
    • root.refine === tile.refine, and
    • root.boundingVolume === tile.content.boundingVolume (or root.boundingVolume === tile.boundingVolume when tile.content.boundingVolume is undefined).
    • root.viewerRequestVolume === tile.viewerRequestVolume or root.viewerRequestVolume is undefined.
  • Cannot be used to create cycles, for example, by pointing to the same tileset.json containing the tile or by pointing to another tileset.json that then points back to the tileset.json containing the tile. tileset.json
  • 不能用于创建循环,例如,指向包含瓦片的相同的tileset.json,或指向另外的tileset.json这个json又指向回来
    • 瓦片的变换和根瓦片的变换均被应用。例如,下面引用外部瓦片的瓦片,T3的计算变换是[T0][T1][T2][T3]。

 

Bounding volume spatial coherence

正如以上所述,树具有空间一致性;每个瓦片具有一个包围体完全封闭它的内容,子瓦片的内容完全在父包围体中。这并不意味着子瓦片的包围体完全在父瓦片的包围体中。例如:

地形瓦片的包围球体

四个子瓦片的包围球体。子瓦片的内容完全在父瓦片的包围体中,但是子瓦片的包围体不完全在父瓦片的包围体中,因为它们不是紧包围的。

Creating spatial data structures

在tileset.json中通过root定义了树,递归,树的子节点可以定义空间数据结构的不同类型。此外,可以采用任意瓦片格式和细化方法replacement or additive)的组合,允许很大的灵活性来在支持各种各样的数据集。

         这取决于生成tileset.json转换工具,来定义数据集最优的树。运行引擎,比如Cesium,是通用的,并能渲染tileset.json定义的树。这里对3D Tiles如何表示各种空间结构进行简要说明。

K-d trees

当瓦片存在两个子瓦片 当与x, y, 或 z 轴平行的分裂面将瓦片分割成两个子瓦片时,k-d 树被创建。随着树的层级的增加,分裂轴通常循环旋转,分裂平面可以采用中位数分裂,表面积探索、或其他的方式。

K-d树举例,注意非是均匀细分

注意k-d树不具备典型的2D地理空间瓦片体系的均匀细分特点,因此,k-d树可以为稀疏和不均匀分布的数据集创建更多的平衡树。

3D Tiles允许使用k-d 树的变种,比如多路k-d树,可以使树的每个叶子节点沿轴线有多个分裂。每个瓦片不是只有两个子瓦片,而是有n个子瓦片。

Quadtrees

当每个瓦片具有4个均匀细分的子瓦片(比如,使用中心经纬度),可以创建四叉树,类似典型的二维地理空间瓦片体系。空瓦片可以删除。

典型的四叉树细分

3D Tiles允许四叉数变化,比如非均匀细分和紧包围(和包围相反,例如,父瓦片的25%,对于稀疏数据集是浪费的)。

紧包围盒包围每个瓦片的四叉树

举个例子,下面是Canary Wharf的根瓦片和子瓦片。注意底左区域,这个地方的的包围体不包括左面没有建筑的的水域,如下:

 

3D Tile也支持其他四叉树的变种,比如松散的四叉树,子瓦片重叠,但是空间一致性保持,比如,父瓦片完全封闭它的子瓦片。这种方法可以避免分裂特征,比如3d模型,交叉瓦片。

具有非均匀重叠瓦片的四叉树

下面,绿色建筑在左边子瓦片,紫色建筑在右边子瓦片。注意瓦片重叠,中心两个绿色的和一个紫色的建筑没有分裂。

 

Octrees

八叉树继承了四叉树,采用3个正交分裂平面将一个瓦片再细分成8个子瓦片。类似四叉树,3D Tiles允许采用八叉树的变种,例如非均匀细分,紧包围体,以及重叠子瓦片。

 

典型的八叉树细分

以下是精细化点云的非均匀八叉树细分。该点云在the Church of St Marie at Chappes, France 来自Prof. Peter Allen, Columbia University Robotics Lab。由Alejandro Troccoli 和 Matei Ciocarlie扫描。

Grids

3D Tiles通过支持任意数量的子瓦片来实现统一的、不统一的以及重叠的网格。举个例子,以下是剑桥的不统一重叠的网格的俯视图。

3D Tiles利用了空瓦片的优势:这些瓦片具有bounding volume,但是没有content。由于瓦片的content属性不需要定义,空的非叶子瓦片可以使用分层剔除加速非统一网格。这对创建没有分层LOD的四叉树或八叉树非常必要。

Tile formats

每个瓦片的content.url属性指向另外一个瓦片,该瓦片的格式在上面Status section列出。

瓦片集可以包含任何瓦片格式的组合。3D Tiles也支持在同一瓦片中采用Composite瓦片。

Declarative styling 声明式样式

使用声明式样式以高度着色的建筑物

3D Tiles include concise declarative styling defined with JSON and expressions written in a small subset of JavaScript augmented for styling.

Styles generally define a feature's show and color (RGB and translucency) using an expression based on a feature's properties, for example:

{
    "color" : "(${Temperature} > 90) ? color('red') : color('white')"
}

This colors features with a temperature above 90 as red and the others as white.

完整细节请参见 Declarative Styling spec.

 

Roadmap Q&A

General Q&A

今天是否可以使用3D Tiles?

我们预计最初的3D Tiles规范将发展直到2016年秋季。如果你对3D Tiles的变化没有意见,那么是的,加入进来吧。

3D Tiles Cesium专用的吗

不,3D Tiles是一种通用的规范,用于流式传输大量异构的3D地理空间数据集。Cesium 团队启动这项计划是因为我们需要一种开放格式,用于将3D内容流式传输到Cesium 。Cesium 的创始人AGI也在开发制作 3D Tiles的工具。我们希望看到其他可视化引擎和转换工具使用3D Tiles。

3D Tiles 与glTF的关系?

glTF是WebGL的运行时资产格式,是Khronos(与WebGL和COLLADA相同的组)的3D模型的开放标准。Cesium使用glTF作为其3D模型格式,Cesium团队为glTF规范和开源COLLADA2GLTF转换器做出了重大贡献。我们建议将Cesium中的glTF用于个人资产,例如飞机、人物角色或3D建筑。

我们创建了用于流式传输大量地理空间数据集的 3D Tiles,其中单个glTF模型将是禁止的。考虑到glTF对渲染进行了优化,Cesium有一个经过良好测试的glTF加载程序,并且存在glTF的现有转换工具,3D Tiles将glTF用于一些瓦片格式,例如 b3dm (用于3D建筑)。我们创建了一个二进制glTF扩展名(KHR_binary_glTF),以便将glTF嵌入到二进制分片中并避免base64编码或多文件开销。

采用这种方法可以同时改进Cesium、glTF和3D Tiles,例如,当我们向glTF添加mesh 压缩时,它有利于Cesium、glTF生态系统和3DTiles中的3D模型。

3D Tiles 是否支持运行时编辑?

3D建筑的一个常见用例是流式处理城市数据集,根据一个或多个属性(例如,建筑的高度)为每个建筑着色,然后隐藏一些建筑并用高分辨率的3D建筑替换它们。使用三维分幅,这种类型的编辑可以在运行时完成。

一般情况下,可以在运行时编辑建筑物上的几何图形、矢量数据等,然后将这些更改有效地保存在三维平铺中,但这不是最初的重点。但是,样式设置要容易得多,因为它可以在运行时应用,而无需修改3D Tiles树,并且是初始工作的一部分。

Will 3D Tiles include terrain?3DTiles 会包括地形吗?

Yes, a quantized-mesh-like tile would fit well with 3D Tiles and allow Cesium to use the same streaming code (we say quantized-mesh-like because some of the metadata, e.g., for bounding volumes and horizon culling, may be organized differently or moved to tileset.json).

是的,一个 quantized-mesh-like (量化网状)瓦片很适配3D Tiles,并允许Cesium 使用相同的流代码(我们称之为quantized-mesh-like,因为一些元数据,例如,用于包围盒和地平线剔除的元数据,可能会以不同的方式组织或移到tileset.json)。

然而,由于Cesium 已经很好地流动了,我们在短期内不关注这一点。

3D Tiles 会包括影像吗?

是的,有机会提供地形和图像的优化基础层(类似于3D模型如何同时包含几何体和纹理)。还有一个开放的研究问题,即如何为3D图像平铺。在2D中,给定视图仅使用一个LOD(z层)。在3D中,尤其是朝地平线看时,来自多个LOD的瓷砖彼此相邻。我们如何使接缝看起来好看?这可能需要工具和运行时支持。

像地形那样,由于Cesium 已经很好地流影像了,我们在短期内不关注这一点。

3D Tiles 会取代KML吗?

在很多情况下,是的。KML区域和网络链接是在web上传输大量三维地理空间数据集的笨拙方法。为web构建3D Tiles ,并针对流媒体进行优化;使用真实HLOD;多边形不需要三角剖分;等等。

 

Technical Q&A

How do 3D Tiles support heterogeneous datasets?

Geospatial datasets are heterogeneous: 3D buildings are different from terrain, which is different from point clouds, which are different from vector data, and so on.

3D Tiles support heterogeneous data by allowing different tile formats in a tileset, e.g., a tileset may contain tiles for 3D buildings, tiles for instanced 3D trees, and tiles for point clouds, all using different tile formats.

3D Tiles also support heterogeneous datasets by concatenating different tile formats into one tile using the Composite tile format. In the example above, a tile may have a short header followed by the content for the 3D buildings, instanced 3D trees, and point clouds.

Supporting heterogeneous datasets with both inter-tile (different tile formats in the same tileset) and intra-tile (different tile formats in the same Composite tile) options allows conversion tools to make trade-offs between number of requests, optimal type-specific subdivision, and how visible/hidden layers are streamed.

Will tileset.json be part of the final 3D Tiles spec?

Yes. There will always be a need to know metadata about the tileset and about tiles that are not yet loaded, e.g., so only visible tiles can be requested. However, when scaling to millions of tiles, a single tileset.json with metadata for the entire tree would be prohibitively large.

3D Tiles already support trees of trees. content.url can point to another tileset.json, which enables conversion tools to chunk up a tileset into any number of tileset.json files that reference each other.

There's a few other ways we may solve this:

  • Moving subtree metadata to the tile payload instead of tileset.json. Each tile would have a header with, for example, the bounding volumes of each child, and perhaps grandchildren, and so on.
  • Explicit tile layout like those of traditional tiling schemes (e.g., TMS's z/y/x). The challenge is that this implicitly assumes a spatial subdivision, whereas 3D Tiles are general enough to support quadtrees, octrees, k-d trees, and so on. There is likely to be a balance where two or three explicit tiling schemes can cover common cases to complement the generic spatial data structures.

How do I request the tiles for Level n?

More generally, how do 3D Tiles support the use case for when the viewer is zoomed in very close to terrain, for example, and we do not want to load all the parent tiles toward the root of the tree; instead, we want to skip right to the high-resolution tiles needed for the current 3D view?

This 3D Tiles topic needs additional research, but the answer is basically the same as above: either the skeleton of the tree can be quickly traversed to find the desired tiles or an explicit layout scheme will be used for specific subdivisions.

Will 3D Tiles support horizon culling?

Since horizon culling is useful for terrain, 3D Tiles will likely support the metadata needed for it. We haven't considered it yet since our initial work with 3D Tiles is for 3D buildings where horizon culling is not effective.

Is Screen-Space Error the only metric used to drive refinement?

At runtime, a tile's geometricError is used to compute the Screen-Space Error (SSE) to drive refinement. We expect to expand this, for example, by using the Virtual Multiresolution Screen Space Error (VMSSE), which takes occlusion into account. This can be done at runtime without streaming additional tile metadata. Similarly, fog can also be used to tolerate increases to the SSE in the distance.

However, we do anticipate other metadata for driving refinement. SSE may not be appropriate for all datasets; for example, points of interest may be better served with on/off distances and a label collision factor computed at runtime. Note that the viewer's height above the ground is rarely a good metric for 3D since 3D supports arbitrary views.

See #15.

How are cracks between tiles with vector data handled?

Unlike 2D, in 3D, we expect adjacent tiles to be from different LODs so, for example, in the distance, lower resolution tiles are used. Adjacent tiles from different LODs can lead to an artifact called cracking where there are gaps between tiles. For terrain, this is generally handled by dropping skirts slightly angled outward around each tile to fill the gap. For 3D buildings, this is handled by extending the tile boundary to fully include buildings on the edge; see above. For vector data, this is an open research problem that we need to solve. This could invole boundary-aware simplification or runtime stitching.

When using replacement refinement, can multiple children be combined into one request?

Often when using replacement refinement, a tile's children are not rendered until all children are downloaded (an exception, for example, is unstructured data such as point clouds, where clipping planes can be used to mask out parts of the parent tile where the children are loaded; naively using the same approach for terrain or an arbitrary 3D model results in cracking or other artifacts between the parent and child).

We may design 3D Tiles to support downloading all children in a single request by allowing tileset.json to point to a subset of a file for a tile's content similiar to glTF buffer and bufferView. HTTP/2 will also make the overhead of multiple requests less important.

See #9.

How can additive refinement be optimized?

Compared to replacement refinement, additive refinement has a size advantage because it doesn't duplicate data in the original dataset. However, it has a disadvantage when there are expensive tiles to render near the root and the view is zoomed in close. In this case, for example, the entire root tile may be rendered, but perhaps only one feature or even no features are visible.

3D Tiles can optimize this by storing an optional spatial data structure in each tile. For example, a tile could contain a simple 2x2 grid, and if the tile's bounding volume is not completely inside the view frustum, each box in the grid is checked against the frustum, and only those inside or intersecting are rendered.

See #11.

What compressed texture formats do 3D Tiles use?

3D Tiles will support the same texture compression that glTF will support. In addition, we need to consider how well GPU formats compress compared to, for example, jpeg. Some desktop game engines stream jpeg, then decompress and recompress to a GPU format in a thread. The CPU overhead for this approach may be too high for JavaScript and Web Workers.

Acknowledgments致谢

Data credits 数据信用

本规范中的截图采用了awesome CyberCity3D 建筑数据以及 Bing Maps 基础图层。

 

 

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风的心愿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值