3dtiled-to-3dtiles
Reference notes

loaders.gl Tile Converter — @loaders.gl/tile-converter

Source: https://loaders.gl/docs/modules/tile-converter/cli-reference/tile-converter

Source: https://loaders.gl/docs/modules/tile-converter/cli-reference/tile-converter

Summary

The tile-converter is a CLI (and JS library) for two-way batch conversion between I3S and 3D Tiles. It is maintained by the Esri/loaders.gl team.

npm i @loaders.gl/tile-converter

npx tile-converter --install-dependencies
npx tile-converter --input-type <I3S|3DTILES> --tileset <tileset> --name <name> [options...]

Key options

OptionDirectionDescription
--input-typeboth"I3S" or "3DTILES"
--tilesetboth.json file (3DTiles) or http://…/SceneServer/layers/0 (I3S)
--outputbothOutput folder (default: ./data)
--namebothTileset name (used in output JSON + SLPK filename)
--output-versionI3S→3DT"1.0" or "1.1" (default)
--no-dracoI3S→3DTDisable Draco compression on output
--slpk3DT→I3S(deprecated since 4.3 — SLPK is now the default output)
--max-depthbothMax depth of tile traversal (default: ∞)
--generate-textures3DT→I3SCompress/decompress textures (KTX2 ↔ JPG/PNG)
--generate-bounding-volumes3DT→I3SRecompute OBB/MBS from geometry
--instant-node-writing3DT→I3SKeep node JSON on disk (saves RAM for huge datasets; ~2× slower)
--split-nodes3DT→I3SOne node per PBR material (prevents material merge artefacts)
--egmbothPath to Earth Gravity Model .pgm for ellipsoidal→gravity height conversion
--token3DT→I3SCesium Ion access token
--quietbothSkip interactive prompts (resume/new, metadata class)
--validateI3S→3DTCount tiles; check child fits parent bounding volume
--analyzebothAnalyze without converting
--metadata-class3DT→I3SSelect a metadata class when multiple are detected
--add-hashAdd hash entry to an existing SLPK

Relation to this project (i3s-to-3dtiles)

This project's packages/i3s-to-3dtiles/ is a custom parser — it does NOT use @loaders.gl/tile-converter. It reads I3S SLPK directories directly:

  • i3sParse.js: reads layers/0/ (scene-layer.json), node pages, and geometry buffers
  • glbBuild.js: writes raw GLB (no loaders.gl dependency)

Why not wrap @loaders.gl/tile-converter?

This project@loaders.gl/tile-converter
DepsZero (pure Node)~300 MB after --install-dependencies
ScopeSLPK directory onlySLPK, REST service, Cesium Ion
UnsupportedDraco, LEPCC, texturesAll supported
APIDirect convert() callCLI / subprocess
Browser futurePossibleNode-only (native deps)

For production I3S conversion (especially Draco-compressed or textured datasets), prefer @loaders.gl/tile-converter. For simple uncompressed mesh / point clouds, this project's built-in converter suffices.

@loaders.gl/i3s (separate from tile-converter)

@loaders.gl/i3s provides SLPKLoader, SLPKSource, I3SLoader — read-only, no 3D Tiles writer. Can serve SLPK tiles on-demand via SLPKSource (random access into the zip without full extract). Streaming: loaders.gl I3S loaders support incremental tile loading from REST services; SLPK is file-based.

import { SLPKLoader } from '@loaders.gl/i3s';
import { load } from '@loaders.gl/core';
const layer = await load('path/to/data.slpk', SLPKLoader);

Docker usage

docker pull visgl/tile-converter
docker run --rm \
  -v /path/to/output:/loaders-bundle/data \
  -v /path/to/input:/loaders-bundle/input-data \
  visgl/tile-converter \
  --input-type 3dtiles \
  --tileset input-data/tileset.json \
  --name MyDataset \
  --output data

Running a converted I3S layer locally

PORT=8080 I3sLayerPath="./data" npx i3s-server
# then open: https://loaders.gl/examples/i3s?url=http://localhost:8080/LayerName/SceneServer/layers/0

On this page