-
Notifications
You must be signed in to change notification settings - Fork 503
Add 3DTILES_content_gltf_vector
#838
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
55bef8d
71becab
086970b
e80f311
b87059f
e15238b
34e0895
c48ebdc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,161 @@ | ||
| <!-- omit in toc --> | ||
|
|
||
| # 3DTILES_content_gltf_vector | ||
|
|
||
| <!-- omit in toc --> | ||
|
|
||
| ## Contributors | ||
|
|
||
| - Björn Blissing, [@bjornblissing](https://github.com/bjornblissing) | ||
| - Xuan Huang, [@xuanhuang1](https://github.com/xuanhuang1) | ||
| - Sean Lilley, [@lilleyse](https://github.com/lilleyse) | ||
| - Don McCurdy, [@donmccurdy](https://github.com/donmccurdy) | ||
| - Adam Morris, [@weegeekps](https://github.com/weegeekps) | ||
| - Daniel Zhong, [@danielzhong](https://github.com/danielzhong) | ||
|
|
||
| <!-- omit in toc --> | ||
|
|
||
| ## Status | ||
|
|
||
| Draft | ||
|
|
||
| <!-- omit in toc --> | ||
|
|
||
| ## Dependencies | ||
|
|
||
| Written against the 3D Tiles 2.0 specification. | ||
|
|
||
| <!-- omit in toc --> | ||
|
|
||
| ## Optional vs. Required | ||
|
|
||
| This extension is always optional. It should be placed in the tileset JSON `extensionsUsed` list, but not in the `extensionsRequired` list. | ||
|
|
||
| <!-- omit in toc --> | ||
|
|
||
| ## Contents | ||
|
|
||
| - [Overview](#overview) | ||
| - [Extending 3D Tiles content](#extending-3d-tiles-content) | ||
| - [Points](#points) | ||
| - [Polylines](#polylines) | ||
| - [Polygons](#polygons) | ||
| - [Bounding volumes and clipping](#bounding-volumes-and-clipping) | ||
| - [Feature IDs and Properties](#feature-ids-and-properties) | ||
| - [Visualization](#visualization) | ||
| - [Schema](#schema) | ||
| - [Implementation Examples](#implementation-examples) | ||
|
|
||
| ## Overview | ||
|
|
||
| Applied to geospatial domains, the term “vector data” refers to geometric topologies: points in 2D or 3D coordinate systems; polylines connecting a series of points; or polygons having a closed, exterior loop of points, optionally with additional interior loops defining holes in the polygon. The term "vector data" exists in contrast to “raster data”, which stores pixel grids in image-like formats, rather than discrete geometric types. | ||
|
|
||
| Extending the concept of vector data into the domain of graphics APIs, and of 3D scenes already composed of graphics primitives — such as points, lines, triangles — this extension proposes and defines an additional distinction: “vector data” comprises point, polyline, and polygon geometries with intrinsic semantic meaning, but without intrinsic rendering intent. | ||
|
|
||
| > [!NOTE] | ||
| > Unlike typical glTF geometry, vector data geometry does not directly convey rendering intent. Vector data is a vehicle for topology or for associated properties. Points may be aggregated, clustered, or used as anchors for labels. Lines may be widened, dashed, or used as an invisible track for animation. Polygons may be outlined, extruded, subtracted from existing scene geometry, or used to define an abstract area of analysis. | ||
|
|
||
| Working from the definition above, this extension proposes a mechanism for encoding vector point, line, and polygon data in 3D Tiles using glTF content, and for distinguishing such vector data from general glTF content. The extension further refines tile and content bounding volumes as needed to support seamless tiled vector rendering in a variety of visual styles. | ||
|
|
||
| ## Extending 3D Tiles content | ||
|
|
||
| A `content` definition, containing a reference URL or template URL to glTF content, may be extended with the `3DTILES_content_gltf_vector`. The extension's boolean property, `vector: true`, indicates that the glTF content of the tile SHOULD be interpreted as vector data. The value of the `vector` property MUST be `true`; for non-vector content the extension is omitted. | ||
|
|
||
| ```jsonc | ||
| { | ||
| ... | ||
| "extensionsUsed": [ "3DTILES_content_gltf_vector" ], | ||
| "root": { | ||
| ... | ||
| "content": { | ||
| "uri": "content/{level}/{x}/{y}.glb", | ||
| "extensions": { | ||
| "3DTILES_content_gltf_vector": { "vector": true } | ||
| } | ||
| } | ||
| ... | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| Interpretation of glTF content as particular vector types is explained further in the following sections. See [points](#points), [polylines](#polylines), and [polygons](#polygons). | ||
|
|
||
| Requirements for bounding volumes on glTF vector content may differ from other 3D Tiles content types. See [Bounding volumes and clipping](#bounding-volumes-and-clipping). | ||
|
|
||
| ## Points | ||
|
|
||
| glTF mesh primitives having `primitive.mode = 0` ("POINTS") SHOULD be interpreted as vector point topologies. Authoring tools SHOULD encode multiple point features within the same glTF mesh primitive, to improve file size and rendering efficiency. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What constitutes a “feature” for points?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All good questions, thanks! After re-reading this, I believe perhaps the word "feature" should be avoided here and elsewhere in this extension, except under the "Feature IDs and Properties" non-normative section below. Instead we should use the terms like "point geometries" or "point topological primitives", as distinct from glTF mesh primitives. To your questions, though, the intention is that feature membership is defined separately by KHR_mesh_features. Vertex/feature mappings may be 1:1, 1:N, N:1, or N:N. But certainly the most common would be 1:1, or N:1 (e.g. many vertices share the same |
||
|
|
||
| ## Polylines | ||
|
|
||
| glTF mesh primitives having `primitive.mode = 3` ("LINE_STRIP") SHOULD be interpreted as vector polyline topologies. Authoring tools SHOULD encode multiple polyline features within the same glTF mesh primitive, separated by primitive restart values using `KHR_mesh_primitive_restart`, to improve file size and rendering efficiency. | ||
|
|
||
| ## Polygons | ||
|
|
||
| glTF mesh primitives in drawing mode `primitive.mode = 4` ("TRIANGLES"), using extension [`EXT_mesh_polygon`](https://github.com/KhronosGroup/glTF/pull/2570) SHOULD be interpreted as vector polygon topologies. Authoring tools SHOULD encode multiple polygon features within the same glTF mesh primitive, to improve file size and rendering efficiency. | ||
|
|
||
| ## Bounding volumes and clipping | ||
|
|
||
| When the `3DTILES_content_gltf_vector` extension is attached to a glTF `content` definition, a boolean `clip` property may optionally be included, defaulting to `false`: | ||
|
|
||
| ```jsonc | ||
| "content": { | ||
| "uri": "content/{level}/{x}/{y}.glb", | ||
| "extensions": { | ||
| "3DTILES_content_gltf_vector": { | ||
| "vector": true, | ||
| "clip": true | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| When `true`, a default 3D Tiles requirement is modified: `content.boundingVolume` is no longer required to be fully contained within `tile.boundingVolume`. | ||
|
|
||
| Client implementations SHOULD visually "clip" this content at the limits of `tile.boundingVolume`. Overflow of content outside the tile bounding volume is referred to as a "buffer" region. | ||
|
|
||
| The buffer region is provided to mitigate seams and discontinuities at tile boundaries. For polylines and polygons crossing tile boundaries and rendered with certain visual styles — particularly "wide" lines or outlines — display in tile A may be affected by the continuation of the same geometry a short distance ("buffer") into tile B. By clipping precisely at the tile boundary, sections of the geometry in tile B may still influence display within tile A, without duplicate rendering and/or z-fighting in tile B. | ||
|
|
||
| <p> | ||
| <img alt="Vector Tiles and Contents" src="./figures/vector_tiles_and_contents.png"/> | ||
| </p> | ||
|
|
||
| > [!NOTE] | ||
| > Clipping may be implemented by pre-processing geometry, by discarding fragments in a pixel shader, or by any other means. For typical vector visual styles (involving, for example, wide lines), it is expected that most implementations will implement clipping in the fragment shader (or equivalent), in order to preserve the influence of geometry just outside the tile boundary on lines or outlines crossing the tile boundary. | ||
|
|
||
| > [!NOTE] | ||
| > To avoid visual artifacts, client implementations would (in the absence of "buffer" region data) need to connect geometries in each tile to their corresponding geometries in adjacent tiles. Such mapping and reconstruction at runtime, while not prohibited, is often impractical for realtime implementations. Overlapping buffers at tile boundaries are included in 3D Tiles as an alternative. | ||
|
|
||
| As a result, `content.boundingVolume` may extend arbitrarily outside of `tile.boundingVolume`. Client implementations SHOULD implement LOD selection and tile visibility based on the tile bounding volume, not the (potentially larger) content bounding volume; tile visibility is unchanged as compared to non-vector data. Authoring implementations SHOULD include content extending _outside_ the tile bounding volume only to the extent that such content is likely to influence visualization _inside_ the tile bounding volume. | ||
|
|
||
| > [!NOTE] | ||
| > A small buffer region, representing a single-digit percentage of a tile's width, is expected to be sufficient for most rendering styles. Client implementations may choose to limit line widths to the widths of tile buffers, in screen space or world space, to avoid visual artifacts. | ||
|
|
||
| > [!NOTE] | ||
| > Point geometries do not typically require buffer regions or clipping at tile boundaries for proper rendering, but authoring and client implementations are not prohibited from doing either. | ||
|
|
||
| ## Feature IDs and Properties | ||
|
|
||
| _This section is non-normative._ | ||
|
|
||
| Point, polyline, and polygon geometries are often associated with other geometries comprising a single conceptual feature. Polyline and polygon geometries may also be cut across neighboring tiles during the tiling process. In such cases, `EXT_mesh_features` and `EXT_structural_metadata` may be used to reference and store properties associated with vector features. Global unique IDs, stored as columns in `EXT_structural_metadata`, may be used to allow features split across multiple tiles to participate in interaction (e.g. highlighting) as a single entity. | ||
|
|
||
| ## Layers | ||
|
|
||
| _This section is non-normative._ | ||
|
|
||
| “Layers” are a common concept when working with vector data, representing semantic or functional groups of geometries requiring common handling by the application. For example, in a vector basemap, land and water boundaries are typically rendered behind geometries like roads and buildings, and will have different styling rules applied. In this case, semantic layers such as "water", "land", "roads", and "buildings" may be appropriate. | ||
|
|
||
| When translating from vector formats with explicit layer concepts, authoring implementations should encode each layer as a unique glTF node, named for the source layer. Ordered layers (if applicable) should be encoded as ordered nodes under a common parent node or scene. | ||
|
|
||
| Point, polyline, and polygon geometries should — in the absence of layers — be encoded with the minimum number of mesh primitives required. | ||
|
|
||
| ## Visualization | ||
|
|
||
| _This section is non-normative._ | ||
|
|
||
| Visual representation of vector data in 3D Tiles is left undefined by this specification. Current and future versions of the 3D Tiles styling language may be used to define or modify styles. | ||
|
|
||
| ## Schema | ||
|
|
||
| * [3DTILES_content_gltf_vector.schema.json](schema/3DTILES_content_gltf_vector.schema.json). | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| { | ||
| "$schema": "https://json-schema.org/draft/2020-12/schema", | ||
| "$id": "3DTILES_content_gltf_vector.schema.json", | ||
| "title": "3DTILES_content_gltf_vector extension", | ||
| "description": "3DTILES_content_gltf_vector extension data defining vector tile contents", | ||
| "type": "object", | ||
| "properties": { | ||
| "vector": { | ||
| "enum": [true], | ||
| "description": "Indicates tile content is vector data" | ||
| }, | ||
| "clip": { | ||
| "type": "boolean", | ||
| "description": "Whether content should be clipped to tile bounds when rendering", | ||
| "default": false | ||
| } | ||
| }, | ||
| "required": ["vector"] | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question — which of the following do we want to allow?
I suspect yes on (1), but I'm not sure about 2 and/or 3.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3 seems messy. From a spec standpoint either 1 or 2 should be okay.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed — if we needed (3) I suppose we'd need to either navigate the messiness of specifying which part of the content is which, or push some or all of this specification down into a glTF extension instead of a 3D Tiles extension. But defining "what is a vector, and how does it interact with tile boundaries" feels messy to define at the glTF level, without reference to geospatial concepts and 3D Tiles styling.
So I think I'd lean toward 1+2 but not 3, perhaps.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand these cases, but wouldn't it be simpler to remove the
vector:trueflag and only detect whether the extension is present? For example:There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a great point. Does a valid case exist where
vectormay be set tofalse, @donmccurdy?Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if there's a similar precedent in 3D Tiles, but in glTF the convention is that an extension attached to a core property should:
I can't find a link to the discussion off-hand, but I believe Ed Mackey originally articulated this goal. The extension KHR_materials_unlit was designed before that, and is the main exception I'm aware of.
Do we want 3D Tiles to follow a similar convention? In that case we'd want to design as if the extension could be collapsed onto the content object in the future:
{ "uri": "roads.glb", "vector": true }