Three.js 快速入门教程【二】透视投影相机

系列文章目录

Three.js 快速入门教程【一】开启你的 3D Web 开发之旅
Three.js 快速入门教程【二】透视投影相机
Three.js 快速入门教程【三】渲染器


文章目录


一、前言

在 Three.js 创建的 3D 虚拟世界中,相机是我们观察场景的窗口。而透视投影相机(PerspectiveCamera)是 Three.js 里常用的相机类型之一,它模拟了人眼观察物体的方式,即近大远小,能为场景带来逼真的深度感。本篇文章将介绍透视投影相机在 Three.js 中的使用。


二、创建透视投影相机

javascript 复制代码
// 创建一个透视相机
const camera = new THREE.PerspectiveCamera(
  75, // 视场角(FOV)
  window.innerWidth / window.innerHeight, // 宽高比
  0.1, // 近裁剪面
  2000 // 远裁剪面
);

PerspectiveCamera( fov, aspect, near, far )参数介绍:

参数 说明 默认值
fov 视野角度(Field of View),指垂直方向上的视角,单位是度。通常设置为 45 - 75 度,类似人眼的视角范围,能让场景看起来自然。数值越大,视角越广,场景中的物体看起来越小;数值越小,视角越窄,物体看起来越大 50
aspect 宽高比,即渲染区域的宽度与高度之比。一般设置为Canvas画布宽高比width / height,确保场景在不同尺寸屏幕上正确显示 1
near 近裁剪面,相机能看到的最近距离。小于此距离的物体不会被渲染。设置过小可能导致近处物体出现闪烁或错误,需根据场景大小合理调整 0.1
far 远裁剪面,相机能看到的最远距离。大于此距离的物体不会被渲染。设置过大可能影响性能,因为 GPU 需要处理更多远处的物体。 2000

ps:表格中提到的Canvas画布指的是3d场景在网页上渲染的dom节点,它是个canvas,可通过渲染器的domElement属性获取。

javascript 复制代码
//创建渲染器
const renderer = new THREE.WebGLRenderer();
//获取dom
const canvas=renderer.domElement

三、位置设置

改变相机在3D场景中位置

1、通过camera.position.set(x,y,z),其中x,y,z分别代表3维坐标系中x轴、y轴、z轴坐标向量

javascript 复制代码
camera.position.set(5, 10, 30);

2、通过camera.position.属性设置,camera.position是一个THREE.Vector3对象(三维向量),有x、y、z三个属性

javascript 复制代码
camera.position.x = 5;
camera.position.y = 10;
camera.position.z = 30;

ps:相机默认位置在原点(0,0,0)


四、方向控制

设置相机方向,使得它的正前方指向某个方向。

通过camera.lookAt(x,y,z),让相机看向某个点

javascript 复制代码
camera.lookAt(0,10,30);

或传入一个三维向量对象

javascript 复制代码
const target = new THREE.Vector3( 0, 10, 30 );
camera.lookAt( target );

看向场景中一个物体:

javascript 复制代码
const mesh= new THREE.Mesh(
    new THREE.BoxGeometry(1, 1, 1),
    new THREE.MeshStandardMaterial({ color: 0x00ff00 })
);
scene.add(mesh);
camera.lookAt(mesh.position);

始终保持看向该物体:

javascript 复制代码
function animate() {
    requestAnimationFrame(animate);
    camera.lookAt(mesh.position);
    renderer.render(scene, camera);
}
animate();

ps:相机方向默认看向z轴负方向

知识点提前了解:z轴方向跟css z-index方向是一致的,人眼睛跟电脑屏幕垂直方向即为z轴,
向屏幕内为负,向屏幕外为正,屏幕宽方向为x轴,高方向为y轴

五、旋转相机

1、通过camera.rotation.set(x,y,z);

入参x,y,z以弧度为单位

