Add a static hero camera to a render sequence

Your main camera is animated for the whole timeline — but sometimes one moment (an explosion, a headlight beam, a reveal) deserves its own fixed, carefully-framed shot cut into the middle of the video. This tutorial adds a second, non-animated camera and schedules it in the Render tab's Camera Sequence. Open the editor, load a scene with an existing timeline, open the Shell tab, and paste each block in order.

Why a second camera, not more keyframes. The Camera Sequence is a completely separate mechanism from animating camera itself: it's a list of shots, each naming a camera object and a start time, persisted on scene.userData.renderShots. A shot's camera does not need any keyframes at all — it can simply sit wherever you put it for the whole time it's on screen. That's the point: a hero shot is often better hand-framed once than animated.

1 Find a moment worth a dedicated shot

Scrub the timeline to the moment you want to showcase and look at what your main camera shows there. Use holdTimelineAt to jump straight to a timestamp without pressing play:

const { holdTimelineAt } = await import('./editor/js/intelligence/timelineController.js');
holdTimelineAt(editor, 24); // seconds into the Universal Timeline

If the main camera's framing doesn't do that moment justice — too far, wrong angle, an object in the way — that's exactly the case for a second, purpose-built camera.

2 Add the new camera

A plain THREE.PerspectiveCamera, added like any other object. Give it a name — you'll use it to select the camera again later. Don't add any keyframes to it; point it once and leave it:

const heroCam = new THREE.PerspectiveCamera(38, 16 / 9, 0.1, 500);
heroCam.name = 'HeadlightHeroCam';
heroCam.position.set(-4.15, 3.2, 14);
heroCam.lookAt(-4.15, 1.0, -40);
editor.execute(new AddObjectCommand(editor, heroCam));

Jump back to your target moment and check the framing from the new camera before wiring it into anything — swap the viewport over to it temporarily:

editor.viewportCamera = heroCam;
editor.signals.viewportCameraChanged.dispatch();
holdTimelineAt(editor, 24);

Nudge heroCam.position / re-run .lookAt(...) and re-dispatch objectChanged until it reads well across the whole span you'll use it for — not just one instant. A bus or character can move a long way in a few seconds; check both ends of the window:

heroCam.position.set(-4.15, 3.2, 14);
heroCam.lookAt(-4.15, 1.0, -40);
editor.signals.objectChanged.dispatch(heroCam);
Keep it clear of anything that moves. A static camera parked directly in a moving object's path will get run over mid-shot. Offset it to the side, or elevate it, so the subject passes near — not through — the lens for the shot's entire duration.

3 Cut it into the Camera Sequence

The sequence is a plain array on scene.userData.renderShots: { id, at, camera: uuid, transition, transitionDur }. A shot runs from its at until the next shot's at (or the timeline's end). Build a three-shot sequence — main camera, then the hero shot, then back to the main camera:

const shots = [
  { id: 'shot-intro',     at: 0,  camera: editor.camera.uuid, transition: 'cut',  transitionDur: 0.5 },
  { id: 'shot-headlight', at: 20, camera: heroCam.uuid,       transition: 'fade', transitionDur: 0.8 },
  { id: 'shot-return',    at: 29, camera: editor.camera.uuid, transition: 'fade', transitionDur: 0.8 },
];
editor.scene.userData = editor.scene.userData || {};
editor.scene.userData.renderShots = shots;
editor.signals.sceneGraphChanged.dispatch(); // refreshes the Render tab's sequencer UI

Switch the viewport back to your main camera when you're done previewing:

editor.viewportCamera = editor.camera;
editor.signals.viewportCameraChanged.dispatch();

4 Check it in the Render tab

  1. Open the Render tab. The Camera Sequence lane now shows three colored blocks — one per shot, labeled with the camera name and its cut/fade transition.
  2. Click a block to select it; the detail row below lets you retarget its camera, nudge its start time, or change cut/fade and the fade duration — all without touching the Shell again.
  3. With zero shots, the render always falls back to the single camera picked in the Camera dropdown at the top — the sequence is opt-in, never required.

5 Render it

Pick a resolution/FPS and click Render & Export. The sequence plays back exactly as scheduled: your main camera's own animation runs during its shots, then the render cuts (or fades) to the static hero camera at 20s, holds its fixed framing for nine seconds, then cuts back.

Real example this tutorial is based on. A bus's headlight beams were nearly invisible from the main animated camera's angle at that distance. Rather than re-choreograph the whole approach, one static camera placed dead-center on the road — elevated above the bus's roofline, looking straight down the lane the headlights travel — was cut in for just the arrival. The beams read as two clean glowing cones converging on the lens, then the sequence handed back to the main camera for the stop and boarding. See the animation guide for the full $S(...) grammar this tutorial's main camera would otherwise use.

Credits and licences

People

Assets

None used.

Tools

None used.