PerspectiveCamera
是 Three.js 中最常用的摄像机之一,它使用透视投影来模拟人眼的视觉效果。透视摄像机通过设置视场角(FOV)、长宽比、近裁剪面、远裁剪面来决定场景中的物体如何被渲染。本文将详细介绍 PerspectiveCamera
的使用,涵盖其所有属性和方法,并结合实际示例代码帮助你掌握如何在项目中使用它。
PerspectiveCamera
?PerspectiveCamera
模拟人眼的透视效果,也就是离视点越远的物体看起来越小,近的物体看起来越大。这种摄像机广泛用于 3D 场景渲染和游戏中,能够让用户获得更真实的视觉体验。
PerspectiveCamera
的构造函数const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
window.innerWidth / window.innerHeight
,以匹配浏览器窗口的宽高比。要创建一个 PerspectiveCamera
,我们需要指定视场角、长宽比、近裁剪面和远裁剪面。
const fov = 75; // 视场角
const aspect = window.innerWidth / window.innerHeight; // 长宽比
const near = 0.1; // 近裁剪面
const far = 1000; // 远裁剪面
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
在上面的代码中,我们创建了一个视场角为 75 度,长宽比为窗口宽高比,近裁剪面为 0.1,远裁剪面为 1000 的透视摄像机。
默认情况下,摄像机会位于原点 (0, 0, 0),我们通常需要将它移出原点以便能够看到场景中的物体。可以使用 camera.position.set(x, y, z)
来设置摄像机的位置。
camera.position.set(0, 0, 5); // 设置摄像机在 z 轴上距离场景 5 个单位的位置
PerspectiveCamera
本质上是 Three.js 的 Object3D
,它可以像任何其他 3D 对象一样被添加到场景中。但是,通常不需要手动将摄像机添加到场景中,因为摄像机会自动应用于渲染器。
scene.add(camera); // 可选
通过 renderer.render(scene, camera)
方法,可以使用 PerspectiveCamera
渲染场景。
renderer.render(scene, camera);
PerspectiveCamera
创建完整示例让我们通过一个完整的示例来了解如何使用 PerspectiveCamera
。我们将在一个简单的 3D 场景中创建一个旋转的立方体,并使用透视摄像机来渲染场景。
// 初始化场景
const scene = new THREE.Scene();
// 创建透视摄像机
const fov = 75;
const aspect = window.innerWidth / window.innerHeight;
const near = 0.1;
const far = 1000;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.set(0, 0, 5);
// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 创建一个立方体
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
// 动画循环
function animate() {
requestAnimationFrame(animate);
// 旋转立方体
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
// 渲染场景
renderer.render(scene, camera);
}
animate();
在这个示例中,我们创建了一个透视摄像机,设置其位置,并创建了一个简单的立方体。通过动画循环,立方体不断旋转,并使用透视摄像机渲染场景。
PerspectiveCamera
的参数你可以在运行时动态调整 PerspectiveCamera
的参数,以实现一些特殊的视觉效果。
你可以通过修改摄像机的 fov
属性来动态调整视场角。例如,通过响应用户的滚轮事件来缩放场景:
window.addEventListener('wheel', (event) => {
camera.fov += event.deltaY * 0.05; // 滚轮控制视场角
camera.updateProjectionMatrix(); // 更新投影矩阵
});
当窗口大小发生变化时,摄像机的长宽比也需要更新以匹配新的窗口尺寸。可以通过以下代码来监听窗口大小的变化,并动态调整摄像机的长宽比:
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
Three.js 提供了 OrbitControls
,它允许用户通过鼠标拖拽、缩放来控制摄像机的视角。你可以将 OrbitControls
和 PerspectiveCamera
结合起来,创建更具交互性的 3D 场景。
首先,导入 OrbitControls
:
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
然后,在初始化摄像机之后,创建 OrbitControls
实例:
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true; // 启用阻尼效果
controls.dampingFactor = 0.25; // 阻尼系数
controls.enableZoom = true; // 启用缩放
在动画循环中调用 controls.update()
,以确保控制器的平滑操作:
function animate() {
requestAnimationFrame(animate);
controls.update(); // 更新控制器
renderer.render(scene, camera);
}
通过 OrbitControls
,用户可以交互式地缩放、旋转和拖拽摄像机视角。
你可以结合透视摄像机与光源,创建更为复杂的场景。以下是一个使用 DirectionalLight
的示例:
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(5, 5, 5);
scene.add(light);
// 创建带有材质和光照效果的立方体
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
在这个示例中,DirectionalLight
用于为场景提供照明,并且通过 MeshStandardMaterial
创建的立方体会受光源的影响。
PerspectiveCamera
的高级用法lookAt
方法PerspectiveCamera
可以通过 lookAt
方法将视角锁定到场景中的某个点。这对于需要固定观察某一目标的场景非常有用。
camera.lookAt(new THREE.Vector3(0, 0, 0)); // 使摄像机始终注视场景中心
在某些场景中,你可能需要在多个摄像机之间进行切换。你可以在渲染循环中动态切换不同的摄像机。
let usePerspective = true;
document.addEventListener('keydown', (event) => {
if (event.code === 'KeyC') {
usePerspective = !usePerspective;
}
});
function animate() {
requestAnimationFrame(animate);
if (usePerspective) {
renderer.render(scene, perspectiveCamera);
} else {
renderer.render(scene, orthographicCamera);
}
}
在这个示例中,我们通过按
下 C
键动态切换不同的摄像机视角。
PerspectiveCamera
是 Three.js 中使用最广泛的摄像机类型之一。它通过模拟人眼的透视效果,为我们提供了逼真的 3D 场景渲染体验。在实际应用中,我们可以结合轨道控制器、光照等其他组件,实现更丰富的交互效果。