文章目录
-
- 前言
- [一、前置准备:Three.js 环境搭建](#一、前置准备:Three.js 环境搭建)
- [二、初始化 Three.js 核心三要素:场景、相机、渲染器](#二、初始化 Three.js 核心三要素:场景、相机、渲染器)
- 三、创建物体:几何体与材质
- [四、 响应式窗口适配](#四、 响应式窗口适配)
- [五、集成 dat.GUI 实现可视化调试](#五、集成 dat.GUI 实现可视化调试)
- 六、轨道控制器 (OrbitControls)
- 七、模板与样式
- 总结
本文为Three.js系列文章,专注前端 3D 可视化领域,从基础原理到实战落地,带你从零掌握 Three.js,适配 Web 端 VR、数字孪生、3D 展厅、数据可视化等主流业务场景。
【前端进阶之旅】3D 引擎的基本理解 ------ 基于 Three.js,吃透 3D 场景六大核心要素
项目完整代码请看这里
前言
Three.js,作为目前业界最主流、生态最完善的 WebGL 开源框架,它封装了复杂的底层 WebGL API,让前端开发者无需深入学习图形学知识,就能快速在网页中构建出高性能、沉浸式的 3D 场景,是前端踏入 3D 世界的最佳入门选择。
一、前置准备:Three.js 环境搭建
npm + Vite 工程化引入(实际项目首选)
bash
# 安装Three.js核心库
npm install three
# 安装可视化调试工具
pnpm add dat.gui
pnpm add @types/dat.gui -D
在项目中引入使用:
bash
<script setup lang="ts">
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/Addons.js";
import { onMounted, ref } from "vue";
import gsap from "gsap";
import * as dat from "dat.gui";
// ...
</script>
二、初始化 Three.js 核心三要素:场景、相机、渲染器
上一篇文章我们详细讲解了三大核心要素 ------ 场景 (Scene)、相机 (Camera)、渲染器 (Renderer),只有三者配合,才能完成一次完整的 3D 画面渲染,这也是所有 Three.js 项目的基础骨架。
核心 API 与基础用法:
javascript
// 创建场景
const scene = new THREE.Scene();
// 创建相机
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000,
);
// fov: 视野角度, aspect: 长宽比, near: 近端, far: 远端
// 设置相机位置
camera.position.z = 30;
// 创建渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染器大小
renderer.setSize(window.innerWidth, window.innerHeight);
const container = ref<HTMLDivElement | null>(null);
onMounted(() => {
if (container.value) {
container.value.appendChild(renderer.domElement);
render();
}
});
<template>
<div ref="container" class="container" />
</template>
<style lang="scss" scoped>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
width: 100vw;
height: 100vh;
}
</style>
到这里,我们已经完成了 Three.js 最基础的骨架搭建,接下来我们只需要往场景中添加物体、光源、交互逻辑,就能让这个 3D 世界丰富起来。
三、创建物体:几何体与材质
在 Three.js 中,我们想要创建一个可见的 3D 物体,必须由两部分组成:几何体 (Geometry) 和 材质 (Material),再通过网格 (Mesh) 将两者结合,最终添加到场景中。
javascript
// 创建几何体
const geometry = new THREE.BoxGeometry(10, 10, 10); // 宽, 高, 深度(Z轴)
// 创建材质
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
// 创建网格
const box = new THREE.Mesh(geometry, materials);
// 设置摄像机位置,-1表示摄像机在物体内部
box.geometry.scale(1, 1, -1);
// 将网格添加到场景中
scene.add(box);
代码中的彩蛋:你可能注意到了代码中有两段被注释掉的函数 useBox 和 useSphere。这是实现360 度全景图的两种常用方法(立方体全景和球体全景)。如果你有六张全景图或一张全景图,取消注释并加载正确的图片路径即可体验 VR 效果。

四、 响应式窗口适配
为了让 3D 场景在浏览器窗口大小改变时也能正常显示,我们需要监听 resize 事件。
javascript
window.addEventListener("resize", () => {
// 更新相机的宽高比
camera.aspect = window.innerWidth / window.innerHeight;
// 更新相机的投影矩阵
camera.updateProjectionMatrix();
// 更新渲染器的尺寸
renderer.setSize(window.innerWidth, window.innerHeight);
});
五、集成 dat.GUI 实现可视化调试
dat.GUI 是一个非常棒的工具,它能让我们快速生成一个控制面板,实时修改参数而不用改代码。
typescript
// 初始化 GUI
const gui = new dat.GUI();
// 创建一个文件夹来管理立方体相关属性
const boxFolder = gui.addFolder("立方体属性");
// 添加位置控制滑块
boxFolder.add(box.position, "x").name("移动X轴").min(-10).max(10).step(0.01);
boxFolder.add(box.position, "y").name("移动Y轴").min(-10).max(10).step(0.01);
boxFolder.add(box.position, "z").name("移动Z轴").min(-10).max(10).step(0.01);
// 添加颜色选择器
boxFolder
.addColor({ color: 0x00ff00 }, "color")
.name("修改颜色")
.onChange((value) => {
box.material.color = new THREE.Color(value);
});
// 定义参数对象,用于控制显示隐藏和触发动画
const params = {
visible: true,
moveAnimation: () => {
gsap.to(box.position, { x: 10, duration: 2, yoyo: true });
}
}
// 添加复选框和按钮
boxFolder.add(params, "visible").name("显示/隐藏").onChange((value) => {
box.visible = value;
})
boxFolder.add(params, "moveAnimation").name("移动动画");
boxFolder.open(); // 默认展开该文件夹
// 同理,添加相机属性控制文件夹
const cameraFolder = gui.addFolder("相机属性");
// ... (代码省略,与立方体类似)
cameraFolder.open();
六、轨道控制器 (OrbitControls)
这是让场景 "动" 起来的关键。它允许我们通过鼠标拖拽旋转视角、滚轮缩放。
typescript
// 声明控制器变量
let controls: OrbitControls;
// 用于绑定DOM的 ref
const container = ref<HTMLDivElement | null>(null);
// 渲染循环函数
const render = () => {
// 如果有控制器,需要在每一帧更新(特别是开启阻尼效果时)
controls && controls.update();
// 执行渲染
renderer.render(scene, camera);
// 请求下一帧,形成循环
requestAnimationFrame(render);
};
onMounted(() => {
if (container.value) {
// 实例化控制器:需要相机和渲染器的DOM元素作为参数
controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true; // 开启阻尼(惯性)效果,让交互更丝滑
controls.update();
// 将渲染器生成的 canvas 挂载到 Vue 模板中
container.value.appendChild(renderer.domElement);
// 开始渲染循环
render();
}
});
七、模板与样式
最后,我们需要一个容器来放置 Three.js 的画布。
html
<template>
<div ref="container" class="container" />
</template>
<style lang="scss" scoped>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.container {
width: 100vw;
height: 100vh;
}
</style>
总结
通过这段代码,我们已经掌握了在 Vue3 中使用 Three.js 的基本流程:
搭建基础: 引入库,创建 Scene、Camera、Renderer。添加内容: 创建 Geometry 和 Material,合成 Mesh 并加入场景。交互控制: 使用 OrbitControls 进行视角控制。调试优化: 使用 dat.GUI 快速调参。持续渲染: 使用 requestAnimationFrame 建立动画循环。