首页 / Three.js 入门教程 / 内置几何体大全

Three.js 入门教程

内置几何体大全

本教程共 40 篇 · 第 11 篇 · 更新于 2026-08-14 · 约 9 分钟阅读

Three.js几何体BufferGeometry内置形状WebGL

本节目标:把 three.js 内置的常用几何体全部过一遍,学会每种几何体的构造参数,能按需选型、调出想要的外观。

内置几何体从哪里来

three.js 核心包里内置了接近二十种几何体类。它们都继承自 BufferGeometry(第 10 章讲过),自带 positionnormaluv 等顶点数据,创建出来就能直接配合 Mesh 使用。不需要引任何扩展,import * as THREE from 'three' 之后随手可用。

Note

旧教程里的 BoxBufferGeometrySphereBufferGeometry 这类名字在 r125 之后已经全部移除,现在统一叫 BoxGeometrySphereGeometry。看到旧代码直接去掉 Buffer 就行。

3D 几何体:常用六件套

BoxGeometry 长方体

new BoxGeometry(width, height, depth)。三个参数是长、宽、高,默认都是 1,彼此独立。不写参数得到的就是边长 1 的立方体。

const box = new THREE.BoxGeometry(2, 1, 0.5); // 长 2、高 1、深 0.5 的长方体

后面还有 widthSegmentsheightSegmentsdepthSegments 三个分段参数,默认都是 1,一般不用动。分段数只在需要变形或细分时才有意义。

SphereGeometry 球体

new SphereGeometry(radius, widthSegments, heightSegments)widthSegments 是水平分段数(绕赤道一圈),默认 32,最小 3;heightSegments 是垂直分段数(从南极到北极),默认 16,最小 2。分段越密球越圆,顶点也越多。

const sphere = new THREE.SphereGeometry(1, 32, 16);

后面还有四个可选参数:phiStart / phiLength 控制水平方向从哪个角度开始、扫过多少弧度;thetaStart / thetaLength 控制垂直方向。用它们可以切出半球、扇形球面:

const half = new THREE.SphereGeometry(1, 32, 16, 0, Math.PI * 2, 0, Math.PI / 2); // 上半球

CylinderGeometry 圆柱体

new CylinderGeometry(radiusTop, radiusBottom, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength)。前三个参数是顶面半径、底面半径和高度,默认都是 1。

const cylinder = new THREE.CylinderGeometry(0.6, 0.6, 1.2, 32);

radialSegments 是圆周分段数,默认 8,想让它圆润一般调到 32 以上。openEnded 设为 true 时上下盖打开,变成空心管。thetaStart / thetaLength 可以切出半圆柱之类的局部形状。

Tip

顶面半径和底面半径不一样,圆柱就变成圆台;把其中一个设为 0,就是圆锥。ConeGeometry 本质上就是底面半径固定、顶面半径为 0 的 CylinderGeometry。

ConeGeometry 圆锥体

new ConeGeometry(radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength)

const cone = new THREE.ConeGeometry(0.7, 1.2, 32); // 底面半径 0.7、高 1.2

参数含义和 CylinderGeometry 一一对应,只是上下两个半径合并成了单个 radius

TorusGeometry 圆环

new TorusGeometry(radius, tube, radialSegments, tubularSegments, arc)

const torus = new THREE.TorusGeometry(0.6, 0.25, 16, 48);

radius 是环的半径(环心到管心的距离),tube 是管的粗细,必须小于 radiusradialSegments 是管截面的分段数(默认 12),tubularSegments 是沿环一周的分段数(默认 48)。最后的 arc 是扫过的弧度,默认 2π 是整环,改成 π 就得到半个甜甜圈。

TorusKnotGeometry 环面纽结

new TorusKnotGeometry(radius, tube, tubularSegments, radialSegments, p, q)

const knot = new THREE.TorusKnotGeometry(0.55, 0.2, 64, 8, 2, 3);

环面纽结就是绕着自己转了几圈的”打结管子”。参数 p、q 是一对互质整数,决定绕法,默认 2 和 3 是最经典的形状。这个几何体的三角形很多,天生精细,适合当场景里的”主角”。

CapsuleGeometry 胶囊体

new CapsuleGeometry(radius, height, capSegments, radialSegments, heightSegments)

const capsule = new THREE.CapsuleGeometry(0.45, 0.8, 8, 16);

胶囊体是中间一段圆柱、两头各扣一个半球,height 只算中间圆柱那段的高度。它在 r142 之后加入核心包,做游戏角色、药丸、软糖都很常用。

