Three.js-硬要自学系列21 (相机动画、旋转渲染、管道漫游)

586 阅读4分钟

本章主要学习知识点

  • 学习如何操作摄像机运动
  • 了解如何旋转相机进行渲染
  • 了解管道漫游实现原理,并练习实操

相机动画

相机动画可以理解为「让3D场景的虚拟镜头动起来」,就像电影中的运镜效果。

通过移动摄像机位置或调整镜头参数,我们可以实现:

  • 环绕观察:让镜头围绕物体旋转,类似无人机环绕拍摄
  • 推拉镜头:从远处逐渐靠近物体(放大)或后退远离(缩小)
  • 视角切换:从俯视切换到平视,展示不同角度的场景细节

修改相机动画的三种方式

1、直接修改相机参数 (适合简单的动画)

看看下面这个环绕运动

angle += 0.002;
// 在XOZ面上做圆周运动
camera.position.x = R * Math.cos(angle);
camera.position.z = R * Math.sin(angle);
camera.lookAt(0,0,0);

13.gif

这种方式适合直线运动、匀速旋转等基础动画

2、使用Tween.js库 (适合复杂动画)
new TWEEN.Tween(camera.position) 
.to({ x: 200 }, 3000) 
.easing(TWEEN.Easing.Quadratic.InOut) // 缓动效果 
.start(); // 循环更新Tween动画 

function animate() { 
    TWEEN.update();
    requestAnimationFrame(animate);
}

这种方式适合具有弹性、反弹等高级缓动效果动画

3、路径动画 (沿预定轨迹运动)
  • 定义运动路径 (如贝塞尔曲线)
  • 通过插值计算相机位置
const path = new THREE.CurvePath(); 
path.add(new THREE.LineCurve3(startPoint, endPoint)); // 添加路径段 
const t = 0.5; // 路径进度(0~1) 
const point = path.getPoint(t); // 获取中点坐标 
camera.position.copy(point);

这种方式适合沿复杂轨迹飞行或环绕的动画

相机运动的使用场景

场景实现方案效果示例
产品展示环绕动画 + 缓动360°旋转查看商品细节
地图漫游路径动画 + 键盘控制第一人称视角游览3D城市
过场切换相机位置插值镜头从全景推近到特写
交互式教学点击触发相机位移点击按钮切换解剖模型视角

旋转渲染

你可以理解为现实中我们扭动我们头从不同的角度观看同一事物,而不是移动我们自身

在THREE.js中是通过调整camera.up来实现相机角度姿态改变的,默认是Y轴朝上(0,1,0)

为了能更好的查看,我们常见一个立方体,并为其每个面添加不同颜色的材质

const geometry = new THREE.BoxGeometry( 1, 1, 1 );

// 设置立方体的每个面为不同的颜色
const faceColors = [
    new THREE.Color(0x00ff00), // 前
    new THREE.Color(0x0000ff), // 后
    new THREE.Color(0xff0000), // 上
    new THREE.Color(0x00ffff), // 下
    new THREE.Color(0xffff00), // 左
    new THREE.Color(0xff00ff), // 右
];

// 创建材质数组
const materials = faceColors.map(color => new THREE.MeshBasicMaterial({ color: color }));
cube = new THREE.Mesh( geometry, materials );
scene.add( cube );

image.png

我们可以看到默认状态下,Y轴为绿色线条朝上,且我们看到的是红色面朝上,修改camera.up为(0,0,1),也就是蓝色线条朝上看看

camera.up.set(0,0,1)

image.png

可以看到此时蓝线朝上,相当于当前的Y轴被之前的Z轴替代了,反应在模型上就像是模型被翻转了一样。

管道漫游

「漫游管道」可以理解为「让相机像火车一样沿着3D管道内部移动」,创造出一种沉浸式的穿梭或飞行效果。

先看效果

53.gif

要实现管道漫游,首先要创建一条管道路径,使用THREE.CurveTHREE.CatmullRomCurve3生成3D曲线

const path = new THREE.CatmullRomCurve3([
    new THREE.Vector3(-5, 2, 9),
    new THREE.Vector3(-1, 4, 4),
    new THREE.Vector3(0, 0, 0),
    new THREE.Vector3(6, -6, 0),
    new THREE.Vector3(9, -4, 6),
    new THREE.Vector3(12, 3, 3),
    new THREE.Vector3(22, 3, 16),
    new THREE.Vector3(4, 3, 18),
    new THREE.Vector3(-5, 2, 12),
    new THREE.Vector3(-5, 2, 9),

]);

const geometry = new THREE.TubeGeometry(path, 125, 0.5, 30 ,true)
const texLoader = new THREE.TextureLoader(loadingManager)
const texture = texLoader.load('texture/disturb.jpg')

这里为了能看见该管道,这里进行了贴图,调整相机位置我们能看到如下管道

image.png

这里可以发现管道呈闭环状态,最简单的闭环就是环状,这样容易实现无限循环漫游效果, 调整相机位置

const pointsArr = path.getSpacedPoints(3000)
let i = 0;

camera.position.copy(pointsArr[i]);  // 管道中的第一个点坐标
camera.lookAt(pointsArr[i + 1]);   

image.png

通过不断地改变相机位置,实现漫游效果

if(i < pointsArr.length - 1) {
    camera.position.copy(pointsArr[i])
    camera.lookAt(pointsArr[i + 1])
    i += 1;
}else {
    i = 0;
}

主要应用场景

场景实现效果技术要点
地铁隧道模拟第一人称视角穿越隧道透视相机 + 直线路径
工业管道监控自动巡检管道内部正投影相机 + 固定高度
科幻游戏过场飞船在虫洞中穿梭曲线路径 + 动态材质

以上案例均可在案例中心查看体验

THREE 案例中心

image.png