Skip to main content
WEB
SkillFreeBy GameSkillGameSkill original

Three.js: Load a glb and Assemble a Scene

/threejs-glb-scene-assembly

A GameSkill original: load a glb (Draco included) into three.js asynchronously and wire a small playable scene around it: loading bar, model normalisation, colliders, a water shader with matching buoyancy, lights, pooled particles and WebAudio sound.

License
MIT
By
By GameSkill
Download ZIP

Tested by GameSkill

40/40 checks passed on three.js r186 (0.186.1) in Chrome 156 headless (2026-10-28): trigger, a runnable example, a screenshot and self-check, one job per skill, and English + Chinese docs. Trigger checks match prompts against skill descriptions; they are not a live agent run.

Test report

GameSkill's tested copy

Written and tested by GameSkill for gameskill.dev. The ZIP holds the whole skill: SKILL.md and its Chinese version, scripts, a runnable example, tests, the self-check list and our test report.

A GameSkill original, released under MIT. The ZIP keeps LICENSE and CREDITS.md, which lists the workflow inspiration, the CC0 test assets and the third-party libraries with their licenses.

Three.js: Load a glb and Assemble a Scene

Self-check

  • 通过 http 访问,DRACOLoader 解码器路径没有 404 / Served over http; the DRACOLoader decoder path has no 404
  • 全部用 loadAsync + Promise.all 加载完再开始玩,加载失败在画面上提示 / Everything loads with loadAsync + Promise.all before play starts; load errors show on screen
  • 模型缩放到已知高度、轴心在底部,碰撞体从模型算出来 / Model scaled to a known height, pivot at the base, colliders derived from the model
  • 水面着色器和 CPU 浮力用同一张波浪表 / Water shader and CPU buoyancy share one wave table
  • AudioContext 在用户操作里创建或恢复 / AudioContext created or resumed inside a user gesture
  • npm test 和 npm run test:browser 都通过,没有控制台错误 / npm test and npm run test:browser pass with no console errors

Install

Tell your AI

Install the skill from https://gameskill.dev/skills/threejs-glb-scene-assembly/install.md

GameSkill's tested copy

Tested copy into .claude/skills/
mkdir -p .claude/skills
curl -fsSL https://gameskill.dev/dl/skills/threejs-glb-scene-assembly.zip -o /tmp/gameskill-threejs-glb-scene-assembly.zip
unzip -oq /tmp/gameskill-threejs-glb-scene-assembly.zip -d .claude/skills
rm /tmp/gameskill-threejs-glb-scene-assembly.zip

What you get

  • Bottle Cove: a playable demo in one file of wiring (src/main.js, 8 numbered sections)
  • GLTFLoader + DRACOLoader with a LoadingManager progress bar and an on-screen error overlay
  • prepareModel: scale to a target height, pivot at the base, shadows on
  • Sphere and AABB colliders, a sum-of-sines water shader with matching CPU buoyancy, pooled particles
  • WebAudio ambience, music and SFX synthesised at runtime (no audio files)
  • 16 Node logic tests and a 10-check headless Chrome test

Good fit

  • A first 3D web game scene in three.js
  • Fixing DRACOLoader decoder errors, invisible models and colour-space problems
  • Water, floating objects, simple collisions and particles without a physics engine

Not for

  • Large worlds or real physics: use a physics engine such as Rapier when the scene grows
  • Making the glb itself small: run it through multiview-to-web-3d-asset first

Try this prompt

Prompt
Load my Draco glb in three.js with a loading bar and drop it into a small scene I can walk around.

About this skill

A GameSkill original, written and tested for gameskill.dev under MIT. The demo, Bottle Cove: walk around an island, pick up bottles bobbing in the surf, bump into rocks. One file of wiring (src/main.js, 8 numbered sections) and one engine-free logic module (src/logic.js) that the Node tests cover.

Agent steps

  1. Loaders: one LoadingManager for progress, DRACOLoader().setDecoderPath(...), then gltfLoader.setDRACOLoader(draco). Load with await Promise.all([loader.loadAsync(url), ...]); start gameplay only after it resolves and show errors on screen.
  2. Normalise the model (prepareModel): measure with Box3, scale to a target height, put the pivot at the base centre, enable shadows. Never trust the file's scale.
  3. Collider: derive it from the loaded model (bounding sphere; AABBs for static props).
  4. Water: a ShaderMaterial whose vertex shader and logic.waveHeight share one wave list, so floating objects ride the visible surface.
  5. Lights: hemisphere fill plus one directional sun with a tight shadow camera; sRGB output and ACES tone mapping.
  6. Particles: one Points with a fixed pool; no allocation in the loop.
  7. Audio: create the AudioContext on the first key or pointer event; surf, a pentatonic pluck loop on a look-ahead scheduler, one-shot chime and bump.
  8. Loop: clamp dt to 50 ms so a background tab doesn't teleport anything.

Common errors it fixes

  • THREE.DRACOLoader decoder errors or a 404 on draco_decoder.wasm: wrong decoder path, or the page was opened from file://.
  • Invisible model: the scale (AI meshes arrive at 1 or 100 units) or a camera inside it; prepareModel fixes both.
  • Black or washed-out custom shader: missing #include <colorspace_fragment>, or tone mapping applied twice.
  • No sound: the context was created before a user gesture and stays suspended.

Credits

Workflow inspiration: a post by @gkxspace on X. Code and text are ours. Model: Khronos WaterBottle (Microsoft, CC0-1.0), optimised with Multi-view to Web-ready 3D Asset. three.js r186 (MIT) and the Draco decoder (Apache-2.0) are vendored with their licences.

Requirements

  • A static http server (node test/serve.mjs is included); glb and wasm do not load from file://
  • Node.js 20+ to run the tests; Chrome for the browser check

Topics

FAQ

Works well with

Skills the author points to as related or as the better fit for neighbouring tasks.

Similar skills