Skip to content

Cameras

A camera defines the viewpoint a SceneView renders from. Flutter Scene gives you a quick declarative camera for simple cases, a camera that lives in the scene graph as a component for richer setups, and a sensible default so a scene always renders.

In the demo below, three CameraComponents view the same scene from different angles. The buttons switch which one is the scene’s primary camera.

Three cameras on nodes. The buttons switch the primary camera with makeActive.

The simplest camera is a PerspectiveCamera you hand to the view. Pass a fixed one for a still viewpoint.

SceneView(
scene,
camera: PerspectiveCamera(
position: vm.Vector3(0, 2, 5),
target: vm.Vector3.zero(),
),
)

For a camera that moves over time, use cameraBuilder, which receives the elapsed time each frame. This is what the earlier guides use to orbit the view.

SceneView(
scene,
cameraBuilder: (elapsed) {
final t = elapsed.inMicroseconds / 1e6;
return PerspectiveCamera(
position: vm.Vector3(sin(t) * 5, 2, cos(t) * 5),
target: vm.Vector3.zero(),
);
},
)

PerspectiveCamera takes position, target, and up, plus fovRadiansY, fovNear, and fovFar for the lens.

A camera can also live in the scene as a CameraComponent on a node. The node’s transform drives the view, so the camera moves, rotates, parents, and animates like anything else in the graph. Aim it by positioning its node.

final cameraNode = Node()..addComponent(CameraComponent());
scene.add(cameraNode);

The scene tracks a single primary camera, Scene.camera. The first CameraComponent mounted into the scene becomes the primary automatically, so adding one camera is all most scenes need. To select a different one, call makeActive, or assign Scene.camera directly (with any Camera, including a plain PerspectiveCamera).

secondCamera.makeActive(); // make this component the primary
scene.camera = PerspectiveCamera(position: vm.Vector3(0, 10, 0)); // or set one directly
scene.camera = null; // clear the override; revert to the first mounted camera

A SceneView given no camera, cameraBuilder, or viewsBuilder renders through the primary camera, so it follows whatever you select.

SceneView(scene) // uses Scene.camera

When a scene has no camera set up at all, a bare SceneView(scene) still renders, through a built-in default camera that frames content placed near the origin. So you always see something, even before you add a camera.

To show your own placeholder instead of the default while you set a scene up, gate the view on your own state, or assign Scene.camera as soon as you have one.

To render the same scene from more than one camera at once, the most Flutter-native way is to lay out multiple SceneView widgets, each given its own camera. Split-screen is a Row of two views; picture-in-picture is a Stack with a small view on top. Flutter handles the layout, sizing, and input.

For several viewports composited into one canvas with per-frame control, SceneView also takes a viewsBuilder that returns a list of RenderViews, each pairing a camera with a viewport rectangle.

Camera, PerspectiveCamera, CameraComponent, Scene, and SceneView.