3D Animator
A plain prompt gets you an object spinning in the middle of a grey void: a static camera, flat light, linear motion and no sound. An animator thinks about four things before writing any code: camera, light, motion and sound. This skill makes you think like that, then write every frame in code.
The rules come from a WhatsNext AI (@whats.nextai) production pipeline, tuned against measured top-performing reels:
- under 10% static frames;
- about 0.7 hard cuts per 10 s;
- music about 9 dB under the voice.
0. Before any code: direct it
Write a shot list first. Every beat gets one line:
beat | seconds | subject | CAMERA move | LIGHT change | MOTION event | SOUND cue
Rules for the shot list:
- Frame 1 shows the subject. Don't fade in from black, don't show a logo, don't open on an empty stage.
- Change something visible by about 1.5 s: a camera move, a reveal or a light change.
- Each beat changes one thing: the scale (wide ↔ macro), the angle, the light, or the state of the object. Never all at once.
- Restage the same object rather than cutting to unrelated scenes. The ending shot should rhyme with the opening shot.
- No subject? Pick one with a hidden inside, so the camera has somewhere to go: a watch, a phone, an engine, a city block, a cable. Plan a cutaway or reveal.
1. Camera (references/camera.md)
- The camera never rests. Add a slow orbit and bob made of two incommensurate sines on top of every shot, so no frame is static. Starting values: about 0.17 rad × sin(0.8t) + 0.09 rad × sin(1.9t + 0.7).
- Move between key cameras with ease-in-out (cubic). Never use linear moves, and never snap.
- Dolly, don't zoom. Move the camera position and keep the field of view between 30° and 40° for objects. Wide-angle FOV distorts products.
- Push in on reveals. Pull back to give context. One move per beat.
- Few hard cuts: about 0.7 per 10 s. Motion comes from the camera, not from cutting.
- Vertical 9:16 framing:
- Keep the subject in the middle 60% of the frame height.
- The top 15% is for a title.
- The bottom 25% is for captions and app UI.
- Leave the right 150 px clear on Instagram and TikTok.
- Depth: put something in the foreground, the subject in the middle and a soft background behind. Add floating dust motes or particles near the look-at point so even a slow move reads as motion.
2. Light (references/light.md)
- Dark background, one accent colour, one subject. For example, a navy
#0B0F18scene with an orange#FF914Daccent for "information". - Light setup:
- A hemisphere fill: sky
#A9BDE0, ground#0B0F18, intensity about 0.8. - A cool key directional light from above-left: intensity about 1.5, casting shadows.
- A warm point light on one side and a cool point light on the other, so edges separate from the background.
- A hemisphere fill: sky
- Reflections: use an environment map (
RoomEnvironmentthroughPMREMGenerator) at an intensity of 0.2–0.6. Without it, metal and glass look like plastic. - Bloom only on purpose:
- Use UnrealBloomPass with threshold 0.9 or more, strength about 0.4 and radius about 0.4.
- Things that should glow use
emissive, and nothing else glows. - The overexposure trap: pure white materials plus bloom wash the frame out. Use light grey (
#C9CFD9) for "white" plastics.
- Use fog (
<fog args={[bg, near, far]}/>) so distance falls off into the background colour. - Light changes are story beats: a part lights up as it's named, the room dims for a reveal, a flash lands on the payoff.
3. Motion (references/motion.md)
- Every animation is a pure function of the frame:
t = frame / fps.- Never use
Date.now()orMath.random(). Userandom(seed)from remotion. - Never animate with
useFrame.
- Never use
- Pops use springs (damping 12–14, stiffness about 170). Moves use ease-in-out cubic. Use linear only for constant things like conveyor belts and particle drift.
- Stagger related elements by 3–5 frames. Never move ten things on the same frame.
- Add secondary motion: a slow turntable spin on the hero object (±0.4 rad), drifting motes, a breathing scale (±1%).
- Holds are a choice. A freeze of up to 2 s is fine when it's a deliberate dramatic beat. Otherwise something always moves.
- Labels: short uppercase status labels pop in on the beat they name. Mark recreations "3D RECREATION".
4. Sound (references/sound.md)
- One SFX per event:
- a whoosh on a big camera move;
- a hit on a reveal;
- a riser (about 2 s) into a reveal;
- a click or pop on labels.
- Synthesise them (scripts/sfx_synth.py) or use CC0 packs.
- The music bed sits 6–11 dB under the voice, about 9 dB as a target. Sidechain-duck it under the narration.
- Silence is an effect. Drop the music out for one beat before the key line, then slam back in on a hit.
- Master to −14 LUFS integrated, with true peak at or below −1.5 dBTP. Pad the voice key to the full length so the music tail isn't cut.
5. Code rules (Remotion + three.js)
- Canvas: wrap 3D in
<ThreeCanvas width={width} height={height}>from@remotion/three, and always include lights. - Sequences: any
<Sequence>inside the canvas needslayout="none". - Post-processing: an EffectComposer can take over rendering with a priority-1
useFrame(() => composer.render(), 1). That's the one allowed use, because Remotion advances the scene once per frame so output stays deterministic. See templates/Fx3D.tsx. - State: drive the scene from a single state function
worldAt(t)that returns camera, stage and flags. Keep the components dumb. - Rendering: render with
--gl=angleon macOS when WebGL output is black or unstable. Use H.264, yuv420p, 1080×1920, 30 fps.
Ready-made pieces (copy, don't import):
templates/Fx3D.tsx: Env reflections and Bloom.templates/camera.ts:easeCam,orbit,ramp,pop.templates/Motes.tsx: deterministic dust particles.
6. Verify like an editor
- Render 4–6 stills: the hook, every reveal, and the last frame. Look for overexposure, the subject cut off by captions or the title, empty frames and unreadable text.
- Render the video, then run
scripts/check_motion.sh out.mp4. Target: under 10% static frames, motion (YDIF) at about 2 or more, and about 0.7 hard cuts per 10 s. If it's static, increase the orbit or bob, add motes, or add a push-in. Don't add cuts. - If there's audio, check loudness (−14 LUFS) and that the music sits about 9 dB under the voice.
- Re-render only what failed.
Done means: a shot list exists, every beat has a camera move, a light role, a motion event and a sound cue, the checks pass, and you looked at the stills.