Cameras in 3D
Create named cameras in the same space as your artwork. One camera supplies the view at a time. Move it to reveal depth, change its lens to reframe, or blend to another moving camera without rendering two images.
@version 5
size: (1920, 1080)
fill: "#101522"
imagine lens
camera: perspective
focalLength: 50
sensorHeight: 24
near: 1
far: 10000
imagine headline
text: "A new perspective."
fontSize: 100
fill: "#ffffff"
create headline as title
create lens as wide
active: true
position: (0, 0, 2250)
lookAt: title
animate active
0s: true
2s: false
4s: true
create lens as detail
active: false
position: (300, 120, 900)
lookAt: title.glyph(-1)
animate position.z from 900 to 650 over 5s
ease: "ease-in-out"
animate active
0s: false
2s: true
4s: false
animate pose from wide to detail over 0.6s
delay: 2s
ease: "ease-in-out"Pose and lens
Coordinates are scene units, with Y up. A camera with zero rotation looks along its local negative Z axis. Rotation uses the same clockwise XYZ degrees as artwork. Parent a camera under a group to build an orbit or travelling rig. Parent scale affects position; orientation follows the rig's rigid rotations and lens values stay unchanged. Zero or nonfinite scale is invalid.
Artwork parented to a camera rides its full orientation, including lookAt,
up and roll. A layer at local (0, 0, -1650) stays centred in the view
while the camera aims around. Glyph targets resolve during rendering, so
children of a camera aimed at name.glyph(index) aim at that text instance's
anchor instead.
Choose free rotation, or lookAt with optional up and roll. Do not combine
both controls. lookAt accepts a world (x, y, z) point, a unique instance name,
or name.glyph(index). Negative glyph indices count from the last shaped glyph.
An instance target follows its world anchor. A glyph target follows its current
ink centre, including glyph animation. Whitespace has no ink target. Hidden and
offscreen targets still prepare their layout. Missing or ambiguous targets,
self/dependent camera targets and coincident camera/target positions are errors.
At an up-vector pole, orientation uses a deterministic world-axis fallback.
targetOffset is an XYZ vector in target-local units for instance/glyph targets,
or world units for point targets. up defaults to (0, 1, 0) in world space.
roll rotates clockwise around the target direction, in degrees.
| Property | Perspective | Orthographic |
|---|---|---|
camera |
perspective |
orthographic |
| Lens | focalLength: 50, sensorHeight: 24 in millimetres, or vertical fov in degrees |
orthoHeight, default scene height |
near / far |
1 / 10000 |
1 / 10000 |
Lens and clipping values can animate. Use fov or focalLength, never both.
All lengths must be finite and positive; 0 < fov < 180 and near < far.
Projection is fixed for each camera. Without an authored position or rig
transform, the default camera frames the scene at Z=0 using its numeric rest
lens values: a longer lens stands further back, so two unpositioned cameras
with different focal lengths show the Z=0 plane at the same size and differ
only in depth. Give each camera a position when a lens change should reframe.
Lens animation does not implicitly move the camera. Set position
explicitly when driving the base lens with an expression. Higher export pixel
density does not change the view. Aspect ratio determines horizontal extent.
There is no depth of field.
Activation and ordinary animation
active is an ordinary boolean property on a camera. Exactly one camera must
resolve to true at the sampled scene time. Multiple active cameras, no active
camera, and nonboolean values produce diagnostics. A single camera is inferred
only when active is unspecified; explicit false never falls back to true.
Blueprint activation is inherited normally, so activating a shared blueprint
can create a conflict between its instances. Visibility does not select a view.
Animate active with ordinary keys or expressions. Boolean keys switch at their
exact time, independently of easing overshoot or hold. Delay, repeat, direction
and speed use the existing animation engine. Activation and pose tracks use
exact scene time even when artwork has reduced FPS. Normal position/lens tracks retain their
existing FPS sampling. All cameras resolve before selecting the view, so a
simultaneous off/on change is atomic and backward seeks are deterministic.
Camera transforms and lenses use the existing animation blend modes. For
example, an additive position animation can layer shake over a travelling rig.
To move between complete live camera views, animate pose between camera names
as in the example above. The same engine owns keyframe interpolation, easing,
delay, speed, repetition and composition. Use its existing blend: mix and
weight options to layer a pose animation over the camera's base view. pose
itself can reference a camera as that base view. Complete poses support
replace and mix; apply add and multiply to individual numeric channels.
Pose references read each endpoint's current authored world transform, target and lens, including animation. They do not recursively follow the endpoint's own pose track. Self references therefore mean the camera's authored pose, not a dependency cycle. A pose track changes the effective view; it does not move scene nodes or artwork parented to the endpoint cameras.
The value interpolator uses shortest-path quaternion rotation, interpolated
position/lens/clipping values and bounded progress. Only matching projections
can interpolate. A held pose key or an active switch can cut between projection
types. One view is rendered throughout; this is not an image crossfade.
Camera animation ends contribute to ordinary scene duration. References bind to instance identity and save using current names.
Surfaces, effects and output
Opaque artwork writes surface depth, including text, strokes, images and copies. Antialiased edges and translucent paint test depth but do not write solid depth. Coplanar surfaces use authored layer order without changing world positions. Artwork remains double-sided. Unfiltered groups keep their children's depths.
Fully covered pixels resolve by depth whatever the draw order, so text or a
group with opacity below 1 on a turned opaque card keeps its antialiased edges.
Transparent surfaces and antialiased edges blend back to front over them.
Intersecting translucent surfaces can have ordering artifacts. An isolated filtered group is one
composition unit: its original surface depth survives the color filters, while
added halos do not write solid depth. Interleaving translucent surfaces across
filtered groups is approximate. Screen-space distortions do not create new
physical geometry. Root effects apply after composition.
A filtered group's effect covers its projected on-screen bounds plus the
effect's own padding, as in 2D. Effect sizes such as dotSize, cellSize or a
blur radius are scene units measured at the group's depth, so a halftone dot
shrinks with the poster as it moves away. Root effects measure sizes in stage
units: size spans the output, like a 2D scene. Content whose painted area is
only known on the GPU (copies, animated glyphs) or that crosses the near plane
processes the whole view.
Root fill is the output background. It does not rotate as a finite panel. Nested frames remain world-space clipping geometry. Keep essential content between the near and far planes; inspect reports partial clipping for near-plane crossings.
Tools and compatibility
Files from format 4 retain their host view when opened. Older editors that support only format 4 cannot open files saved as format 5. Editing navigation keeps its own orthographic camera; playback and exports use the authored view. This release adds no visual camera panels or gizmos.