3dtiles 翻译

Introduction

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

 

3dtiles 翻译_第1张图片

 

为了支持规律划分的地形、不与经度或纬度线对其的城市以及任意的点云等各种数据集的紧凑的体积,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个特征(模型)。

3dtiles 翻译_第2张图片

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

 

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

 

 

 

 

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

 

 

 

3dtiles 翻译_第3张图片

 

 

 

 

 

 

 

 

 

 

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 Matrix4 和 Matrix3 类型。

 

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),考虑:

3dtiles 翻译_第4张图片

 

每个tile计算的变换是:

  • TO: [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,应该在其他任何变换解压缩。

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

  • TO: [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 tileset 和 demo 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)。

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

 

 

 

3dtiles 翻译_第5张图片

 

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]。

3dtiles 翻译_第6张图片

 

Bounding volume spatial coherence

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

3dtiles 翻译_第7张图片

地形瓦片的包围球体

3dtiles 翻译_第8张图片

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

 

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 树被创建。随着树的层级的增加,分裂轴通常循环旋转,分裂平面可以采用中位数分裂,表面积探索、或其他的方式。

3dtiles 翻译_第9张图片

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

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

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

 

 

 

Quadtrees

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

3dtiles 翻译_第10张图片

典型的四叉树细分

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

3dtiles 翻译_第11张图片

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

 

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

3dtiles 翻译_第12张图片

 

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

3dtiles 翻译_第13张图片

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

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

 

 

 

3dtiles 翻译_第14张图片

 

Octrees

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

 

3dtiles 翻译_第15张图片

 

典型的八叉树细分

 

以下是精细化点云的非均匀八叉树细分。该点云在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

3dtiles 翻译_第16张图片

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

 

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
    • Can I use 3D Tiles today?
    • Are 3D Tiles specific to Cesium?
    • What is the relationship between 3D Tiles and glTF?
    • Do 3D Tiles support runtime editing?
    • Will 3D Tiles include terrain?
    • Will 3D Tiles include imagery?
    • Will 3D Tiles replace KML?
  • Technical Q&A
    • How do 3D Tiles support heterogeneous datasets?
    • Will tileset.json be part of the final 3D Tiles spec?
    • How do I request the tiles for Level n?
    • Will 3D Tiles support horizon culling?
    • Is screen-space error the only metric used to drive refinement?
    • How are cracks between tiles with vector data handled?
    • When using replacement refinement, can multiple children be combined into one request?
    • How can additive refinement be optimized?
    • What compressed texture formats do 3D Tiles use?

General Q&A

Can I use 3D Tiles today?

We expect the initial 3D Tiles spec to evolve until fall 2016. If you are OK with things changing, then yes, jump in.

Are 3D Tiles specific to Cesium?

No, 3D Tiles are a general spec for streaming massive heterogeneous 3D geospatial datasets. The Cesium team started this initiative because we need an open format optimized for streaming 3D content to Cesium. AGI, the founder of Cesium, is also developing tools for creating 3D Tiles. We expect to see other visualization engines and conversion tools use 3D Tiles.

What is the relationship between 3D Tiles and glTF?

glTF, the runtime asset format for WebGL, is an open standard for 3D models from Khronos (the same group that does WebGL and COLLADA). Cesium uses glTF as its 3D model format, and the Cesium team contributes heavily to the glTF spec and open-source COLLADA2GLTF converter. We recommend using glTF in Cesium for individual assets, e.g., an aircraft, a character, or a 3D building.

We created 3D Tiles for streaming massive geospatial datasets where a single glTF model would be prohibitive. Given that glTF is optimized for rendering, that Cesium has a well-tested glTF loader, and that there are existing conversion tools for glTF, 3D Tiles use glTF for some tile formats such as b3dm (used for 3D buildings). We created a binary glTF extension (KHR_binary_glTF) in order to embed glTF into binary tiles and avoid base64-encoding or multiple file overhead.

Taking this approach allows us to improve Cesium, glTF, and 3D Tiles at the same time, e.g., when we add mesh compression to glTF, it benefits 3D models in Cesium, the glTF ecosystem, and 3D Tiles.

Does 3D Tiles support runtime editing?

A common use case for 3D buildings is to stream a city dataset, color each building based on one or more properties (e.g., the building's height), and then hide a few buildings and replace them with high-resolution 3D buildings. With 3D Tiles, this type of editing can be done at runtime.

The general case runtime editing of geometry on a building, vector data, etc., and then efficiently saving those changes in a 3D Tile will be possible, but is not the initial focus. However, styling is much easier since it can be applied at runtime without modification to the 3D Tiles tree and is part of the initial work.

Will 3D Tiles include terrain?

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).

However, since Cesium already streams terrain well, we are not focused on this in the short-term.

Will 3D Tiles include imagery?

Yes, there is an opportunity to provide an optimized base layer of terrain and imagery (similar to how a 3D model contains both geometry and textures). There is also the open research problem of how to tile imagery for 3D. In 2D, only one LOD (z layer) is used for a given view. In 3D, especially when looking towards the horizon, tiles from multiple LODs are adjacent to each other. How do we make the seams look good? This will likely require tool and runtime support.

As with terrain, since Cesium already streams imagery well, we are not focused on this in the short-term.

Will 3D Tiles replace KML?

In many cases, yes. KML regions and network links are a clunky approach to streaming massive 3D geospatial datasets on the web. 3D Tiles are built for the web and optimized for streaming; true HLOD is used; polygons do not need to be triangulated; and so on.

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

  • Erik Andersson
  • Sarah Chow
  • Kevin Ring
  • Dylan Brown
  • Leesa Fini

Data credits

The screenshots in this spec use awesome CyberCity3D buildings and the Bing Maps base layer.

 

 

你可能感兴趣的:(3d)