Camera
The scene camera, reached at scene.camera. It's a Node, so the full transform
surface works — position, eulerAngles, lookAt, forward. On top of that it exposes
projection reads and screen→world ray helpers for picking.
You never construct one: every Scene creates its own camera (overlays share the
parent's). In an ARScene the camera is driven by device tracking — read it, don't
place it.
At a glance
scene.camera.position = [0, 2, 4]
scene.camera.lookAt([0, 0.5, 0])
scene.addEventListener('touchstart', ev => {
const ray = scene.camera.getRay(ev.clientX, ev.clientY)
const hit = Physics.raycast(ray.origin, ray.dir)
if (hit) console.log('tapped', hit.node?.name)
})Projection reads
camera.fov // vertical field of view, DEGREES (read-only)
camera.horizontalFov // horizontal field of view, degrees (read-only)
camera.displaySize // [width, height] of the 3D viewport, px (read-only)
camera.projectionMatrix // Float32Array(16), live — the host updates it in place on resize/fov changeScreen → world rays
camera.getViewDirection(screenX, screenY): Vec3 // world-space ray direction through a screen point
camera.getRay(screenX, screenY): Ray // origin = camera.worldPosition, dir = view directionScreen coordinates are logical px — the same space as ev.clientX / ev.clientY. getRay
pairs directly with Physics.raycast for tap-picking; Ray is documented in
ray-plane-noise.
Note
there is no worldToScreen helper — the inverse projection is only available raw, via
projectionMatrix + the camera's worldMatrix.
Pitfalls
// ✗ moving the camera in an ARScene — tracking overwrites it every frame
arScene.camera.position = [0, 2, 4]
// ✓ move the WORLD instead: parent content under scene.root and place thatSee also
- Scene — where the camera comes from; overlays share it
- Node — the inherited transform surface (
position,lookAt,forward) - 3D physics & shapes — raycasting the rays you build here
- Ray, Plane, Noise — the
Rayreturned bygetRay