You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Camera: 3D rotation with a shared perspective, and camera motion blur #362
Two reels in this batch film their scenes with a moving camera: the whole shot (room, mockup, text, tiles) orbits together, and fast camera moves blur the entire frame. The per-node tools can't do either for a whole scene.
1. rotate_x, rotate_y and perspective on camera
Camera keyframes accept only x, y, zoom, rotation, origin.x, origin.y, focus and aperture:
unknown camera keyframe property 'rotate_x'
Parallax through style.depth knows translation and zoom only. To tilt a whole shot, you copy the same rotate_x/rotate_y keyframes onto every group. Each group then has its own vanishing point, and near planes don't swing more than far ones.
The rotation applies to each direct child of the scene according to its style.depth, the same rule the parallax and the camera.focus blur already use.
2. Camera motion blur
Dives and whip moves in the references drag the whole image. camera.keyframes moves the camera without blur, motion_blur works per element, and transitions only act at a cut.
Part 1 landed in #400: camera.rotate_x, rotate_y and perspective, applied once about the camera's origin and scaled by each plane's style.depth. Keyframes work on all three.
Part 2 — camera motion blur — is still open, and this is why it was split rather than bundled.
It means rendering each frame several times with the camera at sub-frame positions inside the shutter window and accumulating them. That is not a paint-pass change: it belongs in the encode loop, where render_frame_task_scaled produces one buffer per frame. It brings its own cost model — k× render time on every frame the camera moves — and its own question of where the sampling happens so the audio and frame accounting stay consistent.
Bundling it into #400 would have made one PR that was really two, with the cheap half hostage to the expensive one.
Closing. Part 1 shipped in #400: camera.rotate_x, rotate_y and perspective,
applied once about the camera's origin and scaled by each plane's style.depth.
All three animate through keyframes, and rules/camera-3d.md documents it.
Part 2 — camera motion blur — is dropped rather than parked. It means rendering
each frame k times at sub-frame camera positions and accumulating them: a k×
cost on every frame the camera moves, in the encode loop rather than the paint
pass. That is a cost decision, and nothing is asking for it.
Reopen with a target k and an acceptable per-frame budget if it becomes wanted.
Activity
feat(camera): tilt a whole shot in 3D with one shared vanishing point (…
LeadcodeDev commentedon Sep 27, 2026
Part 1 landed in #400:
camera.rotate_x,rotate_yandperspective, applied once about the camera's origin and scaled by each plane'sstyle.depth. Keyframes work on all three.Part 2 — camera motion blur — is still open, and this is why it was split rather than bundled.
It means rendering each frame several times with the camera at sub-frame positions inside the shutter window and accumulating them. That is not a paint-pass change: it belongs in the encode loop, where
render_frame_task_scaledproduces one buffer per frame. It brings its own cost model — k× render time on every frame the camera moves — and its own question of where the sampling happens so the audio and frame accounting stay consistent.Bundling it into #400 would have made one PR that was really two, with the cheap half hostage to the expensive one.
LeadcodeDev commentedon Sep 29, 2026
Closing. Part 1 shipped in #400:
camera.rotate_x,rotate_yandperspective,applied once about the camera's origin and scaled by each plane's
style.depth.All three animate through
keyframes, andrules/camera-3d.mddocuments it.Part 2 — camera motion blur — is dropped rather than parked. It means rendering
each frame k times at sub-frame camera positions and accumulating them: a k×
cost on every frame the camera moves, in the encode loop rather than the paint
pass. That is a cost decision, and nothing is asking for it.
Reopen with a target k and an acceptable per-frame budget if it becomes wanted.