多面体家族

四种正多面体写法完全一样:new 类名(radius, detail)detail 为 0 时是标准正多面体;大于 0 会把每个面继续细分,顶点变多,就不再是严格的正多面体了。

const tetra = new THREE.TetrahedronGeometry(0.8);   // 四面体:4 个三角面
const octa  = new THREE.OctahedronGeometry(0.8);    // 八面体:8 个三角面
const dode  = new THREE.DodecahedronGeometry(0.8);  // 十二面体:12 个五边形面
const icosa = new THREE.IcosahedronGeometry(0.8);   // 二十面体:20 个三角面

它们都继承自 PolyhedronGeometry。如果这些还不够用,PolyhedronGeometry(vertices, indices, radius, detail) 可以用顶点数组和索引数组搭任意多面体,不过顶点坐标要自己算,一般用不到。

搭配 flatShading: true(平面着色),多面体会呈现硬朗的切面质感,做低多边形风格很合适:

const material = new THREE.MeshStandardMaterial({
  color: 0x4488ff,
  flatShading: true,
});

2D 几何体

PlaneGeometry 平面

new PlaneGeometry(width, height, widthSegments, heightSegments)

const plane = new THREE.PlaneGeometry(2, 1);

一个矩形面,默认平躺在 XZ 平面上(法线朝 Y 轴正方向)。做地面、墙面、公告板都靠它。

Note

平面默认只有正面(FrontSide)可见,从背面看会”消失”,这是正常的。要两面都显示,把材质的 side 设为 THREE.DoubleSide,第 12 章会细讲。

CircleGeometry 圆形

new CircleGeometry(radius, segments, thetaStart, thetaLength)

const circle = new THREE.CircleGeometry(1, 32);

圆形由一圈三角形拼成,segments 默认 32,最小 3。把 segments 调小,圆会变成多边形——比如 6 就是六边形,这是个很实用的小技巧。thetaStart / thetaLength 可以切出扇形。

RingGeometry 圆环面

new RingGeometry(innerRadius, outerRadius, thetaSegments, phiSegments, thetaStart, thetaLength)

const ring = new THREE.RingGeometry(0.5, 1, 32); // 内半径 0.5、外半径 1

中间带洞的圆盘,innerRadius 是内半径、outerRadius 是外半径。做齿轮、垫圈、瞄准环之类的形状很顺手。

参数速查表

下面这张表把 11 种几何体的构造参数汇总在一起,写代码时可以直接查:

几何体构造参数(按顺序)常用调整
BoxGeometrywidth, height, depth长宽高各不同即长方体
SphereGeometryradius, widthSegments, heightSegments分段 32/16 起步
CylinderGeometryradiusTop, radiusBottom, height, radialSegments上下半径不同成圆台
ConeGeometryradius, height, radialSegments就是顶面半径为 0 的圆柱
TorusGeometryradius, tube, radialSegments, tubularSegmentstube 必须小于 radius
TorusKnotGeometryradius, tube, tubularSegments, radialSegments, p, qp、q 互质形状更经典
CapsuleGeometryradius, height, capSegments, radialSegmentsheight 只算中间圆柱
PlaneGeometrywidth, height默认平躺在 XZ 平面
CircleGeometryradius, segmentssegments 设为 6 就是六边形
RingGeometryinnerRadius, outerRadius内半径设为 0 就是实心圆
Tetra/Octa/Dodeca/Icosaradius, detaildetail 大于 0 会细分每个面

表格里只列了最常用的参数,每个几何体的完整参数在官方文档的对应页面都有。

分段数:所有几何体的通用开关

几乎所有内置几何体都有”分段数”参数,它决定表面由多少个三角形组成:

  1. 分段少:顶点少、渲染快,但形状棱角分明,是”低模”感;
  2. 分段多:表面平滑,但顶点成倍增加,占内存也占 GPU 时间;
  3. 静态展示,球和圆柱调到 32 就足够;跑在手机上可以降到 16 省性能。

实际使用中,先写默认参数看形状,觉得不够圆再往上加分段,比一上来就填 64、128 靠谱得多。

完整示例:几何体画廊

下面这个页面把 9 种几何体摆成三排,配上灯光和轨道控制器,保存成 HTML 直接运行:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8" />
  <title>内置几何体画廊</title>
  <style>
    html, body { margin: 0; height: 100%; }
  </style>
