1、3D网页基础:Three.js简介、WebGL与Three.js的关系、搭建第一个3D场景
各位同学,欢迎来到《3D网页音视频同步交互课程》的第一章。
说实话,每次带新人入门3D网页开发,我都要先问一个问题:你为什么要学Three.js? 很多人回答「因为酷」。嗯,没错,确实酷。但更实际的原因是——浏览器原生3D能力,已经被WebGL彻底激活了。而我们今天的主角Three.js,就是站在WebGL肩膀上,让3D开发变得「像写普通网页一样简单」的那个工具。
1.1 什么是Three.js?
Three.js是一个基于JavaScript的3D引擎库。它封装了底层图形API,让你不用跟那些晦涩的着色器代码死磕。
我个人的理解是:Three.js就是3D世界的jQuery。你想想看,jQuery把DOM操作简化了,Three.js则把3D场景的搭建简化了。你只需要关心「场景里有什么」「相机怎么看」「物体怎么动」,剩下的矩阵运算、渲染管线、缓冲区管理……嗯,Three.js帮你扛了。
核心定位: Three.js = WebGL的「高级封装」 + 3D场景的「声明式API」
我在2016年第一次接触Three.js时,被它的设计惊艳到了。你只需要几行代码,就能在浏览器里看到一个旋转的立方体。这种「即时反馈」带来的成就感,是很多后端技术给不了的。
1.2 WebGL与Three.js的关系
很多新手会混淆这两个概念。我简单解释一下:
- WebGL:浏览器底层的图形API,直接跟GPU打交道。它很强大,但也很「原始」。你要自己管理顶点缓冲、编写着色器、处理矩阵变换……说白了,就像用汇编语言写网页。
- Three.js:基于WebGL的上层封装。它把那些重复性的工作抽象成「场景」「相机」「网格」「材质」这些直观的概念。
举个例子你就明白了:
| 任务 | 用WebGL | 用Three.js |
|---|---|---|
| 创建一个立方体 | 写几百行着色器+顶点数据 | new THREE.BoxGeometry() |
| 添加光照 | 自己实现光照算法 | new THREE.DirectionalLight() |
| 让物体旋转 | 手动更新矩阵 | cube.rotation.y += 0.01 |
看到区别了吧?Three.js不是替代WebGL,而是让你用更少的代码,做更多的事。
我的建议: 如果你刚开始学3D网页开发,直接上手Three.js。等遇到性能瓶颈或需要定制渲染效果时,再回头研究WebGL底层。别一开始就钻着色器,容易劝退。
1.3 搭建第一个3D场景
好了,理论说完了,咱们直接动手。一个最简单的3D场景,需要三样东西:场景(Scene)、相机(Camera)、渲染器(Renderer)。缺一不可。
我习惯把这三者比作「拍电影」:
- 场景 = 摄影棚,所有物体、灯光、特效都在里面
- 相机 = 摄像机,决定了你从哪个角度看到场景
- 渲染器 = 放映机,把3D画面「拍」到屏幕上
来,看代码:
// 1. 创建场景
const scene = new THREE.Scene();
// 2. 创建透视相机(视角75°,宽高比自动,近裁面0.1,远裁面1000)
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5; // 把相机往后拉5个单位
// 3. 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 4. 添加一个立方体
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
// 5. 动画循环
function animate() {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();
这段代码跑起来,你就能看到一个绿色的立方体在屏幕中央旋转。是不是很简单?
注意: 我曾经遇到过新手把相机放在原点(0,0,0),结果立方体也放在原点,然后发现「怎么什么都看不到?」——因为相机和物体重叠了。记得把相机往后挪一挪,比如 camera.position.z = 5。
1.4 场景三要素详解
咱们再深入一点,看看这三个核心对象到底在干什么。
场景(Scene)
场景就是一个容器。你往里面放什么,渲染时就显示什么。可以放网格、灯光、粒子、辅助线……甚至其他场景(通过组Group实现)。
我个人习惯在场景里加一个AxesHelper,方便观察坐标轴方向:
const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper);
相机(Camera)
Three.js提供了两种常用相机:
- 透视相机(PerspectiveCamera):模拟人眼,近大远小,适合大多数3D场景
- 正交相机(OrthographicCamera):没有透视效果,适合2D游戏或UI界面
你想想看,如果做3D产品展示,肯定用透视相机;如果做地图编辑器,正交相机更合适。
渲染器(Renderer)
渲染器负责把场景和相机「拍」成一张图片,然后显示在canvas上。默认是WebGLRenderer,如果你需要2D回退,可以用CSS2DRenderer或CSS3DRenderer。
小技巧: 记得在窗口大小变化时更新渲染器和相机:
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
不然画面会变形,嗯,我踩过这个坑。
1.5 本章小结
今天我们干了三件事:
- 搞清楚了Three.js和WebGL的关系——Three.js是WebGL的「翻译官」
- 搭建了第一个3D场景——场景、相机、渲染器,三件套齐活
- 让一个立方体旋转了起来——动画循环是3D交互的基础
下一章,我们会深入讲解几何体与材质,让你能创建出更丰富的3D物体。到时候,咱们的立方体就能穿上「衣服」、打上「灯光」了。
记住:3D网页开发,没那么玄乎。你只要把场景、相机、渲染器这三样东西玩明白,后面就是堆乐高。
公众号:蓝海资料掘金营,微信deep3321