javascript 复制代码
// 设置相机绕z轴旋转45度(转换为弧度),x轴和y轴不旋转
camera.rotation.set(0,0,Math.PI / 4,);

2、通过rotation属性旋转相机

rotation属性包含三个值,分别是绕 X、Y、Z 轴的旋转角度(以弧度为单位)

javascript 复制代码
//绕着x轴旋转45度
camera.rotation.x=Math.PI/4;
//绕着y轴旋转90度
camera.rotation.y=Math.PI/2;
//绕着z轴旋转60度
camera.rotation.z=Math.PI/3;

旋转顺序:默认XYZ(可通过camera.rotation.order修改)

javascript 复制代码
camera.rotation.order='YZX';

六、牛刀小试

下面实现一个小案例:通过鼠标滚轮实现相机缩放功能

代码示例:

javascript 复制代码
import * as THREE from "three";
//创建场景
const scene = new THREE.Scene();
//设置黑色背景色
scene.background = new THREE.Color(0x000000);

//创建一个球体
const geometry = new THREE.SphereGeometry(5);
//创建一个基础材质
const material = new THREE.MeshBasicMaterial({
  color: "#ff00ff",
});
//创建一个网格对象
const mesh = new THREE.Mesh(geometry, material);
//设置网格对象位置
mesh.position.set(0, 0, 0);
//添加到场景中
scene.add(mesh);

//创建相机
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);
//设置相机位置
camera.position.set(0, 10, 30);
//相机默认看向网格对象
camera.lookAt(mesh.position);

//创建渲染器
const renderer = new THREE.WebGLRenderer();
//设置渲染器尺寸为页面宽高
renderer.setSize(
  document.documentElement.clientWidth,
  document.documentElement.clientHeight
);
//将渲染器的 DOM 元素添加到页面中
document.body.appendChild(renderer.domElement);

// 循环动画
function animate() {
  // 定时刷新
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}
// 执行动画
animate();

//监听滚轮事件
window.addEventListener("wheel", (event) => {
  const speed = 1;
  if (event.deltaY > 0) {
    //缩小
    camera.position.z += speed;
  } else {
    //放大
    camera.position.z -= speed;
  }
});

运行效果:

说明:监听wheel事件,根据滚轮滚动方向调整相机的position.z值,position.z值越大相机离我们眼睛越近,离物体越远呈现视觉效果就是物体在缩小,反之在放大。

总结

透视投影相机是 Three.js 创建逼真 3D 场景的重要工具。通过掌握其创建、位置与方向控制以及与场景的交互,我们能为用户带来更丰富、沉浸式的 3D 体验。在实际应用中,需根据场景需求和用户体验,不断调整相机参数和交互逻辑,创造出令人满意的 3D 作品。

更多three.js入门知识点请关注该系列教程后续的更新。

相关推荐
软件开发技术局33 分钟前
撕碎QT面具(8):对控件采用自动增加函数(转到槽)的方式,发现函数不能被调用的解决方案
开发语言·qt
周杰伦fans2 小时前
C#中修饰符
开发语言·c#
yngsqq2 小时前
c# —— StringBuilder 类
java·开发语言
前端御书房2 小时前
前端PDF转图片技术调研实战指南:从踩坑到高可用方案的深度解析
前端·javascript
赔罪2 小时前
Python 高级特性-切片
开发语言·python
程序员黄同学3 小时前
请谈谈 Vue 中的响应式原理,如何实现?
前端·javascript·vue.js
子豪-中国机器人3 小时前
2月17日c语言框架
c语言·开发语言
夏天的阳光吖3 小时前
C++蓝桥杯基础篇(四)
开发语言·c++·蓝桥杯
oioihoii4 小时前
C++17 中的 std::to_chars 和 std::from_chars:高效且安全的字符串转换工具
开发语言·c++
宁波阿成4 小时前
vue3里组件的v-model:value与v-model的区别
前端·javascript·vue.js