3dtiled-to-3dtiles
Guide (from README.md)

Format comparison

🟢 = operational · 🟡 draft = scaffold built, partially/un-validated · 🟠 doc = spec referenced in

🟢 = operational · 🟡 draft = scaffold built, partially/un-validated · 🟠 doc = spec referenced in docs/references/, converter not built (lower-priority / niche). The Spec column below gives every canonical source plus a link to the distilled local mirror (hand-written since several spec sites block automated fetching — kept in sync as the converters evolve).

Output — 3D Tiles

FormatStatusHierarchy / subdivisionNode (leaf) contentRefineIntermediate nodesMetadata locationHTTP rangeSpec
3D Tiles (output)🟢 outexplicit or implicit; box/region/sphere volumesglTF/GLB w/ KHR_gaussian_splatting+_spz_2 (splats) or POINTS/TRIANGLESREPLACE/ADDoptional contenttileset.json (+ .3tz)OGC

Tiled point clouds → 3D Tiles

FormatStatusHierarchy / subdivisionNode (leaf) contentRefineIntermediate nodesMetadata locationHTTP rangeSpec
COPC (Cloud Optimized Pointcloud)🟢octree (EPT-style)LAZ-compressed LAS pointsADDoctree nodes (accumulate)COPC VLR + hierarchy pages✅ designed for range readscopc.io · spec repo · local: copc-format.md
Potree (v1 and v2)🟢octree (named r/r0..r7)points: position int32×3·scale+offset + rgb (2.0 octree.bin / 1.x per-node .bin)ADDoctree nodes (accumulate)2.0 metadata.json+hierarchy.bin (22 B/node) · 1.x cloud.js+.hrc✅ (2.0 single octree.bin; 1.x per-node files)PotreeConverter · 2.0 format · ref impl potree23dtiles · local: potree-format.md

Generic tiled formats → 3D Tiles

Formats that carry (or wrap) a general node/mesh hierarchy rather than a point- or splat-specific one.

FormatStatusHierarchy / subdivisionNode (leaf) contentRefineIntermediate nodesMetadata locationHTTP rangeSpec
3D Tiles packages .3tz/.3dtiles🟢passthrough — whatever the wrapped tileset.json declares (explicit or implicit)the wrapped tileset's own tile content, unchanged(wrapped tileset's own)(wrapped tileset's own).3tz: ZIP + @3dtilesIndex1@ binary index (path→offset) · .3dtiles: SQLite key TEXT, content BLOBN/A — O(1) offset read / SQLite key lookup, not source-file byte-ranges3tz spec · .3dtiles proposal #727 · local: 3tz-3dtiles-packages.md
I3S (Esri)🟡 draftnode tree (always explicit — no implicit/template scheme), OBB/MBS LoD (SLPK or REST)nodes/geometry/textures; DefaultGeometrySchema = PerAttributeArray (pos f32×3 · normal f32×3 · uv0 f32×2 · color u8×4, sequential) or DracoREPLACEnode pages (nodepages/*.json)3dSceneLayer.json + node pages✅ REST/rangeesri/i3s-spec (OGC Community Standard) · local: i3s-spec.md
3MX (Bentley/Acute3D)🟢master Scene.3mx JSON → 3MXBO binary node treeOpenCTM (MG1/LZMA) mesh + JPEG baseColor → transcoded to glTFREPLACE3MXBO node-tree levelsScene.3mx + per-node .3mxb➖ per-file GET (lazy external-tileset fragments per .3mxb)Bentley docs
Bing Maps 3D🟢quadtree of quadkeys (availability by HTTP probe)tf=3dv4 GLB — Draco geometry + KTX2 textures, ECEF baked into the node matrixREPLACEquadkey levelsmanifest by quadkey/genid➖ per-file GET(undocumented public tile service, reverse-engineered)
Nexus (CNR-ISTI)🟠 docmultiresolution patch DAG / batched meshper-patch mesh (not splats)header + patch indexgithub · paper

Tiled Gaussian-splat sources → 3D Tiles

FormatStatusHierarchy / subdivisionNode (leaf) contentRefineIntermediate nodesMetadata locationHTTP rangeSpec
SOG (streamed) (PlayCanvas)🟢binary spatial tree (AABB split)unbundled SOG chunk: WebP textures → DataTable (pos/quat-w-first/log-scale/SH-DC/logit-opacity)REPLACEempty grouping nodesno geo metadata, lod-meta.json + per-chunk meta.json✅ per-filestreamed-SOG · SOG · splat-transform · local: streamed-sog.md · sog.md
LCC (XGRIDS)🟢grid of Units (cellX×Y) × per-cell LODsData.bin fixed 32 B/splat: pos f32×3, color rgba8, scale u16×3, rot 10-10-10-2 (+SH Shcoef.bin 64 B)REPLACEper-cell coarse LODsgeoref'ed, meta.lcc JSON + Index.binIndex.bin offsets into Data.bindeveloper.xgrids.com · LCC whitepaper · LCC-Web-SDK · local: lcc-format.md
RAD (SparkJS)🟢LoD merge tree, variable fanout (Tiny-LoD base β≈1.75; Bhatt-LoD unspecified, our converter observes ~1.5 in practice)RADC chunk: per-splat columns — f16/oct88r8 interleaved, ln_0r8/r8_delta planar, f32_lebytes byte-transposedREPLACEdownsampled merged splatsno geo metadata, root RAD0 JSON + per-chunk RADC JSON✅ chunked .radcspec: LoD getting started · blog: Spark 2.0 · ext-splats · local: rad-format-notes.md · spark-2.0-blog-post.md
GeoSplats (MapTiler)🟢octree voxel grids (grid_1/8/64/512) × 8 progressive LODsper-octant SOGS (means_l/u, quats, scales, sh0 WebP) or octant_<n>.plyREPLACE (LOD subset)coarser-LOD octantsgeoref'ed,model.json (georef) + per-sub-model metadata.json (voxel_grids + entries TOC)✅ per-file / rangemaptiler.com/geosplats · SDK @maptiler/geosplats (CDN .mjs) · local: maptiler-geosplats.md

Other specs (no dedicated converter row above)

Extension/format specs referenced by the tables above but not themselves a distinct converter target:

On this page