glTF — The JPEG of 3D: Khronos's Web, AR/VR, and Games Format, with OSM Building Export

2026-04-149 min read
glTFGLB3DKhronosPBRwebAR

glTF (GL Transmission Format) is an open 3D transmission format from the Khronos Group — the same consortium behind OpenGL, Vulkan, and WebGL. Version 1.0 shipped in October 2015; the major one — 2.0 — in June 2017, and since then glTF has positioned itself as "the JPEG of 3D": universal, efficient, natively supported by every modern 3D engine. Unlike OBJ (text) or FBX (Autodesk proprietary binary), glTF is a JSON manifest with companion .bin buffers and .png/.jpg/.ktx2 textures, or a single-file .glb (binary glTF) container. PBR materials (metallic-roughness model), Draco compression (minus 90% size), KTX2 texture compression, and the KHR_* extensions ecosystem make glTF the standard for web 3D, AR/VR, mobile games, and smart-city apps. On osm2cdr.ru gltf_exporter.py runs through Building3DExporter and emits a glTF JSON + .bin pair, or optionally a single-file GLB binary for drag-and-drop into three.js / Sketchfab / Microsoft Windows 3D Viewer.

Map generation of Vienna city center

History: Khronos and the COLLADA/FBX problem

Khronos Group is an open hardware/software consortium known for OpenGL (since 1992), OpenCL, WebGL, Vulkan. By 2012 the consortium had a gap: there was no single 3D format to ship models from server to client. COLLADA, which Khronos had standardized in 2004, turned out too verbose and slow for the web — hundred-megabyte XML manifests parsed in seconds. FBX from Autodesk was faster but proprietary and closed.

In 2012 Patrick Cozzi from Cesium (Analytical Graphics, specializing in 3D cartography) and Tony Parisi proposed a new format inside Khronos. The first prototype — glTF — appeared at SIGGRAPH 2013. By October 2015 Khronos shipped glTF 1.0 — JSON manifest + .bin buffers + GLSL shaders.

But glTF 1.0 had a problem: GLSL shaders were hard-baked into the file, and different browsers/engines rendered the same model differently. In June 2017 Khronos shipped glTF 2.0 with a radical change: shaders gone, replaced with PBR materials (Physically Based Rendering, metallic-roughness model). That removed 90% of incompatibilities and made glTF universally renderable.

Since 2018 glTF 2.0 has been the universal standard. Microsoft built it into Windows 10 3D Viewer (Paint 3D, Mixed Reality Viewer). Facebook accepts glTF for 3D Stories posts. Sketchfab made glTF the primary export. Apple Reality Composer imports glTF. Google Model Viewer is a single HTML tag — <model-viewer src="x.glb">. Cesium uses glTF as the internal format for 3D Tiles (the OGC smart-city standard). Khronos maintains a KHR_* extensions ecosystem: Draco compression (minus 90% size), KTX2 textures (GPU-native compression), instancing, lights, materials with five texture slots.

What's inside a glTF file

glTF 2.0 is a JSON manifest with references to binary buffers and image textures. Minimal structure:

  • asset — version, generator ("which program created it")
  • scene — root entry point, references nodes
  • nodes — object hierarchy (parent/children, transformation matrices)
  • meshes — list of mesh objects with primitives; each primitive is a set of attributes (POSITION/NORMAL/TEXCOORD_0/COLOR_0) + indices referencing accessors
  • accessors — typed views into bufferViews (componentType: FLOAT/UNSIGNED_SHORT/UNSIGNED_INT, type: VEC2/VEC3/SCALAR, count, min/max)
  • bufferViews — slices into buffers (byteOffset, byteLength, byteStride, target)
  • buffers — binary buffers (uri refers to a .bin file, or a base64 data URI)
  • materials — PBR material descriptions (baseColorFactor, metallicFactor, roughnessFactor, normalTexture, emissiveFactor, alphaMode)
  • textures — refs to images via samplers
  • images — refs to PNG/JPG (uri) or base64

GLB is the single-file binary variant of glTF 2.0. Structure: - 12-byte header (magic 0x46546C67 = "glTF", version uint32, length uint32) - JSON chunk (type 0x4E4F534A "JSON", same glTF JSON inline) - BIN chunk (type 0x004E4942 "BIN ", geometry + textures inline)

Mermaid diagram: flowchart LR

Map generation of Sochi city center

PBR materials: the glTF 2.0 game-changer

Physically Based Rendering is a lighting model based on physical laws of reflection. glTF 2.0 uses the metallic-roughness method:

  • baseColorFactor [r, g, b, a] or baseColorTexture — base color (or texture)
  • metallicFactor 0..1 — how metallic (0 = dielectric, 1 = metal)
  • roughnessFactor 0..1 — surface roughness (0 = mirror, 1 = matte)
  • normalTexture — normal map for bump mapping
  • occlusionTexture — ambient occlusion
  • emissiveFactor [r, g, b] — self-illumination

Unlike the legacy Phong/Blinn model (OBJ .mtl), PBR describes a material in physically realistic terms. The same glTF file looks consistent across three.js, Babylon.js, Unreal Engine, Unity, Blender Cycles — because all of them implement unified PBR.

Strengths and weaknesses

Strengths. Royalty-free Khronos open standard. JSON + binary hybrid: readable JSON, efficient .bin. PBR materials for universal rendering. Browser-friendly: <model-viewer> tag, three.js GLTFLoader, Babylon.js — load in one line of JavaScript. Draco compression (via KHR_draco_mesh_compression) cuts size 10x with no visible quality loss. KTX2 texture compression is GPU-native, no CPU decompression. Single GLB file for drag-and-drop into Sketchfab, Microsoft 3D Viewer, Reality Composer. Skeletal animation and morph targets supported.

