Skip to content

BabylonJS - Cameras

In any 3D scene, the camera determines the viewpoint from which the world is rendered. Babylon.js offers a variety of camera types, each suited for different control schemes and experiences. A scene can contain multiple cameras, but only one camera can be ‘active’ at any given time, defining what the user sees.

All cameras inherit from BABYLON.Camera and share common properties like position, target (where the camera looks), minZ (near clipping plane), and maxZ (far clipping plane).

This is often the most versatile and commonly used camera for general scene viewing. It rotates around a central target point (target) at a specific distance (radius). Rotation is controlled by alpha (horizontal angle) and beta (vertical angle). It handles mouse, touch, and keyboard inputs automatically when attached to the canvas.

const camera = new BABYLON.ArcRotateCamera(
"arcCam", // Name
-Math.PI / 2, // Initial alpha (angle around Y axis)
Math.PI / 2.5, // Initial beta (angle around X axis)
10, // Initial radius (distance from target)
new BABYLON.Vector3(0, 1, 0), // Target position (e.g., center of an object)
scene
);
// Attach controls to the canvas
camera.attachControl(canvas, true); // 'true' prevents default browser actions on input
// Optional: Customize limits
camera.lowerRadiusLimit = 5;
camera.upperRadiusLimit = 50;
camera.upperBetaLimit = Math.PI / 2; // Prevent going below ground

Ideal for first-person perspectives (like FPS games). It moves freely in 3D space, controlled typically by keyboard (WASD) for movement and mouse for looking around. You define its initial position and optionally its target.

const camera = new BABYLON.FreeCamera(
"freeCam",
new BABYLON.Vector3(0, 1.8, -10), // Initial position (e.g., eye level)
scene
);
// Set the initial target (optional, defaults to Z+ direction)
camera.setTarget(BABYLON.Vector3.Zero());
camera.attachControl(canvas, true);
// Optional: Adjust movement speed and sensitivity
camera.speed = 0.5;
camera.angularSensibility = 5000;

Designed to follow a specific mesh (target). It maintains a set distance (radius), height (heightAbove), and rotation angle (rotationOffset) relative to the target mesh, smoothly tracking its movement. Great for third-person games.

// Assuming 'playerMesh' is the mesh to follow
const camera = new BABYLON.FollowCamera(
"followCam",
new BABYLON.Vector3(0, 10, -10), // Initial position (will adjust to target)
scene
);
// Set the target to follow
camera.lockedTarget = playerMesh; // The mesh to follow
// Configure follow parameters
camera.radius = 8; // Distance from target
camera.heightOffset = 4; // Height above target
camera.rotationOffset = 0; // Angle relative to target's back (0 = directly behind)
camera.cameraAcceleration = 0.05; // How fast camera catches up
camera.maxCameraSpeed = 10; // Max speed
camera.attachControl(canvas, true); // Still allows some manual rotation if needed

Uses the mobile device’s orientation sensors (gyroscope, accelerometer) to control camera rotation. Tilting the device looks around the scene. Based on FreeCamera.

const camera = new BABYLON.DeviceOrientationCamera(
"devOrientCam",
new BABYLON.Vector3(0, 1, -5),
scene
);
camera.attachControl(canvas, true);
// Note: Requires HTTPS and user permission to access device orientation.

For creating Virtual Reality (VR) and Augmented Reality (AR) experiences, Babylon.js uses the WebXR standard. The WebXRDefaultExperience helper simplifies setting up VR/AR sessions.

This isn’t a camera itself, but it creates and manages the necessary WebXRCamera, controllers, teleportation, and UI elements for a standard WebXR session.

// Inside an async function or .then() block as WebXR setup is asynchronous
async function setupWebXR() {
try {
const xrHelper = await scene.createDefaultXRExperienceAsync({
// Options like floorMeshes, uiOptions, inputOptions etc.
floorMeshes: [ground] // Example: Specify ground for teleportation
});
if (!xrHelper.baseExperience) {
console.log("WebXR not supported on this device.");
} else {
console.log("WebXR experience ready.");
// The xrHelper manages the WebXRCamera internally.
// You don't usually interact with xrHelper.camera directly unless needed.
}
} catch (error) {
console.error("Error setting up WebXR:", error);
}
}
// Call the setup function (e.g., after scene is created)
setupWebXR();
// Note: WebXR requires HTTPS and specific browser flags or device support.
  • TouchCamera: Older camera specifically for touch input, largely superseded by the built-in touch controls of ArcRotateCamera and FreeCamera.
  • GamepadCamera: A FreeCamera variant specifically designed for gamepad input.
  • VirtualJoysticksCamera: A FreeCamera controlled by on-screen virtual joysticks.
  • Anaglyph Cameras: (AnaglyphArcRotateCamera, AnaglyphFreeCamera) Used for stereoscopic 3D effects with red/cyan glasses (often implemented as post-processes now).
  • Stereoscopic Cameras: Similar to Anaglyph, but for different stereo viewing methods.

You can change the active camera at runtime by setting scene.activeCamera.

// Assuming scene has camera1 and camera2 already created
// Make camera2 the active one
scene.activeCamera = camera2;
// Remember to attach controls for the newly active camera if needed
camera2.attachControl(canvas, true);
// Detach controls from the old camera (good practice)
camera1.detachControl(canvas);

camera.attachControl(canvas, preventDefault) enables the default input mechanisms (mouse, touch, keyboard, etc.) for the camera type. camera.detachControl(canvas) disables them.

You can customize or replace the default input handling using the camera.inputs manager. This allows fine-grained control over which inputs are active and how they behave.

// Example: Disable mouse wheel zoom on ArcRotateCamera
if (camera.inputs.attached.mousewheel) {
camera.inputs.remove(camera.inputs.attached.mousewheel);
}
// Example: Change keyboard keys for FreeCamera
if (camera.inputs.attached.keyboard) {
const keyboardInput = camera.inputs.attached.keyboard;
keyboardInput.keysUp = [87]; // W key
keyboardInput.keysDown = [83]; // S key
keyboardInput.keysLeft = [65]; // A key
keyboardInput.keysRight = [68]; // D key
}