3D Classroom GLB Guide

The ManualQuest 3D classroom renders a teacher avatar inside a room, both loaded as GLB models. This guide explains how to author and export those models so they drop into the classroom editor cleanly and support lip-sync, blinking, and idle animation.
GLB (recommended) and self-contained glTF
GLB is the binary form of glTF 2.0: a single self-contained file that bundles geometry, materials, textures, skinning, morph targets, and animation clips. It is the format the web renderer expects, useGLTF from @react-three/drei loads a .glb directly, and shipping one file (with textures embedded) avoids the loose-asset path resolution problems you get with .gltf + external buffers/images. .glb is the recommended format for both teacher avatars and room models.
You can also upload a .gltf, but only a self-contained one, the buffers and textures must be embedded in the file (as base64 data URIs), not referenced as separate .bin / image files. A .gltf that points to external assets will fail to load, because only the single uploaded file is served. In Blender's glTF 2.0 exporter, choosing the "glTF Embedded (.gltf)" format produces a self-contained .gltf; the "glTF Binary (.glb)" format is still preferred (smaller, one step).
Exporters
- Blender, use the built-in glTF 2.0 exporter (File → Export → glTF 2.0). Choose the
.glb(binary) format and enable embedded textures. Export morph targets (shape keys), skinning, and any animation clips you want packed. - Ready Player Me, avatars exported from Ready Player Me ship with the Oculus viseme morph targets (
viseme_aa,viseme_PP, …) rather than the numeric0–21targets the classroom expects. Either rename those shape keys to the numeric ids below, or add amouthOpentarget to use the amplitude fallback (see the lip-sync section). RPM models already include blink and a smile shape.
Coordinate system, orientation, and scale
The renderer uses a Y-up coordinate system. Author your model so that:
- Up is +Y.
- The model faces +Z, toward the camera.
- The mesh sits near the origin (0, 0, 0).
- The model is roughly unit-scaled, a teacher about 1.6–1.8 units tall, a room sized to contain the avatar.
The classroom editor exposes a per-object transform you can use to fine-tune placement after import: each ClassroomObject carries a position, a scale, and a rotationY (in degrees). That is for fitting a model into a scene, not for fixing a model that was exported at the wrong scale or facing the wrong way, get the base export right first.
Required morph targets for lip-sync
Lip-sync is driven by morph targets (blend shapes / shape keys) on the avatar's head mesh. The classroom uses the Microsoft Azure viseme set: 22 mouth shapes whose morph targets are named with their numeric viseme id, "0" through "21" (id 0 is the closed/neutral mouth). Name them exactly:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21
Each id corresponds to a standard mouth shape (e.g. 2 = open "aa", 21 = closed "p/b/m", 15 = "s/z"). See Microsoft's viseme id reference for the full phoneme-to-id table. The bundled Teacher_Nanami.glb / Teacher_Naoki.glb models follow this convention exactly, inspect them in a glTF viewer to see the named targets.
In addition, include:
eye_close, used for blinking.mouthSmile, used for expression.
If your model uses a different blend-shape convention (e.g. the Ready Player Me / Oculus viseme_aa names) and therefore lacks the numeric 0–21 targets, add a single mouthOpen target instead. The classroom falls back to an amplitude-driven jaw that animates mouthOpen from audio loudness whenever no matching visemes are found, so the mouth still moves.
Size budget
Keep each GLB at or below 25 MB, this matches the client-side upload validation, so larger files are rejected before they reach storage. To stay under budget:
- Embed textures in the single
.glbrather than referencing external images. - Keep texture resolution reasonable (1K–2K is plenty for a classroom avatar or room).
- Keep polygon counts modest; decimate or retopologize dense scans.
Optional packed animation clips
You can pack named animation clips into the GLB. The classroom looks for these clip names:
Idle, Talking, Talking2, Thinking
These clips apply to default rigs (and any model that packs matching clip names). A custom rig without these clips still works: it gets an idle float, blinking, and lip-sync automatically. The named clips simply add richer body animation on top.
Default example models
If you want working references, the shipped defaults live under /models/:
- Teachers,
Teacher_Nanami.glb,Teacher_Naoki.glb - Rooms,
classroom_default.glb
A heavier example, classroom_alternative.glb, is also available if you want to see a more detailed scene. Inspect any of these in Blender or a glTF viewer to confirm the morph target names, scale, and orientation conventions described above before exporting your own.