02 几何体与材质
了解 Three.js 中的各种 3D 形状和材质
几何体分类
Three.js 提供了丰富的内置几何体,大致分为三类:
| 类型 | 说明 | 示例 |
|---|---|---|
| 2D 几何体 | 在一个平面上 | PlaneGeometry, CircleGeometry |
| 3D 几何体 | 立体形状 | BoxGeometry, SphereGeometry |
| 路径几何体 | 用路径绘制 | TorusGeometry, ExtrudeGeometry |
常用 2D 几何体
平面(Plane)
无限薄的平面,常用于地面、墙面。
js
// 平面
const plane = new THREE.PlaneGeometry(10, 10)
// 参数:宽度,高度
// 圆面
const circle = new THREE.CircleGeometry(5, 64)
// 参数:半径,段数(越高越圆)
// 环形
const ring = new THREE.RingGeometry(3, 5, 32)
// 参数:内半径,外半径,段数
// 扇形
const sector = new THREE.SectorGeometry(5, 10, Math.PI / 2, Math.PI / 4)1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
常用 3D 几何体
立方体(Box)
js
// 立方体(宽, 高, 深)
const box = new THREE.BoxGeometry(2, 2, 2)
// 带圆角的立方体(Three.js r158+)
const roundBox = new THREE.BoxGeometry(2, 2, 2, 4, 4, 4) // 后6个参数控制分段数1
2
3
4
5
2
3
4
5
球体(Sphere)
js
// 球体
const sphere = new THREE.SphereGeometry(1, 32, 32)
// 参数:半径,水平段数,垂直段数
// 球体分段越多越圆,但性能开销也越大
const lowPoly = new THREE.SphereGeometry(1, 8, 6) // 低多边形风格
const highPoly = new THREE.SphereGeometry(1, 64, 64) // 高精度1
2
3
4
5
6
7
2
3
4
5
6
7
圆柱体(Cylinder)
js
// 圆柱体
const cylinder = new THREE.CylinderGeometry(1, 1, 4, 32)
// 参数:顶部半径,底部半径,高度,段数
// 圆台(截头圆锥)
const truncatedCone = new THREE.CylinderGeometry(0.5, 2, 4, 32)
// 无顶底面的圆柱(管道)
const tube = new THREE.CylinderGeometry(1, 1, 4, 32, 1, true)
// 最后一个 true 表示 openEnded(两端开口)1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
圆环(Torus)
js
// 圆环(甜甜圈形状)
const torus = new THREE.TorusGeometry(3, 1, 16, 100)
// 参数:半径,管子半径,管子分段数,圆环分段数
// 圆环打结(复杂的环形)
const torusKnot = new THREE.TorusKnotGeometry(2, 0.5, 64, 8)1
2
3
4
5
6
2
3
4
5
6
圆锥(Cone)
js
// 圆锥
const cone = new THREE.ConeGeometry(2, 4, 32)
// 参数:半径,高度,段数
// 多边形棱锥
const pyramid = new THREE.ConeGeometry(2, 4, 6) // 六边形底面1
2
3
4
5
6
2
3
4
5
6
其他几何体
js
// 正十二面体(足球形状)
const dodecahedron = new THREE.DodecahedronGeometry(1)
// 正二十面体
const icosahedron = new THREE.IcosahedronGeometry(1)
// 正八面体
const octahedron = new THREE.OctahedronGeometry(1)
// 正四面体
const tetrahedron = new THREE.TetrahedronGeometry(1)
// 蛋形
const egg = new THREE.EggGeometry(1, 32)1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
材质(Material)
材质决定了物体的表面外观(颜色、光泽、纹理等)。
MeshBasicMaterial(基础材质)
不受光照影响,物体看起来是平的。
js
const basicMaterial = new THREE.MeshBasicMaterial({
color: 0xff6b6b,
transparent: true, // 开启透明
opacity: 0.8, // 透明度 0-1
side: THREE.DoubleSide // 双面可见
})1
2
3
4
5
6
2
3
4
5
6
MeshStandardMaterial(标准材质)
PBR(基于物理的渲染),需要光照才能显示。
js
const standardMaterial = new THREE.MeshStandardMaterial({
color: 0x4ecdc4,
roughness: 0.5, // 粗糙度(0=镜子,1=完全粗糙)
metalness: 0.5, // 金属度(0=非金属,1=纯金属)
wireframe: false, // 线框模式
flatShading: false, // 平面着色(低多边形风格)
})1
2
3
4
5
6
7
2
3
4
5
6
7
MeshPhongMaterial(高光材质)
有镜面高光,适合表现光滑表面。
js
const phongMaterial = new THREE.MeshPhongMaterial({
color: 0xffffff,
specular: 0x444444, // 高光颜色
shininess: 30, // 光泽度(高光强度)
})1
2
3
4
5
2
3
4
5
MeshLambertMaterial(兰伯特材质)
漫反射,计算成本低。
js
const lambertMaterial = new THREE.MeshLambertMaterial({
color: 0xffffff,
emissive: 0x111111 // 自发光颜色
})1
2
3
4
2
3
4
MeshNormalMaterial(法线材质)
用颜色显示面的法线方向(调试用)。
js
const normalMaterial = new THREE.MeshNormalMaterial({
flatShading: true // 平面着色,更明显
})1
2
3
2
3
MeshDepthMaterial(深度材质)
根据深度显示灰度。
js
const depthMaterial = new THREE.MeshDepthMaterial()1
常用材质参数一览
js
const material = new THREE.MeshStandardMaterial({
// 基础
color: 0xffffff, // 基础颜色
map: texture, // 颜色贴图(纹理)
// 粗糙度与金属度
roughness: 0.5, // 0-1,值越小越光滑
metalness: 0.5, // 0-1,值越大越像金属
// 透明度
transparent: true,
opacity: 0.8,
alphaTest: 0.5, // 透明测试阈值
// 法线贴图(增加表面细节凹凸感)
normalMap: normalTexture,
normalScale: new THREE.Vector2(1, 1),
// 置换贴图(真正改变几何体形状)
displacementMap: dispTexture,
displacementScale: 0.1,
// 环境光遮蔽
aoMap: aoTexture,
aoMapIntensity: 1,
// 自发光
emissive: 0xff0000,
emissiveIntensity: 0.5,
// 纹理偏移与重复
normalMap.offset = new THREE.Vector2(0, 0)
normalMap.repeat = new THREE.Vector2(2, 2)
normalMap.wrapS = THREE.RepeatWrapping
normalMap.wrapT = THREE.RepeatWrapping
})1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
几何体分组
组合体(Group)
把多个物体放在一起,方便统一操作。
js
const group = new THREE.Group()
const box = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
new THREE.MeshStandardMaterial({ color: 0xff6b6b })
)
group.add(box)
const sphere = new THREE.Mesh(
new THREE.SphereGeometry(0.5, 32, 32),
new THREE.MeshStandardMaterial({ color: 0x4ecdc4 })
)
sphere.position.x = 2
group.add(sphere)
// 整个组旋转
scene.add(group)
group.rotation.y = Math.PI / 41
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
平移、旋转、缩放
js
const mesh = new THREE.Mesh(geometry, material)
// 平移
mesh.translateX(2) // 沿X轴平移
mesh.translateY(1) // 沿Y轴平移
mesh.translateZ(-3) // 沿Z轴平移
mesh.translateOnAxis(axis, distance) // 沿任意轴平移
// 旋转
mesh.rotateX(Math.PI / 2) // 绕X轴旋转 90°
mesh.rotateY(Math.PI / 2) // 绕Y轴旋转 90°
mesh.rotateZ(Math.PI / 2) // 绕Z轴旋转 90°
// 缩放
mesh.scale.set(2, 2, 2) // 放大2倍
mesh.scale.set(0.5, 0.5, 0.5) // 缩小一半1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
获取几何体信息
js
const geometry = new THREE.BoxGeometry(2, 2, 2)
console.log(geometry.parameters) // {width: 2, height: 2, depth: 2}
console.log(geometry.type) // 'BoxGeometry'
console.log(geometry.attributes.position.count) // 顶点数(24 = 8个顶点 × 3坐标)
console.log(geometry.index?.count) // 索引数(36 = 12个三角面 × 3顶点)1
2
3
4
5
6
2
3
4
5
6
BufferGeometry
Three.js 所有几何体的底层实现都是 BufferGeometry。
js
// 手动创建 BufferGeometry
const geometry = new THREE.BufferGeometry()
// 定义顶点
const vertices = new Float32Array([
0, 1, 0, // 顶点1
-1, -1, 0, // 顶点2
1, -1, 0 // 顶点3
])
// 设置位置属性
geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3))
// 创建面(索引)
const indices = new Uint16Array([0, 1, 2])
geometry.setIndex(new THREE.BufferAttribute(indices, 1))
// 计算法线(光照需要)
geometry.computeVertexNormals()
const mesh = new THREE.Mesh(
geometry,
new THREE.MeshBasicMaterial({ color: 0xff6b6b, side: THREE.DoubleSide })
)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24