相机 (Cameras) 与视图控制 Three.js 相机 (Cameras) 与视图控制详解 在 Three.js 中,相机是场景观察的视点,它决定了场景如何被渲染到屏幕上。理解相机及其控制方式对于创建引人入胜的 3D 体验至关重要。 相机类型 Three.js 提供了多种相机类型,每种相机都适用于不同的场景和需求。最常用的两种是: PerspectiveCamera(透视相机): 模拟人眼观察世界的方式,具有近大远小的透视效果。 OrthographicCamera(正交相机): 没有透视效果,物体的大小与距离无关,常用于 2D 游戏或 CAD 应用。 1.
在 Three.js 中,相机是场景观察的视点,它决定了场景如何被渲染到屏幕上。理解相机及其控制方式对于创建引人入胜的 3D 体验至关重要。
Three.js 提供了多种相机类型,每种相机都适用于不同的场景和需求。最常用的两种是:
PerspectiveCamera(透视相机): 模拟人眼观察世界的方式,具有近大远小的透视效果。
OrthographicCamera(正交相机): 没有透视效果,物体的大小与距离无关,常用于 2D 游戏或 CAD 应用。
PerspectiveCamera 的构造函数如下:
THREE.PerspectiveCamera(fov, aspect, near, far);
fov (Field of View): 视野角度,以度数为单位,表示相机垂直方向的可视范围。常用的值是 45-75 度。
aspect (Aspect Ratio): 宽高比,通常是 canvas 的宽度除以高度。
near (Near Clipping Plane): 近裁剪面,表示相机能看到的最近距离。小于此距离的物体将被裁剪掉。
far (Far Clipping Plane): 远裁剪面,表示相机能看到的最远距离。大于此距离的物体将被裁剪掉。
代码示例:
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.z = 5; // 将相机沿 Z 轴移动 5 个单位
OrthographicCamera 的构造函数如下:
THREE.OrthographicCamera(left, right, top, bottom, near, far);
left, right: 相机左侧和右侧的坐标。
top, bottom: 相机顶部和底部的坐标。
near, far: 近裁剪面和远裁剪面,与 PerspectiveCamera 相同。
代码示例:
const aspect = window.innerWidth / window.innerHeight; const camera = new THREE.OrthographicCamera(-5 * aspect, 5 * aspect, 5, -5, 0.1, 1000); camera.position.z = 5;
无论是哪种类型的相机,都有一些常用的属性和方法:
position: 相机的位置,是一个 THREE.Vector3 对象。
rotation: 相机的旋转,是一个 THREE.Euler 对象。
quaternion: 使用四元数表示的旋转,可以避免万向锁问题。
lookAt(target): 使相机朝向目标点。target 可以是一个 THREE.Vector3 对象,也可以是一个 THREE.Object3D 对象。
updateProjectionMatrix(): 更新相机的投影矩阵。当修改了相机的 fov、aspect、near 或 far 属性后,需要调用此方法。
代码示例:
// 设置相机位置 camera.position.set(0, 2, 5); // 使相机朝向场景中心 camera.lookAt(0, 0, 0);
Three.js 本身不提供内置的视图控制,但提供了许多第三方库来实现各种交互式相机控制。最常用的库是 OrbitControls。
OrbitControls 允许用户通过鼠标或触摸来旋转、缩放和平移相机,围绕一个中心点进行观察。
安装:
npm install three @types/three npm install --save three-orbitcontrols
代码示例:
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'; // 创建 OrbitControls const controls = new OrbitControls(camera, renderer.domElement); // 启用阻尼,使相机移动更平滑 controls.enableDamping = true; controls.dampingFactor = 0.05; // 在渲染循环中更新 controls function animate() { requestAnimationFrame(animate); controls.update(); // 必须在渲染循环中调用 update() renderer.render(scene, camera); } animate();
OrbitControls 的常用属性和方法:
target: 相机围绕旋转的目标点,默认为场景中心 (0, 0, 0)。
minDistance: 相机到目标点的最小距离。
maxDistance: 相机到目标点的最大距离。
minPolarAngle: 相机垂直方向的最小角度(弧度)。
maxPolarAngle: 相机垂直方向的最大角度(弧度)。
minAzimuthAngle: 相机水平方向的最小角度(弧度)。
maxAzimuthAngle: 相机水平方向的最大角度(弧度)。
enableZoom: 是否允许缩放。
enablePan: 是否允许平移。
enableRotate: 是否允许旋转。
autoRotate: 是否自动旋转。
autoRotateSpeed: 自动旋转的速度。
update(): 更新控制器。必须在渲染循环中调用。
除了 OrbitControls,还有其他一些常用的视图控制方式:
TrackballControls: 类似于 OrbitControls,但允许更自由的旋转。
FirstPersonControls: 模拟第一人称视角,常用于游戏。
FlyControls: 允许相机像飞机一样飞行。
PointerLockControls: 将鼠标指针锁定在屏幕中心,常用于 FPS 游戏。
以下是一个使用 OrbitControls 的相机控制流程图:
以下是一个示例,演示如何动态调整相机的 fov 和 aspect 属性:
import * as THREE from 'three'; import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'; import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js'; // 创建场景 const scene = new THREE.Scene(); // 创建相机 const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.z = 5; // 创建渲染器 const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 创建 OrbitControls const controls = new OrbitControls(camera, renderer.domElement); controls.enableDamping = true; controls.dampingFactor = 0.05; // 创建一个立方体 const geometry = new THREE.BoxGeometry(); const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); const cube = new THREE.Mesh(geometry, material); scene.add(cube); // 创建 GUI 界面 const gui = new GUI(); const cameraFolder = gui.addFolder('Camera'); const params = { fov: camera.fov, aspect: camera.aspect }; cameraFolder.add(params, 'fov', 10, 120).onChange(function (value) { camera.fov = value; camera.updateProjectionMatrix(); }); cameraFolder.add(params, 'aspect', 0.5, 2).onChange(function (value) { camera.aspect = value; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); camera.updateProjectionMatrix(); }); cameraFolder.open(); // 渲染循环 function animate() { requestAnimationFrame(animate); controls.update(); renderer.render(scene, camera); } animate(); // 监听窗口大小改变 window.addEventListener('resize', function () { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); });
这个示例使用 lil-gui 库创建了一个 GUI 界面,允许用户动态调整相机的 fov 和 aspect 属性。当属性改变时,会调用 camera.updateProjectionMatrix() 更新投影矩阵,并重新设置渲染器的大小。
相机和视图控制是 Three.js 中非常重要的概念。通过选择合适的相机类型、调整相机属性和使用合适的视图控制库,可以创建出各种各样的 3D 体验。希望本文能够帮助你更好地理解 Three.js 中的相机和视图控制。