1、Three.js入门:什么是Three.js、WebGL与Three.js的关系、Three.js能做什么、第一个3D场景(Hello Cube)

1.1 什么是Three.js?

Three.js,说白了就是一个让浏览器能跑3D的JavaScript库。

我刚开始接触前端3D时,第一反应是:这东西是不是很重?后来发现,它其实就是一个轻量级的封装层。你不需要懂图形学底层,也能在网页里搞出3D效果。

它的核心作用就三个:

  • 创建3D物体——比如立方体、球体、模型
  • 控制场景——灯光、相机、材质、动画
  • 渲染输出——把3D画面画到浏览器里

嗯,你可以把它理解成「3D世界的jQuery」。虽然这个比喻不太严谨,但意思到了。

1.2 WebGL与Three.js的关系

很多人搞不清WebGL和Three.js的区别。我简单说一下。

WebGL是浏览器底层的一个API,它直接跟GPU打交道。你用WebGL画一个三角形,大概要写几十行代码。画一个立方体?上百行。而且全是矩阵运算、着色器代码,看着就头疼。

Three.js是在WebGL之上封装的一层。它把那些复杂的底层操作藏起来了。你只需要写:

const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

三行代码,一个绿色立方体就出来了。

我在项目中遇到过不少新手,一上来就想直接学WebGL。我的建议是:先学Three.js,把3D思维建立起来。等你遇到性能瓶颈或者特殊需求时,再回头研究WebGL也不迟。

一句话总结:Three.js = WebGL的「傻瓜相机」模式。你按快门就行,对焦曝光的事交给它。

1.3 Three.js能做什么?

这个问题我经常被问到。其实Three.js能做的事,比你想象的多得多。

应用场景 具体例子 我见过的实际项目
产品展示 3D商品预览、汽车配置器 某家具品牌的在线展厅,用户能旋转沙发看细节
数据可视化 3D图表、城市热力图 智慧城市项目里,用3D柱状图展示人口密度
游戏 网页小游戏、互动体验 一个营销活动,用户控制3D角色收集金币
建筑可视化 室内漫游、BIM模型 地产公司的样板间VR预览
教育/医疗 分子结构、人体解剖 医学院的3D骨骼教学工具

你想想看,现在连电商详情页都开始用3D了。用户能拖拽旋转商品,比看图片直观多了。这个趋势只会越来越明显。

我的建议:别想着用Three.js做大型3A游戏,那是Unity和Unreal的事。Three.js的强项是轻量、快速、嵌入网页。做个小工具、展示页、互动体验,它比任何引擎都顺手。

1.4 第一个3D场景:Hello Cube

好了,理论说够了。咱们直接上手。

我习惯把Three.js的3D场景拆成四个要素:

  1. 场景(Scene)——放东西的容器
  2. 相机(Camera)——看东西的眼睛
  3. 渲染器(Renderer)——画东西的画笔
  4. 物体(Mesh)——被看的东西

缺一个都不行。就像拍电影,你得有舞台、摄像机、放映机、演员。

下面是最简版本的代码:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Hello Cube</title>
  <style>
    body { margin: 0; overflow: hidden; }
  </style>
</head>
<body>
  <script type="importmap">
  {
    "imports": {
      "three": "https://unpkg.com/three@0.160.0/build/three.module.js"
    }
  }
  </script>

  <script type="module">
    import * as THREE from 'three';

    // 1. 创建场景
    const scene = new THREE.Scene();

    // 2. 创建相机(透视相机)
    const camera = new THREE.PerspectiveCamera(
      75, // 视角角度
      window.innerWidth / window.innerHeight, // 宽高比
      0.1, // 近裁剪面
      1000 // 远裁剪面
    );
    camera.position.z = 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.MeshStandardMaterial({ color: 0x44aa88 });
    const cube = new THREE.Mesh(geometry, material);
    scene.add(cube);

    // 5. 加个灯光(不然立方体是黑的)
    const light = new THREE.DirectionalLight(0xffffff, 1);
    light.position.set(1, 1, 1);
    scene.add(light);

    // 6. 动画循环
    function animate() {
      requestAnimationFrame(animate);

      // 让立方体旋转
      cube.rotation.x += 0.01;
      cube.rotation.y += 0.01;

      renderer.render(scene, camera);
    }

    animate();
  </script>
</body>
</html>

注意:如果你直接双击HTML文件打开,可能会遇到跨域问题。建议用VS Code的Live Server插件,或者用npx serve启动一个本地服务器。

这段代码跑起来后,你会看到一个青绿色的立方体在旋转。嗯,这就是你的第一个3D场景。

我曾经在给团队做培训时,有人问:为什么立方体是黑的?因为没加灯光。Three.js的默认材质需要光照才能显示颜色。如果你用MeshBasicMaterial,就不需要灯光了,但看起来没有立体感。

小技巧:调试时可以把camera.position.z改大改小,看看立方体怎么变化。数值越小,立方体看起来越大。这就是透视相机的效果。

1.5 代码拆解:每一行都在干什么

我习惯把代码拆成小块来理解。咱们过一遍关键部分:

  • importmap:这是ES Module的加载方式。告诉浏览器从哪里下载Three.js库。版本号0.160.0是我常用的稳定版。
  • Scene:一个空容器。所有物体、灯光、辅助线都放进去。
  • PerspectiveCamera:透视相机,模拟人眼效果。近大远小。四个参数分别是:视角、宽高比、近裁面、远裁面。
  • WebGLRenderer:渲染器。它把3D场景画到<canvas>上。setSize设置画布尺寸。
  • BoxGeometry:几何体。1x1x1的立方体。你可以改成2, 1, 1试试,会变成扁长方体。
  • MeshStandardMaterial:标准材质。能响应光照,看起来更真实。
  • Mesh:网格。几何体+材质=一个可以渲染的物体。
  • DirectionalLight:方向光。模拟太阳光,从某个方向照射。
  • requestAnimationFrame:浏览器自带的动画循环。每秒60帧,比setInterval更省资源。

你想想看,这十几行代码背后,WebGL要处理多少东西?顶点着色器、片元着色器、缓冲区、矩阵变换……Three.js全帮你搞定了。

1.6 避坑指南

我刚开始用Three.js时踩过不少坑。分享几个最常见的:

  • 场景是黑的——检查有没有加灯光。或者材质是不是用了MeshBasicMaterial
  • 物体不显示——检查相机位置。如果相机在物体内部,或者距离太远,就看不到。
  • 页面空白——检查渲染器有没有添加到DOM。很多人忘了document.body.appendChild(renderer.domElement)
  • 动画不流畅——别用setInterval做动画循环。用requestAnimationFrame

我曾经有一次调试了半小时,发现是camera.position.z设成了负数。相机在物体后面,当然看不到。嗯,这种低级错误谁都犯过。

1.7 下一步做什么?

跑通Hello Cube之后,我建议你做三件事:

  1. 改颜色——把0x44aa88换成你喜欢的颜色
  2. 改形状——把BoxGeometry换成SphereGeometryCylinderGeometry
  3. 加多个物体——创建第二个立方体,放在不同位置

别怕改坏。Three.js的容错性很好,改错了最多页面空白,刷新一下就好。

下一章我们会深入场景、相机、渲染器这三个核心概念。你会发现,搞懂了它们,Three.js就入门了一半。


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