Three.js 文档:https://threejs.org/
哔哩哔哩配套视频学习教程地址:https://www.bilibili.com/video/BV1HPYQz7Ed2?spm_id_from=333.788.videopod.episodes&vd_source=628c735d0423e2bd1153ac15c47d3d87
市场需求
就业机会、薪资更具有优势。
前端发展趋势
用户交互由 2D 发展为 3D,体验更好。
常见应用场景如:全景展览,在线选车,智慧城市等。
Three.js 可以在浏览器上渲染 3D场景。
需要储备什么知识,才能学习这套课程呢?
第一阶段:学习 three.js 的核心知识
学习内容包括:场景、摄像机、渲染器、几何图形、材质、网格、GUI、全景图、光线投射、性能。
第二阶段:学习 three.js 的进阶知识
学习内容包括:贴图、粗糙度、金属度、物理材质、模型、坐标、光源、阴影、gsap、精灵物体。
第三阶段:学习着色器原理
three.js 是一个基于 JavaScript 的 WebGL 引擎,可直接运行 GPU 驱动游戏与图形驱动应用于浏览器。其提供大量特性与 API 以绘制 3D 场景于浏览器。
拓展知识:
- WebGL:Web 图形库,一组浏览器的 API,可以无需其他插件,可独立渲染 3D 场景。
- GPU:是计算机的图形处理单元部件,负责在显示器上绘制显示图形。
一句话总结 Three.js、WebGL、GPU 三者的关系就是:Three.js 对 WebGL 代码进行封装,底层依赖 GPU 进行图形绘制。
基于 vite 前端构建工具和 JavaScript 语法。
在命令行工具中定位到要搭建项目的路径,然后执行下面的命令:
pnpm create vite
执行命令后,根据提示设置项目名称【Project name】,并选择框架模版【vanilla】,开发语言类型选择【JavaScript】,最终会生成一个名称为项目名称的目录,进入该目录,然后执行 pnpm install 安装依赖,再执行 pnpm dev 运行项目,在浏览器通过 http://localhost:5173/ 访问项目。
如果上面搭建项目成功,可以删除掉构搭建项目中默认生成的代码和文件,以一个轻量且干净的最小框架开始后面的 three.js 学习之旅。
建议:
删除 src 目录下的除了 main.js 和 style.css 以外文件,然后删除 main.js 文件内容只保留导入 style.css 即可。
当然你可以根据自己的需求进行处理。
接下来我们就开始进入 three.js 实战学习阶段了。
简单了解基础三要素,方便我们后续的代码实践:
pnpm add three
// file: src/main.js
// 引入 three.js
import * as THREE from 'three';
// 场景,摄像机,渲染器
let scene, camera, renderer;
// 初始化三要素
function init() {
// 1. 创建场景对象
scene = new THREE.Scene();
// 2. 创建摄像机对象
// 参数1:垂直角度(建议75),视野范围
// 参数2:宽高比(建议与画布相同宽高),物体绘制比例
// 参数3:近截面距离摄像机距离
// 参数4:远截面距离摄像机距离
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
// 移动摄像机 z 轴 5 个单位(默认摄像机和物体的坐标轴的都在原点)
camera.position.z = 5;
// 3. 创建渲染器
renderer = new THREE.WebGLRenderer({
antialias: true, // 开启抗锯齿 - 优化
});
renderer.setSize(window.innerWidth, window.innerHeight); // 设置画布大小
document.body.append(renderer.domElement); // 添加到DOM显示
renderer.render(scene, camera); // 传入场景和摄像机,渲染画面
}
// 初始化元素
init();
此时浏览器看到是黑屏效果,可以通过控制台查看 DOM 结构。
绘制立方体步骤:
注意:
- 默认物体中心与坐标轴中心点重合,所以摄像机需要位移才能看到物体,也就是摄像机需要拉远一些才能看到物体。
- 渲染器需要调用 render 才能渲染画面(等待物体添加到场景后,再调用)
继续完善上面的代码绘制立方体:
// file: src/main.js
// 引入 three.js
import * as THREE from 'three';
// 场景,摄像机,渲染器
let scene, camera, renderer;
// 立方体
let cube;
// 初始化三要素
function init() {
// 1. 创建场景对象
scene = new THREE.Scene();
// 2. 创建摄像机对象
// 参数1:垂直角度(建议75),视野范围
// 参数2:宽高比(建议与画布相同宽高),物体绘制比例
// 参数3:近截面距离摄像机距离
// 参数4:远截面距离摄像机距离
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
// 移动摄像机 z 轴 5 个单位(默认摄像机和物体的坐标轴的都在原点)
camera.position.z = 5;
// 3. 创建渲染器
renderer = new THREE.WebGLRenderer({
antialias: true, // 开启抗锯齿 - 优化
});
renderer.setSize(window.innerWidth, window.innerHeight); // 设置画布大小
document.body.append(renderer.domElement); // 添加到DOM显示
}
// 创建立方体
function createCube() {
// 1. 创建图形,宽深高为 1 单位(立体缓冲几何体)
const geometry = new THREE.BoxGeometry(1, 1, 1);
// 2. 创建材质,颜色为绿色 0x00ff00 (网格基础材质 - 线面纯颜色描绘表面)
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
// 3. 创建网格物体对象,传入图形和材质(网格物体对象)
cube = new THREE.Mesh(geometry, material);
// 4. 把物体加入到场景中
scene.add(cube);
}
// 初始化元素
init();
// 创建立方体
createCube();
renderer.render(scene, camera); // 传入场景和摄像机,渲染画面
此时浏览器效果如下:
由于我们目前看到的只是正方体的一个面,也就是正视图,所以看起来像是平面效果。如果看到其他面,请继续学习下一章节《轨道控制器》。
轨道控制器:可以使摄像机围绕目标进行轨道运动。
作用:右键拖动,左键旋转,滚轮拉近,拉远摄像机。
使用:
继续基于上面的代码使用轨道控制器:
// file: src/main.js
// 引入 three.js
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
// 场景,摄像机,渲染器
let scene, camera, renderer;
// 轨道控制器
let controls;
// 立方体
let cube;
// 初始化三要素
function init() {
// 1. 创建场景对象
scene = new THREE.Scene();
// 2. 创建摄像机对象
// 参数1:垂直角度(建议75),视野范围
// 参数2:宽高比(建议与画布相同宽高),物体绘制比例
// 参数3:近截面距离摄像机距离
// 参数4:远截面距离摄像机距离
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
// 移动摄像机 z 轴 5 个单位(默认摄像机和物体的坐标轴的都在原点)
camera.position.z = 5;
// 3. 创建渲染器
renderer = new THREE.WebGLRenderer({
antialias: true, // 开启抗锯齿 - 优化
});
renderer.setSize(window.innerWidth, window.innerHeight); // 设置画布大小
document.body.append(renderer.domElement); // 添加到DOM显示
}
// 创建立方体
function createCube() {
// 1. 创建图形,宽深高为 1 单位(立体缓冲几何体)
const geometry = new THREE.BoxGeometry(1, 1, 1);
// 2. 创建材质,颜色为绿色 0x00ff00 (网格基础材质 - 线面纯颜色描绘表面)
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
// 3. 创建网格物体对象,传入图形和材质(网格物体对象)
cube = new THREE.Mesh(geometry, material);
// 4. 把物体加入到场景中
scene.add(cube);
}
// 创建轨道控制器
function createControls() {
controls = new OrbitControls(camera, renderer.domElement);
}
/**
* 渲染循环
*/
function renderLoop() {
renderer.render(scene, camera);
// 手动 JS 代码更新过摄像机信息,必须调用轨道控制器 update 方法
controls.update();
// 根据当前计算机浏览器刷新帧率(默认 60 次/秒),不断递归调用此函数渲染最新的画面状态
// 好处:当前页面切换到后台,暂停递归
requestAnimationFrame(renderLoop);
}
// 初始化元素
init();
// 创建轨道控制器
createControls();
// 创建立方体
createCube();
// 渲染循环
renderLoop();
此时在浏览器中,就可以右键拖动立方体,左键旋转立方体看不同的面,滚轮拉进,拉远摄像机。
给画布添加坐标轴辅助对象,就是在画布中模拟 3 个坐标轴(x,y,z),随时显示和调整,辅助我们开发和调试。
注意:因为浏览器兼容性,线段最大最小宽度只能为1。
加入坐标轴辅助对象后完整的 main.js 的代码如下:
// file: src/main.js
// 引入 three.js
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
// 场景,摄像机,渲染器
let scene, camera, renderer;
// 轨道控制器
let controls;
// 立方体
let cube;
// 初始化三要素
function init() {
// 1. 创建场景对象
scene = new THREE.Scene();
// 2. 创建摄像机对象
// 参数1:垂直角度(建议75),视野范围
// 参数2:宽高比(建议与画布相同宽高),物体绘制比例
// 参数3:近截面距离摄像机距离
// 参数4:远截面距离摄像机距离
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
// 移动摄像机 z 轴 5 个单位(默认摄像机和物体的坐标轴的都在原点)
camera.position.z = 5;
// 3. 创建渲染器
renderer = new THREE.WebGLRenderer({
antialias: true, // 开启抗锯齿 - 优化
});
renderer.setSize(window.innerWidth, window.innerHeight); // 设置画布大小
document.body.append(renderer.domElement); // 添加到DOM显示
}
// 创建立方体
function createCube() {
// 1. 创建图形,宽深高为 1 单位(立体缓冲几何体)
const geometry = new THREE.BoxGeometry(1, 1, 1);
// 2. 创建材质,颜色为绿色 0x00ff00 (网格基础材质 - 线面纯颜色描绘表面)
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
// 3. 创建网格物体对象,传入图形和材质(网格物体对象)
cube = new THREE.Mesh(geometry, material);
// 4. 把物体加入到场景中
scene.add(cube);
}
// 创建轨道控制器
function createControls() {
controls = new OrbitControls(camera, renderer.domElement);
}
/**
* 渲染循环
*/
function renderLoop() {
renderer.render(scene, camera);
// 手动 JS 代码更新过摄像机信息,必须调用轨道控制器 update 方法
controls.update();
// 根据当前计算机浏览器刷新帧率(默认 60 次/秒),不断递归调用此函数渲染最新的画面状态
// 好处:当前页面切换到后台,暂停递归
requestAnimationFrame(renderLoop);
}
// 添加坐标轴辅助对象
function createHelper() {
/**
* 用于简单模拟3个坐标轴的对象.
* 红色代表 X 轴. 绿色代表 Y 轴. 蓝色代表 Z 轴.
*/
const axesHelper = new THREE.AxesHelper(5)
scene.add(axesHelper)
}
// 初始化元素
init();
// 创建轨道控制器
createControls();
// 添加坐标轴
createHelper()
// 创建立方体
createCube();
// 渲染循环
renderLoop();
效果如下:
至此,我们完成一个简单 three.js 应用,是不是没有想象中那么难,而且平时做多了平面效果,3D 效果还是挺有趣的!
🔥BuildAdmin是一个永久免费开源,无需授权即可商业使用,且使用了流行技术栈快速创建商业级后台管理系统。