4. 相机 (Cameras) 与视图控制


文档摘要

相机 (Cameras) 与视图控制 Three.js 相机 (Cameras) 与视图控制详解 在 Three.js 中,相机是场景观察的视点,它决定了场景如何被渲染到屏幕上。理解相机及其控制方式对于创建引人入胜的 3D 体验至关重要。 相机类型 Three.js 提供了多种相机类型,每种相机都适用于不同的场景和需求。最常用的两种是: PerspectiveCamera(透视相机): 模拟人眼观察世界的方式,具有近大远小的透视效果。 OrthographicCamera(正交相机): 没有透视效果,物体的大小与距离无关,常用于 2D 游戏或 CAD 应用。 1.

4. 相机 (Cameras) 与视图控制

Three.js 相机 (Cameras) 与视图控制详解

在 Three.js 中,相机是场景观察的视点,它决定了场景如何被渲染到屏幕上。理解相机及其控制方式对于创建引人入胜的 3D 体验至关重要。

1. 相机类型

Three.js 提供了多种相机类型,每种相机都适用于不同的场景和需求。最常用的两种是:

  • PerspectiveCamera(透视相机): 模拟人眼观察世界的方式,具有近大远小的透视效果。

  • OrthographicCamera(正交相机): 没有透视效果,物体的大小与距离无关,常用于 2D 游戏或 CAD 应用。

1.1 PerspectiveCamera

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 个单位

1.2 OrthographicCamera

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;

2. 相机属性与方法

无论是哪种类型的相机,都有一些常用的属性和方法:

  • 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);

3. 视图控制 (Camera Controls)

Three.js 本身不提供内置的视图控制,但提供了许多第三方库来实现各种交互式相机控制。最常用的库是 OrbitControls

3.1 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(): 更新控制器。必须在渲染循环中调用。

3.2 其他控制方式

除了 OrbitControls,还有其他一些常用的视图控制方式:

  • TrackballControls: 类似于 OrbitControls,但允许更自由的旋转。

  • FirstPersonControls: 模拟第一人称视角,常用于游戏。

  • FlyControls: 允许相机像飞机一样飞行。

  • PointerLockControls: 将鼠标指针锁定在屏幕中心,常用于 FPS 游戏。

4. 相机控制流程图

以下是一个使用 OrbitControls 的相机控制流程图:

5. 代码实践:动态调整相机参数

以下是一个示例,演示如何动态调整相机的 fovaspect 属性:

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 界面,允许用户动态调整相机的 fovaspect 属性。当属性改变时,会调用 camera.updateProjectionMatrix() 更新投影矩阵,并重新设置渲染器的大小。

6. 总结

相机和视图控制是 Three.js 中非常重要的概念。通过选择合适的相机类型、调整相机属性和使用合适的视图控制库,可以创建出各种各样的 3D 体验。希望本文能够帮助你更好地理解 Three.js 中的相机和视图控制。


发布者: 作者: 转发
评论区 (0)
U