Three.js From Zero · Article s8-05
S8-05 Debug Overlays
Season 8 · Article 05
Debug Overlays & Inspectors
Tools you keep open during development: Stats.js (FPS), lil-gui (live tweak), renderer.info (draw calls), AxesHelper/GridHelper, Three.js DevTools extension.
1. Stats.js
import Stats from 'three/addons/libs/stats.module.js';
const stats = new Stats();
document.body.appendChild(stats.dom);
// per frame:
function tick() { stats.begin(); render(); stats.end(); ... }
Toggle-able panels: FPS, ms, MB. One click during demo → FPS overlay on screen.
2. renderer.info
console.log(renderer.info);
// { render: { calls, triangles, points, lines, frame },
// memory: { geometries, textures },
// programs: [...] }
renderer.info.autoReset = false; // so you can read BEFORE next frame
// after render:
console.log('draws this frame:', renderer.info.render.calls);
renderer.info.reset();
3. lil-gui
import GUI from 'lil-gui';
const gui = new GUI();
gui.add(params, 'count', 100, 10000).onChange(rebuild);
gui.addColor(params, 'color');
gui.add(shader.uniforms.uGlow, 'value', 0, 3).name('Glow');
Auto-generated controls. Works on any plain object's properties.
4. Three.js DevTools (browser extension)
three-devtools — scene inspector in Chrome DevTools. Pick an object, see its properties, modify live.
5. Helpers (built-in)
scene.add(new THREE.AxesHelper(5)); // XYZ axes
scene.add(new THREE.GridHelper(10, 10)); // ground grid
scene.add(new THREE.SkeletonHelper(mesh)); // bones
scene.add(new THREE.CameraHelper(shadowCam)); // camera frustum
scene.add(new THREE.BoxHelper(mesh, 0xffff00));// bounding box
scene.add(new THREE.DirectionalLightHelper(light, 1));
6. WebGL Inspector / Spector.js
Spector.js: captures a frame's WebGL commands, shows every draw call, uniforms, textures. Essential for "why is this slow" investigations.
7. Demo — all overlays active
FPS:60
ms/frame:0
draws:0
tris:0
geoms:0
texts:0
8. Tools by use-case
| Question | Tool |
|---|---|
| Why only 30fps? | Stats.js + renderer.info |
| Too many draw calls? | renderer.info.render.calls |
| Memory leak? | renderer.info.memory |
| Shader not working? | Spector.js capture |
| Tweak shader constants? | lil-gui binding to uniform |
| Where's this object? | AxesHelper/BoxHelper |
| Shadow not casting? | CameraHelper on shadow cam |
9. Production vs dev flag
const isDev = import.meta.env.DEV; // Vite
if (isDev) {
document.body.appendChild(stats.dom);
scene.add(new THREE.AxesHelper(5));
}
// Tree-shaken from prod build.
10. Takeaways
- Stats.js: FPS overlay during dev.
- renderer.info: draw calls + memory counters.
- lil-gui: live-tweak any property.
- Helpers for axes, grid, skeleton, frustum, bbox.
- Spector.js for shader-level debugging.
- Three.js DevTools extension for scene inspection.
- Gate all behind a dev flag so prod doesn't ship them.