</head>
<body>
  <script type="importmap">
  {
    "imports": {
      "three": "https://cdn.jsdelivr.net/npm/three@0.185.0/build/three.module.js",
      "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.185.0/examples/jsm/"
    }
  }
  </script>

  <script type="module">
    import * as THREE from 'three';
    import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

    // 场景、相机、渲染器
    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(45, innerWidth / innerHeight, 0.1, 100);
    camera.position.set(6, 5, 10);
    const renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setSize(innerWidth, innerHeight);
    document.body.appendChild(renderer.domElement);

    // 灯光:MeshStandardMaterial 需要光
    scene.add(new THREE.AmbientLight(0xffffff, 3));
    const dirLight = new THREE.DirectionalLight(0xffffff, 3);
    dirLight.position.set(5, 10, 7);
    scene.add(dirLight);

    const controls = new OrbitControls(camera, renderer.domElement);

    // 几何体工厂:名字 -> 创建函数
    const makers = [
      ['Box', () => new THREE.BoxGeometry(1.2, 1.2, 1.2)],
      ['Sphere', () => new THREE.SphereGeometry(0.8, 32, 16)],
      ['Cylinder', () => new THREE.CylinderGeometry(0.6, 0.6, 1.2, 32)],
      ['Cone', () => new THREE.ConeGeometry(0.7, 1.2, 32)],
      ['Torus', () => new THREE.TorusGeometry(0.6, 0.25, 16, 48)],
      ['TorusKnot', () => new THREE.TorusKnotGeometry(0.55, 0.2, 64, 8, 2, 3)],
      ['Capsule', () => new THREE.CapsuleGeometry(0.45, 0.8, 8, 16)],
      ['Dodecahedron', () => new THREE.DodecahedronGeometry(0.75)],
      ['Plane', () => new THREE.PlaneGeometry(1.4, 1.4)],
    ];

    const meshes = [];
    makers.forEach(([name, make], i) => {
      const mesh = new THREE.Mesh(
        make(),
        new THREE.MeshStandardMaterial({
          color: new THREE.Color().setHSL(i / makers.length, 0.7, 0.5),
        })
      );
      mesh.position.x = (i % 3 - 1) * 2.2;   // 三列
      mesh.position.z = Math.floor(i / 3) * -2.2; // 三行
      scene.add(mesh);
      meshes.push(mesh);
    });

    function animate() {
      requestAnimationFrame(animate);
      meshes.forEach((mesh) => {
        mesh.rotation.x += 0.005;
        mesh.rotation.y += 0.01;
      });
      controls.update();
      renderer.render(scene, camera);
    }
    animate();

    // 窗口缩放自适应
    addEventListener('resize', () => {
      camera.aspect = innerWidth / innerHeight;
      camera.updateProjectionMatrix();
      renderer.setSize(innerWidth, innerHeight);
    });
  </script>
</body>
</html>

示例里有几个值得注意的点:

  1. 每个几何体只传了必要的参数,分段数取 32 或 16,兼顾平滑和性能;
  2. 多面体 Dodecahedron 默认是平滑着色,想看清切面,把材质改成 flatShading: true 再看;
  3. 全部使用 MeshStandardMaterial,所以场景里加了环境光和方向光,否则物体会是全黑的。

常见问题

  1. 物体棱角分明:多半是分段数太小。CylinderGeometry 的 radialSegments 默认只有 8,SphereGeometry 默认 32,先检查分段数再怀疑别处。
  2. 想要半个圆环、半圆柱、半圆:把 thetaLength 设为 Math.PI 即可。所有”绕圈生成”的几何体都支持这个参数。
  3. 一个几何体想用在多个 Mesh 上:直接复用同一个实例就行,多个 Mesh 可以共享一份顶点数据,省内存。需要各自独立变形时,才用 geometry.clone()
  4. 模型”破面”或接缝:分段数不够时,球和圆环的两极、接缝处容易出现瑕疵,把分段数调高一般能解决。

小结

内置几何体是最快的”搭积木”工具。Box、Sphere、Cylinder、Cone、Torus、TorusKnot、Capsule 覆盖了大部分三维形状,四种多面体提供几何感造型,Plane、Circle、Ring 处理二维面。除了这些,还有 Lathe、Tube、Extrude、Shape 等靠路径和轮廓生成的进阶几何体,用到时再单独展开。

记不住参数没关系,记住三句话就够了:分段数管圆滑,theta 管切角,上下半径差管造型。