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回退,可以用CSS2DRendererCSS3DRenderer

小技巧: 记得在窗口大小变化时更新渲染器和相机:

window.addEventListener('resize', () => {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
});

不然画面会变形,嗯,我踩过这个坑。

1.5 本章小结

今天我们干了三件事:

  1. 搞清楚了Three.js和WebGL的关系——Three.js是WebGL的「翻译官」
  2. 搭建了第一个3D场景——场景、相机、渲染器,三件套齐活
  3. 让一个立方体旋转了起来——动画循环是3D交互的基础

下一章,我们会深入讲解几何体与材质,让你能创建出更丰富的3D物体。到时候,咱们的立方体就能穿上「衣服」、打上「灯光」了。

记住:3D网页开发,没那么玄乎。你只要把场景、相机、渲染器这三样东西玩明白,后面就是堆乐高。

公众号:蓝海资料掘金营,微信deep3321