Skip to content

BabylonJS - 摄像机

在任何 3D 场景中,相机决定了世界的渲染视角。Babylon.js 提供了多种相机类型,每种都适用于不同的控制方案和体验。一个场景可以包含多个相机,但任何时候只能有一个相机是“活动”的,决定了用户看到的内容。

所有相机都继承自 BABYLON.Camera,并共享共同的属性,如 position(位置)、target(相机看向哪里)、minZ(近裁剪面)和 maxZ(远裁剪面)。

这是用于一般场景查看的最通用和最常用的相机。它绕着一个中心目标点 (target) 以特定距离 (radius) 旋转。旋转由 alpha(水平角度)和 beta(垂直角度)控制。当附加到画布时,它会自动处理鼠标、触摸和键盘输入。

const camera = new BABYLON.ArcRotateCamera(
"arcCam", // 名称
-Math.PI / 2, // 初始 alpha (绕 Y 轴的角度)
Math.PI / 2.5, // 初始 beta (绕 X 轴的角度)
10, // 初始 radius (距目标的距离)
new BABYLON.Vector3(0, 1, 0), // 目标位置 (例如,物体的中心)
scene
);
// 将控制附加到画布
camera.attachControl(canvas, true); // 'true' 阻止默认浏览器输入行为
// 可选:自定义限制
camera.lowerRadiusLimit = 5;
camera.upperRadiusLimit = 50;
camera.upperBetaLimit = Math.PI / 2; // 阻止低于地面

非常适合第一人称视角(如 FPS 游戏)。它在 3D 空间中自由移动,通常由键盘(WASD)控制移动,鼠标控制环顾。你定义其初始位置和可选的目标点。

const camera = new BABYLON.FreeCamera(
"freeCam",
new BABYLON.Vector3(0, 1.8, -10), // 初始位置 (例如,眼睛高度)
scene
);
// 设置初始目标 (可选,默认为 Z+ 方向)
camera.setTarget(BABYLON.Vector3.Zero());
camera.attachControl(canvas, true);
// 可选:调整移动速度和敏感度
camera.speed = 0.5;
camera.angularSensibility = 5000;

旨在跟随特定的网格(目标)。它保持与目标网格设定的距离 (radius)、高度 (heightAbove) 和旋转角度 (rotationOffset),平滑地跟踪其移动。非常适合第三人称游戏。

// 假设 'playerMesh' 是要跟随的网格
const camera = new BABYLON.FollowCamera(
"followCam",
new BABYLON.Vector3(0, 10, -10), // 初始位置 (将调整到目标位置)
scene
);
// 设置要跟随的目标
camera.lockedTarget = playerMesh; // 要跟随的网格
// 配置跟随参数
camera.radius = 8; // 距目标的距离
camera.heightOffset = 4; // 高于目标的高度
camera.rotationOffset = 0; // 相对于目标背后的角度 (0 = 正后方)
camera.cameraAcceleration = 0.05; // 相机追赶的速度
camera.maxCameraSpeed = 10; // 最大速度
camera.attachControl(canvas, true); // 如果需要,仍然允许一些手动旋转

4. DeviceOrientationCamera (设备方向相机)

Section titled “4. DeviceOrientationCamera (设备方向相机)”

使用移动设备的 ориентация 传感器(陀螺仪、加速度计)来控制相机旋转。倾斜设备可以环顾场景。基于 FreeCamera。

const camera = new BABYLON.DeviceOrientationCamera(
"devOrientCam",
new BABYLON.Vector3(0, 1, -5),
scene
);
camera.attachControl(canvas, true);
// 注意:需要 HTTPS 和用户权限才能访问设备方向。

为了创建虚拟现实 (VR) 和增强现实 (AR) 体验,Babylon.js 使用 WebXR 标准。WebXRDefaultExperience 辅助类简化了 VR/AR 会话的设置。

这本身不是一个相机,但它创建并管理标准的 WebXR 会话所需的 WebXRCamera、控制器、传送和 UI 元素。

// 在异步函数或 .then() 块内,因为 WebXR 设置是异步的
async function setupWebXR() {
try {
const xrHelper = await scene.createDefaultXRExperienceAsync({
// 选项,如 floorMeshes, uiOptions, inputOptions 等等
floorMeshes: [ground] // 示例:指定用于传送的地面
});
if (!xrHelper.baseExperience) {
console.log("WebXR not supported on this device.");
} else {
console.log("WebXR experience ready.");
// xrHelper 在内部管理 WebXRCamera。
// 除非有必要,你通常不需要直接与 xrHelper.camera 交互。
}
} catch (error) {
console.error("Error setting up WebXR:", error);
}
}
// 调用设置函数(例如,在场景创建后)
setupWebXR();
// 注意:WebXR 需要 HTTPS 和特定的浏览器标志或设备支持。
  • TouchCamera (触摸相机):专门用于触摸输入的旧相机,很大程度上已被 ArcRotateCamera 和 FreeCamera 内置的触摸控制取代。
  • GamepadCamera (手柄相机):FreeCamera 的变体,专门为手柄输入设计。
  • VirtualJoysticksCamera (虚拟摇杆相机):通过屏幕虚拟摇杆控制的 FreeCamera。
  • Anaglyph Cameras (红蓝立体相机):(AnaglyphArcRotateCamera, AnaglyphFreeCamera) 用于使用红/青色眼镜实现立体 3D 效果(现在通常作为后期处理实现)。
  • Stereoscopic Cameras (立体相机):类似于红蓝立体相机,但用于不同的立体观看方法。

你可以在运行时通过设置 scene.activeCamera 来更改活动相机。

// 假设场景中已经创建了 camera1 和 camera2
// 将 camera2 设置为活动相机
scene.activeCamera = camera2;
// 记住为新活动的相机附加控制(如果需要)
camera2.attachControl(canvas, true);
// 分离旧相机的控制(良好实践)
camera1.detachControl(canvas);

camera.attachControl(canvas, preventDefault) 为相机类型启用默认的输入机制(鼠标、触摸、键盘等)。camera.detachControl(canvas) 禁用它们。

你可以使用 camera.inputs 管理器自定义或替换默认的输入处理。这允许对哪些输入处于活动状态以及它们的行为方式进行细粒度控制。

// 示例:在 ArcRotateCamera 上禁用鼠标滚轮缩放
if (camera.inputs.attached.mousewheel) {
camera.inputs.remove(camera.inputs.attached.mousewheel);
}
// 示例:更改 FreeCamera 的键盘按键
if (camera.inputs.attached.keyboard) {
const keyboardInput = camera.inputs.attached.keyboard;
keyboardInput.keysUp = [87]; // W 键
keyboardInput.keysDown = [83]; // S 键
keyboardInput.keysLeft = [65]; // A 键
keyboardInput.keysRight = [68]; // D 键
}