Weaknesses. JSON parsing overhead vs pure binary (FBX, USD). PBR materials limited to metallic-roughness — no procedural shaders, no custom shading. Animation is rich but not at USD/Alembic level for film/VFX. Young format (2017 release) — some legacy tools still don't support it (old SolidWorks, AutoCAD <2020). Not for 3D printing — slicers don't understand materials or textures; export STL instead.

glTF vs OBJ vs FBX vs USD

OBJ — legacy text exchange, 1990 vintage. Good for quick-sharing between Blender/Maya. glTF — modern replacement with PBR, compression, web-ready. FBX — Autodesk proprietary, strong in Unity/Unreal animation pipelines but closed format. USD (Universal Scene Description from Pixar) — film/VFX scene graph, more complex than glTF, for large pipelines. For a new web/AR/games project — pick glTF; for Maya legacy → FBX; for Pixar-style pipeline → USD.

Use cases

Web developer. Loads glTF in three.js in one line: new GLTFLoader().load('city.glb', gltf => scene.add(gltf.scene)). Gets a full 3D scene with PBR materials, no custom shaders, no preprocessing.

AR/VR developer. Apple Reality Composer imports glTF for iOS AR apps. Google Scene Viewer launches glTF on Android via <model-viewer ar>. Quest and HoloLens support glTF as primary.

Cesium / smart-city dev. Cesium 3D Tiles (OGC standard 1.1, 2023) is glTF inside ZIP tilesets. Used for city-scale browser visualization: Microsoft Cities, NTT Tokyo Digital Twin, Singapore Smart Nation.

Game developer in Unity/Unreal. UnityGLTF and Khronos glTFRuntime for Unreal — official plugins to import glTF as game assets. Smaller build impact than FBX.

3D-print marketplace (Sketchfab). The platform accepts glTF/GLB uploads and renders them in-browser via WebGL. No desktop software needed to view.

OSM visualization in the browser. Export a district as glTF, drop into Google Model Viewer on your site in one HTML line — visitors see a 3D district without plugins.

Software

Blender. Free, cross-platform. Native glTF export since 2.81 (2019). Supports PBR materials, Draco compression (via checkbox), KTX2 textures.

three.js. Free JavaScript library, de-facto standard for web 3D. GLTFLoader loads glTF/GLB in one line.

Babylon.js. Free JavaScript library from Microsoft. Alternative to three.js with a more batteries-included API. Full glTF support.

Microsoft Windows 3D Viewer. Free built-in to Windows 10/11. Opens GLB drag-and-drop.

Google <model-viewer>. Free HTML web component. One tag: <model-viewer src="city.glb" auto-rotate camera-controls></model-viewer>.

Sketchfab. Freemium platform for sharing 3D. Accepts glTF/GLB upload, renders in-browser.

NVIDIA Omniverse, Unreal Engine 5. Paid enterprise stack for film/games. Full glTF import.

Pipeline in OSM2CDR

Our gltf_exporter.py inherits from Building3DExporter. The pipeline mirrors STL/OBJ:

  1. Load buildings from PostGIS via WKB.
  2. Calculate building height by rule height > building:levels × 3 m > fallback.
  3. Extrude polygons into prisms via trimesh.creation.extrude_polygon.
  4. Convert trimesh.Mesh → glTF via mesh.export(file, file_type='glb') (or .gltf for JSON+bin pair).
  5. PBR materials per building type: residential = baseColorFactor [0.8, 0.8, 0.8, 1], metallicFactor 0, roughnessFactor 0.9; commercial = [0.6, 0.7, 0.9, 1], roughness 0.7; etc.

Coordinates are Y-up, as the glTF spec requires: the scene is built Z-up and the rotation into +Y is written into the scene-graph nodes on the way out. Nothing to rotate on import into three.js / model-viewer / Blender. (Until 2026-08-30 we emitted Z-up with no rotation in the root node — that was our bug, and it laid the model on its side; fixed.) Tools that want Z-up are served by OBJ and STL, where height stays on Z.

Draco compression is not on by default in our pipeline yet — it could land via a compression=draco query parameter in the future. KTX2 textures we don't use (no building texture maps in OSM).

Map generation of Paris city center

FAQ

glTF or GLB — which to pick? GLB — single binary file, convenient for drag-and-drop, sharing, web upload. glTF JSON + .bin pair — better for development, version control (you can git-diff JSON), hand-editing. For production, GLB is preferred.

Z-up vs Y-up? The glTF 2.0 spec says Y-up ("right-handed coordinate system, Y-up"), and since 2026-08-30 our export follows it: the rotation lives in the scene-graph nodes, the vertex buffers stay in scene meters. You no longer need to rotate 90° on X when importing into three.js / Blender / Reality Composer. If you want Z-up (CAD, GIS, slicers), take OBJ or STL.

Do Cesium 3D Tiles use glTF inside? Yes. 3D Tiles is an OGC streaming standard for city-scale 3D, and tile content within it is glTF (binary GLB or JSON+bin) with additional metadata extensions (BatchTable, FeatureTable). The Cesium runtime is a renderer for 3D Tiles + glTF.

Can I view glTF in a browser without libraries? Yes, through Google's <model-viewer> web component: one HTML line <script type="module" src="https://ajax.googleapis.com/ajax/libs/model-viewer/3.5.0/model-viewer.min.js"></script> + <model-viewer src="x.glb"></model-viewer>. Under the hood — three.js, but the syntax is a plain HTML tag.

What is Draco compression? Google's open-source mesh/point cloud compression. Via the KHR_draco_mesh_compression extension, glTF can shrink geometry 10x with no visible quality loss — a typical building model 500 KB → 50 KB. Enabled by flag in Blender export or the gltf-pipeline CLI tool.

Sources

← All articles