How glTF References External Image Files
The glTF (GL Transmission Format) specification allows 3D assets to
reference external textures rather than bundling them into binary
containers or Base64-encoded strings. By utilizing the top-level
images array within the model's core JSON document, glTF
assigns external Uniform Resource Identifiers (URIs) to texture assets.
This article explains the JSON schema mechanisms behind external image
referencing, the texture-to-material linking pipeline, and how runtime
engines resolve these assets.
The images
Array and the uri Property
In a standard .gltf file, image definitions are
organized in a top-level JSON array named images. When
images are not embedded in a binary buffer via a
bufferView, each image object specifies a uri
property that points directly to the external file location.
{
"images": [
{
"uri": "textures/albedo.png"
},
{
"uri": "textures/roughness_metallic.jpg"
}
]
}The uri string follows the RFC 3986 standard. In
practical workflows, this is almost always a relative file path pointing
to an asset located in the same directory as the .gltf file
or in a designated subfolder (such as textures/). Absolute
web URLs (e.g., https://example.com/textures/albedo.png)
are also valid according to the specification.
Connecting Images to Materials
An external image is not directly assigned to a 3D mesh. Instead, glTF follows an indexed reference chain that links geometries to visual properties:
- Materials (
materials): A material references a texture index for specific slots, such asbaseColorTextureormetallicRoughnessTexture. - Textures (
textures): A texture object combines an image source with a sampler, defining how the image is filtered and wrapped. It references the index of the image via thesourceproperty. - Images (
images): The image entry contains theurito the external asset.
{
"materials": [
{
"name": "WoodMaterial",
"pbrMetallicRoughness": {
"baseColorTexture": {
"index": 0
}
}
}
],
"textures": [
{
"sampler": 0,
"source": 0
}
],
"images": [
{
"uri": "textures/wood_baseColor.png"
}
]
}In this structure, baseColorTexture points to
textures[0], which in turn sets source: 0,
directing the rendering engine to load images[0] from
textures/wood_baseColor.png.
Runtime Path Resolution
When a 3D runtime engine (such as Three.js, Babylon.js, or a custom
OpenGL/Vulkan loader) parses a .gltf file, it resolves
relative URIs against the base URI of the .gltf document
itself.
For example, if the model is fetched from
https://assets.example.com/models/chair/scene.gltf and an
image entry specifies textures/wood.png, the engine
constructs the fully qualified URL
https://assets.example.com/models/chair/textures/wood.png
to download the texture asynchronously.
Format Handling and MIME Types
Standard glTF 2.0 natively supports PNG and JPEG formats for external
images. An optional mimeType property can be included
within the image object:
{
"uri": "textures/normal_map.png",
"mimeType": "image/png"
}While loaders typically infer the format from the file extension or
the external file's response headers, explicitly specifying
mimeType removes ambiguity for custom loaders or
environments where file extensions are omitted.
Advantages of External Referencing
Referencing external images provides several functional benefits over embedding:
- Efficient Caching: Browsers and runtimes can cache individual image files independently of the 3D scene geometry.
- Shared Assets: Multiple separate glTF files can point to the same texture files on disk or over the network, reducing duplication.
- Asset Pipeline Flexibility: High-resolution source images can be replaced, compressed, or generated as web-optimized variants (such as WebP or KTX2 textures via extensions) without rewriting the binary geometry buffers.