内置几何体大全
本教程共 40 篇 · 第 11 篇 · 更新于 2026-08-14 · 约 9 分钟阅读
本节目标:把 three.js 内置的常用几何体全部过一遍,学会每种几何体的构造参数,能按需选型、调出想要的外观。
内置几何体从哪里来
three.js 核心包里内置了接近二十种几何体类。它们都继承自 BufferGeometry(第 10 章讲过),自带 position、normal、uv 等顶点数据,创建出来就能直接配合 Mesh 使用。不需要引任何扩展,import * as THREE from 'three' 之后随手可用。
Note旧教程里的
BoxBufferGeometry、SphereBufferGeometry这类名字在 r125 之后已经全部移除,现在统一叫BoxGeometry、SphereGeometry。看到旧代码直接去掉 Buffer 就行。
3D 几何体:常用六件套
BoxGeometry 长方体
new BoxGeometry(width, height, depth)。三个参数是长、宽、高,默认都是 1,彼此独立。不写参数得到的就是边长 1 的立方体。
const box = new THREE.BoxGeometry(2, 1, 0.5); // 长 2、高 1、深 0.5 的长方体
后面还有 widthSegments、heightSegments、depthSegments 三个分段参数,默认都是 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 是管的粗细,必须小于 radius。radialSegments 是管截面的分段数(默认 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 种几何体的构造参数汇总在一起,写代码时可以直接查:
| 几何体 | 构造参数(按顺序) | 常用调整 |
|---|---|---|
| BoxGeometry | width, height, depth | 长宽高各不同即长方体 |
| SphereGeometry | radius, widthSegments, heightSegments | 分段 32/16 起步 |
| CylinderGeometry | radiusTop, radiusBottom, height, radialSegments | 上下半径不同成圆台 |
| ConeGeometry | radius, height, radialSegments | 就是顶面半径为 0 的圆柱 |
| TorusGeometry | radius, tube, radialSegments, tubularSegments | tube 必须小于 radius |
| TorusKnotGeometry | radius, tube, tubularSegments, radialSegments, p, q | p、q 互质形状更经典 |
| CapsuleGeometry | radius, height, capSegments, radialSegments | height 只算中间圆柱 |
| PlaneGeometry | width, height | 默认平躺在 XZ 平面 |
| CircleGeometry | radius, segments | segments 设为 6 就是六边形 |
| RingGeometry | innerRadius, outerRadius | 内半径设为 0 就是实心圆 |
| Tetra/Octa/Dodeca/Icosa | radius, detail | detail 大于 0 会细分每个面 |
表格里只列了最常用的参数,每个几何体的完整参数在官方文档的对应页面都有。
分段数:所有几何体的通用开关
几乎所有内置几何体都有”分段数”参数,它决定表面由多少个三角形组成:
- 分段少:顶点少、渲染快,但形状棱角分明,是”低模”感;
- 分段多:表面平滑,但顶点成倍增加,占内存也占 GPU 时间;
- 静态展示,球和圆柱调到 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>
示例里有几个值得注意的点:
- 每个几何体只传了必要的参数,分段数取 32 或 16,兼顾平滑和性能;
- 多面体 Dodecahedron 默认是平滑着色,想看清切面,把材质改成
flatShading: true再看; - 全部使用
MeshStandardMaterial,所以场景里加了环境光和方向光,否则物体会是全黑的。
常见问题
- 物体棱角分明:多半是分段数太小。CylinderGeometry 的
radialSegments默认只有 8,SphereGeometry 默认 32,先检查分段数再怀疑别处。 - 想要半个圆环、半圆柱、半圆:把
thetaLength设为Math.PI即可。所有”绕圈生成”的几何体都支持这个参数。 - 一个几何体想用在多个 Mesh 上:直接复用同一个实例就行,多个 Mesh 可以共享一份顶点数据,省内存。需要各自独立变形时,才用
geometry.clone()。 - 模型”破面”或接缝:分段数不够时,球和圆环的两极、接缝处容易出现瑕疵,把分段数调高一般能解决。
小结
内置几何体是最快的”搭积木”工具。Box、Sphere、Cylinder、Cone、Torus、TorusKnot、Capsule 覆盖了大部分三维形状,四种多面体提供几何感造型,Plane、Circle、Ring 处理二维面。除了这些,还有 Lathe、Tube、Extrude、Shape 等靠路径和轮廓生成的进阶几何体,用到时再单独展开。
记不住参数没关系,记住三句话就够了:分段数管圆滑,theta 管切角,上下半径差管造型。