文章目录
- 1. 引言:为什么相机是 3D 场景的“眼睛”?
- 1.1 相机的核心作用
- 1.2 常见相机类型概览
- 2. 相机基础参数解析
- 2.1 通用属性
- 2.2 相机坐标系
- 3. 详解常用相机类型
- 3.1 自由相机(FreeCamera)
- 3.2 弧形旋转相机(ArcRotateCamera)
- 3.3 跟随相机(FollowCamera)
- 3.4 其他相机类型(快速概览)
- 4. 视角交互实战技巧
- 4.1 多相机切换
- 4.2 自定义输入控制
- 4.3 相机动画与过渡
- 5. 相机性能优化与调试
- 5.1 视锥剔除(Frustum Culling)
- 5.2 避免过度绘制
- 5.3 使用调试工具
- 6. 实战任务
- 任务 1:构建可切换的相机系统
- 任务 2:实现“物体聚焦”功能
- 7. 常见问题解答
- 8. 总结与下一章预告
- 8.1 关键知识点回顾
- 8.2 下一章预告
1. 引言:为什么相机是 3D 场景的“眼睛”?
- 上一章简单介绍了场景中如何添加标准形状的物体,并且介绍了如何调整物体属性,包括位置、旋转、缩放,以及父级关系的设置。
- 这一章详细介绍一下Babylon中,相机相关的知识。涵盖相机类型、交互配置及实战技巧。
1.1 相机的核心作用
- 定义用户视角:观察场景的位置、方向、视野范围。
- 交互基础:通过鼠标/键盘/触控控制视角移动。
1.2 常见相机类型概览
- 自由相机(
FreeCamera
) - 弧形旋转相机(
ArcRotateCamera
) - 跟随相机(
FollowCamera
) - 第一人称相机(
UniversalCamera
)
2. 相机基础参数解析
2.1 通用属性
- 位置(Position):
camera.position = new BABYLON.Vector3(x, y, z)
。 - 目标(Target):
camera.setTarget(new BABYLON.Vector3(x, y, z))
。 - 视野(FOV):
camera.fov = 0.8
(弧度制,影响广角效果)。 - 近裁面与远裁面(Clipping Planes):
camera.minZ = 0.1; // 近裁面(避免渲染过近物体)camera.maxZ = 1000; // 远裁面(避免渲染过远物体)
2.2 相机坐标系
- 局部坐标系:相机的移动方向基于自身朝向。
- 世界坐标系:相机的移动方向基于全局坐标轴。
3. 详解常用相机类型
3.1 自由相机(FreeCamera)
- 特点:类似第一人称射击游戏的自由移动视角。
- 代码创建:
const freeCamera= new BABYLON.FreeCamera("freeCamera", new BABYLON.Vector3(0, 5, -10), scene);freeCamera.setTarget(BABYLON.Vector3.Zero());
- 控制配置:
- 键盘移动:默认 WASD 控制前后左右,QE 控制升降。
- 鼠标控制视角:
camera.attachControl(canvas, true)
。 - 灵敏度调整:
freeCamera.speed = 0.5; // 移动速度freeCamera.angularSensibility = 2000; // 鼠标灵敏度(值越大越迟钝)
- 其他相机配置参数:
// 相机反转freeCamera.invertRotation = true;// 相机转动速度freeCamera.inverseRotationSpeed = 3;// 相机y轴角度freeCamera.rotation.y = (rotation * Math.PI) / 180;// 添加滚轮输入freeCamera.inputs.addMouseWheel();// 开启触摸控制freeCamera.inputs.attached.mouse.touchEnabled = true;// 鼠标输入灵敏度。(默认值为2000.0)值越高,灵敏度越低。freeCamera.angularSensibility = 1300;// 定义摄像头可以看到的最小距离 太小会闪面freeCamera.minZ = 10;// 定义摄像头可以看到的最大距离freeCamera.maxZ = 20000;// 广角freeCamera.fov = 1.6;// 定义相机的默认惯性。这有助于使相机运动平稳freeCamera.inertia = 0.8// 设置相机每个窗口的大小freeCamera.viewport = new BABYLON.Viewport(0, 0, 1, 1);
3.2 弧形旋转相机(ArcRotateCamera)
- 特点:围绕目标点旋转、缩放,适合展示物体。
- 代码创建:
const arcRotatecamera = new BABYLON.ArcRotateCamera("arcCam", alpha, beta, radius, // 初始角度(弧度)、半径target, // 目标点(Vector3)scene);arcRotatecamera.attachControl(canvas, true);
- 其他相机配置参数:
// 最大移动距离arcRotatecamera.upperRadiusLimit = 50000;// 最小移动距离arcRotatecamera.lowerRadiusLimit = 10000;// 角度灵敏度XarcRotatecamera.angularSensibilityX = 5000;// 角度灵敏度YarcRotatecamera.angularSensibilityY = 5000;// 平移灵敏度arcRotatecamera.panningSensibility = 8000;// Beta角上限arcRotatecamera.upperBetaLimit = 0;// Beta角上限arcRotatecamera.lowerBetaLimit = 0;// 纵轴最大角度,限制摄影机在场景中的移动arcRotatecamera.upperAlphaLimit = 0;// 纵轴最小角度arcRotatecamera.lowerAlphaLimit = 0;// 允许上下颠倒arcRotatecamera.allowUpsideDown = false;// 滚轮精度arcRotatecamera.wheelPrecision = 0.01;// 指针捏合精度arcRotatecamera.pinchPrecision = 0.01;// 使用自然捏缩放arcRotatecamera.useNaturalPinchZoom = false;// 广角arcRotatecamera.fov = 0.5;// 照相机渲染的最大距离arcRotatecamera.maxZ = 100000;// 照相机渲染的最小距离 太小会闪面arcRotatecamera.minZ = 5;// 让视图相机倾斜一点角度arcRotatecamera.alpha = 0;arcRotatecamera.beta = 0;// 设置相机每个窗口的大小arcRotatecamera.viewport = new BABYLON.Viewport(0, 0, 1, 1);
这里将 弧形旋转相机 和 自由相机 做对比,对于同一个场景,可见 自由相机 对场景有拉伸效果,甚至对场景的显示效果都有影响。
因此,选择适合自己的相机格外重要。
- 关键参数:
- 限制旋转角度:
camera.lowerBetaLimit = 0.1; camera.upperBetaLimit = Math.PI/2
。 - 限制缩放范围:
camera.lowerRadiusLimit = 5; camera.upRadiusLimit = 20
。
- 限制旋转角度:
- 交互优化:
- 启用惯性效果:
camera.inertia = 0.9
(拖拽后平滑停止)。
- 启用惯性效果:
3.3 跟随相机(FollowCamera)
- 特点:跟随某个物体移动,适合角色扮演游戏。
- 代码创建:
const camera = new BABYLON.FollowCamera("followCam", new BABYLON.Vector3(0, 5, -10), // 初始位置scene);camera.radius = 10; // 跟随距离camera.heightOffset = 2; // 垂直偏移camera.lockedTarget = playerMesh; // 绑定目标物体
3.4 其他相机类型(快速概览)
- 第一人称相机(UniversalCamera):针对移动端优化的自由相机。
- VR 设备相机(WebXRCamera):通过 WebXR 支持 VR 头显。
4. 视角交互实战技巧
4.1 多相机切换
- 代码示例:
const camera1 = new BABYLON.FreeCamera(...);const camera2 = new BABYLON.ArcRotateCamera(...);scene.activeCamera = camera1; // 切换活动相机
4.2 自定义输入控制
- 覆盖默认按键事件:
camera.keysUp = [87]; // W 键前进camera.keysDown = [83]; // S 键后退camera.keysLeft = [65]; // A 键左移camera.keysRight = [68]; // D 键右移
- 添加鼠标滚轮缩放(适用于
ArcRotateCamera
):
camera.wheelPrecision = 50; // 滚轮灵敏度
4.3 相机动画与过渡
- 平滑移动相机到新位置:
BABYLON.Animation.CreateAndStartAnimation("camMove", camera, "position",30, 120, // 帧率、总帧数camera.position, // 起始位置new BABYLON.Vector3(10, 5, 0), // 目标位置BABYLON.Animation.ANIMATIONLOOPMODE_CONSTANT);
5. 相机性能优化与调试
5.1 视锥剔除(Frustum Culling)
- 原理:只渲染相机视野内的物体。
- Babylon.js 默认启用,可通过
mesh.isVisible = false
手动控制。
5.2 避免过度绘制
- 调整
maxZ
值,减少远处物体渲染。
5.3 使用调试工具
- 显示相机视锥:
camera.showFrustum = true; // 显示视锥线框
- 实时调试参数:通过
scene.debugLayer
调整相机属性。
6. 实战任务
任务 1:构建可切换的相机系统
- 场景中放置两个相机:自由相机(默认)和弧形旋转相机。
- 按空格键切换相机,并添加过渡动画。
我这里添加了两个按钮,用来切换相机,其中使用 弧形旋转相机 ArcRotateCamera 模拟了上帝视角。
任务 2:实现“物体聚焦”功能
- 点击场景中的物体,弧形旋转相机自动对准该物体并调整距离。
mesh.actionManager = new BABYLON.ActionManager(scene);mesh.actionManager.registerAction(new BABYLON.ExecuteCodeAction(BABYLON.ActionManager.OnPickTrigger,() => {arcCamera.setTarget(mesh.position);arcCamera.radius = mesh.getBoundingInfo().diagonalLength * 2;}));
7. 常见问题解答
- Q1:相机看不到物体?
- 检查相机位置与目标点是否在物体附近。
- 确认物体的位置未被其他物体遮挡。
- Q2:移动端触控不灵敏?
- 调整
angularSensibility
和wheelPrecision
。 - 使用
UniversalCamera
替代FreeCamera
。
- 调整
8. 总结与下一章预告
8.1 关键知识点回顾
- 自由相机、弧形旋转相机的适用场景与控制优化。
- 多相机切换与自定义交互逻辑。
8.2 下一章预告
- 《灯光与阴影:让场景栩栩如生的关键》:学习点光源、方向光与阴影渲染技术。