Find files, editable templates and browser test targets by what you need to make or test. The directory below is cut by format; the two collections under it cut the same library by subject and by workflow.
Three identical spheres differing only in alphaMode, arranged left to right. The MASK sphere's base alpha (0.45) sits deliberately just under its 0.5 cutoff, so a correct renderer discards it entirely while a renderer that treats MASK as BLEND draws it semi-transparent.
The same metal expressed in the archived specular-glossiness model, carried in `extensions` with an equivalent metallic-roughness fallback and NOT listed in extensionsRequired. The correct shape for an asset that must keep loading in viewers which dropped specular-glossiness support.
A morph target stored as a sparse accessor: only 25 of 289 vertices carry a delta, and the accessor has no bufferView at all, so every other vertex reads as zero. Sparse accessors are the least-implemented corner of the glTF spec and the usual cause of a target that appears to do nothing.
The two-target plane with an animation channel whose target path is `weights`: five keyframes, ten scalars, because a weights sampler stores one value per target per key. The case that breaks players which assume every channel output is a vec3 or a quaternion.
Eight POSITION morph targets on one primitive: bumps arranged around a circle, so every active weight is visible independently. Eight is where many real-time renderers stop supporting extra targets; this is the fixture that says whether yours does.
Morph targets that displace both positions and normals, with the first target already at weight 0.3 in the bind pose. Shading that stays flat while the surface ripples is the symptom of a loader that morphs positions and forgets the normal deltas.
A 16x16 plane with two POSITION morph targets (a sine ripple and a centre bulge), both at weight 0 in the bind pose. Drive the weights yourself to check that a loader adds the deltas to the base positions instead of replacing them.
The same two-target morph plane as readable glTF JSON, so the `targets` array, the mesh-level `weights` and the target accessors can be inspected without a hex editor.
One cube on one node, with translation, rotation and scale each driven by a five-key sampler that is cubic-spline, with in/out tangents stored around each value. Three files differing only in `interpolation`: the cleanest way to prove an animation player implements all three modes rather than treating everything as linear.
One cube on one node, with translation, rotation and scale each driven by a five-key sampler that is linearly interpolated. Three files differing only in `interpolation`: the cleanest way to prove an animation player implements all three modes rather than treating everything as linear.
One cube on one node, with translation, rotation and scale each driven by a five-key sampler that is held (STEP): the value jumps at each key. Three files differing only in `interpolation`: the cleanest way to prove an animation player implements all three modes rather than treating everything as linear.
A longer tube skinned to a four-joint chain, every joint but the root animated, so the whole limb curls rather than hinging once. Exercises joint-matrix accumulation down a hierarchy: the step that a two-bone rig cannot catch.
A tube skinned to a two-joint chain with inverse bind matrices, unsigned-byte JOINTS_0 and float WEIGHTS_0, plus a three-second rotation animation on the elbow. The shipped models category had no skinned mesh at all; this is the smallest complete one: rig, bind pose, weights and clip in a single self-contained GLB.
The same two-joint skinned bend as readable glTF JSON with its buffer embedded as a base64 data URI: the file to open in a text editor when a GLB's skin, sampler or inverse bind matrices are not doing what you expect.
The 24-level spiral as readable JSON, so the `children` arrays and per-level TRS can be traced by eye. Useful when a converter flattens or re-parents a hierarchy and you need to see exactly where.
The same sphere with its buffer inlined as a base64 data URI: one self-contained text file, at roughly a third more bytes than the binary it encodes. The middle point of the three storage strategies in this group.
A glTF whose single buffer is a relative URI to a sibling .bin: the layout every DCC tool writes by default, and the one that breaks the moment an asset is moved or served from a different directory. Download the .bin in this group alongside it.
Geometry inline, texture out of line: the image is a relative URI to a sibling PNG while the buffer is embedded, which is the mixed layout that trips asset packers expecting all-or-nothing. Download the PNG in this group with it.
A 10 mm cube as text glTF 2.0: the JSON scene with its binary buffer embedded as a data URI, the human-readable sibling of the GLB. For testing glTF parsers and GLB↔glTF conversion.
The same six-cube ring with translation, quaternion rotation and scale spelled out per node. Read it next to the matrix twin to check a decomposition routine, or to confirm that your quaternion component order really is xyzw.
The same textured sphere with the PNG inlined as a base64 data URI in `images[0].uri`: a single portable text file. The variant that makes a glTF e-mailable and that some loaders quietly refuse.
The three-scene asset as readable JSON, where the top-level `"scene": 1` is one line you can point at in a bug report. Also the fixture for round-tripping multi-scene assets through tools that keep only one scene.
The float32 GLB from this group as a deterministic gzip stream (no embedded filename, mtime 0), what a CDN actually sends when a viewer advertises `Accept-Encoding: gzip`. It compresses to 29.2% of its source against 55.6% for the quantized twin, which is the point of shipping both: quantisation halves the file on disk and then gives most of that back over the wire.