Three.js Motion Graphics Authoring
Three.js animations can be built for web playback and composite WebM video export. Strict architectural rules are recommended to ensure canvas pixels export correctly.
1. Core Architecture & Export Contract
- Export-Safe Canvas:
- ✅ CRITICAL: You MUST set
{ alpha: true, antialias: true, preserveDrawingBuffer: true }on theWebGLRenderer. WithoutpreserveDrawingBuffer, video exports will be blank/black.
- ✅ CRITICAL: You MUST set
- Transparent Backgrounds:
- ✅ Manage backgrounds via CSS composite logic when transparency is needed.
- 🚫 Avoid using
scene.background = new THREE.Color(...)in your Three.js code if exporting with transparency.
- Vite Compatibility:
- ✅ Import dependencies using bare module specifiers:
import * as THREE from 'three';andimport { OrbitControls } from 'three/addons/controls/OrbitControls.js'. - 🚫 Do NOT use CDNs (
https://unpkg.com...), and do NOT inject<script type="importmap">.
- ✅ Import dependencies using bare module specifiers:
2. Animation, Timing & Controls
- The Render Loop:
- ✅ All animation logic (rotations, tweening) should happen inside the
requestAnimationFrame(animate)loop. - 🚫 Avoid
setIntervalorsetTimeoutas they can desync from external playback controls.
- ✅ All animation logic (rotations, tweening) should happen inside the
- Duration Communication:
- ✅ External recording tools often use the DOM Web Animations API (
document.getAnimations()) to calculate the end time. Consider applying dummy Web Animations to an invisible DOM element (e.g.,<div id="timing-dummy"></div>) if your scene uses pure Three.js math looping, so external recorders know when to stop.
- ✅ External recording tools often use the DOM Web Animations API (
- Native Math Tweening:
- ✅ Prefer native math-based easing (e.g.,
(time % loopDuration)) inside the render loop over external libraries like GSAP for perfect video export loops.
- ✅ Prefer native math-based easing (e.g.,
- Cinematic Camera:
- ✅ For sweeping camera moves during export, use
OrbitControlswithcontrols.autoRotate = trueand configurecontrols.autoRotateSpeed.
- ✅ For sweeping camera moves during export, use
3. Materials, Lighting & Styling
- Premium Lighting:
- ✅ Use
MeshStandardMaterialorMeshPhysicalMaterial. Enable shadows (renderer.shadowMap.enabled = true, useTHREE.PCFSoftShadowMap). - ✅ Use an
AmbientLightfor soft fill andDirectionalLightfor sharp, dramatic shadows.
- ✅ Use
- CAD / Blueprint Overlays:
- ✅ For glowing wireframes, pair
THREE.EdgesGeometrywithTHREE.LineSegments. This looks far superior to basicmaterial.wireframe = true.
- ✅ For glowing wireframes, pair
- Legibility & Contrast:
- ✅ For
CanvasTexturetext, use high-contrast text colors and consider adding a subtle halo (shadowColor = 'rgba(255,255,255,0.9)') to guarantee legibility against variable backgrounds. - ✅ Dual Materials for TextGeometry: Reflective front faces can be unreadable. Use an array
[frontMat, sideMat]: flat/emissive material for the front, highly reflective material for the extruded sides.
- ✅ For
- Flat Shading (Low-Poly):
- ✅ To get crisp, faceted low-poly lighting (e.g., on
PlaneGeometry), you MUST convert the geometry usinggeometry.toNonIndexed()before displacing vertices, then setflatShading: trueon the material.
- ✅ To get crisp, faceted low-poly lighting (e.g., on
4. Advanced Geometry & Shaders
- Model Orientation (OrbitControls):
- ✅
OrbitControlslocks the Y-axis. To pan horizontally along a long object, do not fight the camera. Group the object and rotate the group (group.rotation.z = -Math.PI / 2), letting the default Y-axis auto-rotation circle the object perfectly.
- ✅
- Local Fonts:
- ✅ Always host
TextGeometryJSON fonts locally in/public/fonts/(download viacurl). 🚫 Do NOT rely on CDNs (CORS/Vite pathing issues).
- ✅ Always host
- Kinetic Shaders (
onBeforeCompile):- ✅ When injecting GLSL vertex modifications (like sine waves), always program a "readable state" (e.g., dial uniform strength to 0 for a few seconds) so users can read the text. Never stop motion entirely; keep a subtle 10% base wave active.
- GPU Particle Systems:
- ✅ Morphing: Use
MeshSurfaceSamplerto extract vertices, load into customBufferAttributearrays, andmix()within aShaderMaterialvertex shader. - ✅ Sizing: Multiply
gl_PointSizeby a massive base multiplier (e.g.,300.0 * pixelRatio) to prevent perspective attenuation from collapsing particles into 1px dust. - ✅ Blending & Glows: 🚫 Do NOT use
THREE.AdditiveBlendingif exporting on white (it renders invisible). UseTHREE.NormalBlending. Instead of PNG textures, use a math-based alpha fade in the fragment shader for perfect glowing orbs.
- ✅ Morphing: Use
5. Workflow Checklist
- Create a new directory for your animation.
- Add an
index.htmlcontaining the Three.js scene (use ES modules). - Ensure
preserveDrawingBuffer: trueandalpha: trueare set on theWebGLRendererif video export is intended. - Test the sequence in a browser to ensure smooth playback and correct timing.
6. Design Explorations
- Inspiration: Draw inspiration from advanced visual patterns like Particles, Data Topography, and Isometric Dioramas.