{T}

内置几何体

Three.js 提供了丰富的内置几何体(Geometry)类,用于创建各种 3D 形状。这些几何体是构建 3D 场景的基础元素。

概述

几何体定义了 3D 对象的形状,包含顶点位置、面、法线、UV 坐标等数据。Three.js 提供了多种内置几何体,可以快速创建常见的 3D 形状。

架构概览

Three.js 内置几何体继承自 BufferGeometry 基类,按照形状特征可分为以下几类:

plaintext
BufferGeometry (基类)
├── 基础几何体
│   ├── BoxGeometry        立方体/长方体
│   ├── SphereGeometry     球体
│   ├── CylinderGeometry   圆柱体
│   ├── PlaneGeometry      平面
│   └── ConeGeometry       圆锥体
├── 高级几何体
│   ├── TorusGeometry      圆环
│   ├── TorusKnotGeometry  圆环结
│   └── PolyhedronGeometry 多面体基类
│       ├── TetrahedronGeometry   正四面体
│       ├── OctahedronGeometry    正八面体
│       ├── DodecahedronGeometry  正十二面体
│       └── IcosahedronGeometry   正二十面体
├── 二维形状几何体
│   ├── CircleGeometry     圆形
│   └── RingGeometry       环形
├── 特殊几何体
│   ├── TextGeometry       文字几何体
│   ├── ExtrudeGeometry    拉伸几何体
│   ├── LatheGeometry      车削几何体
│   └── TubeGeometry       管道几何体
└── 辅助几何体
    ├── EdgesGeometry      边缘几何体
    └── WireframeGeometry  线框几何体

基础几何体

立方体(BoxGeometry)

创建立方体或长方体,是最常用的几何体之一。

javascript
import * as THREE from 'three';
 
// 创建立方体
const geometry = new THREE.BoxGeometry(1, 1, 1);
 
// 创建长方体(宽度、高度、深度)
const boxGeometry = new THREE.BoxGeometry(2, 1, 3);
 
// 带分段的长方体
const segmentedBox = new THREE.BoxGeometry(2, 2, 2, 2, 2, 2);

构造参数

参数类型默认值说明
widthnumber1宽度(X 轴方向)
heightnumber1高度(Y 轴方向)
depthnumber1深度(Z 轴方向)
widthSegmentsnumber1宽度方向分段数
heightSegmentsnumber1高度方向分段数
depthSegmentsnumber1深度方向分段数
typescript
new THREE.BoxGeometry(
  width: number,           // 宽度(默认 1)
  height: number,          // 高度(默认 1)
  depth: number,           // 深度(默认 1)
  widthSegments: number,   // 宽度分段数(默认 1)
  heightSegments: number,  // 高度分段数(默认 1)
  depthSegments: number    // 深度分段数(默认 1)
);

球体(SphereGeometry)

创建球体,支持创建完整球体或部分球体(如半球、扇形球)。

javascript
// 基础球体
const sphere = new THREE.SphereGeometry(1, 32, 32);
 
// 半球
const hemisphere = new THREE.SphereGeometry(
  1,    // 半径
  32,   // 水平分段
  16,   // 垂直分段
  0,    // 水平起始角度
  Math.PI,  // 水平扫描角度
  0,    // 垂直起始角度
  Math.PI / 2  // 垂直扫描角度
);

构造参数

参数类型默认值说明
radiusnumber1球体半径
widthSegmentsnumber32水平分段数(经度方向)
heightSegmentsnumber16垂直分段数(纬度方向)
phiStartnumber0水平起始角度(弧度)
phiLengthnumber水平扫描角度(弧度)
thetaStartnumber0垂直起始角度(弧度)
thetaLengthnumberπ垂直扫描角度(弧度)
typescript
new THREE.SphereGeometry(
  radius: number,              // 半径(默认 1)
  widthSegments: number,       // 水平分段数(默认 32)
  heightSegments: number,      // 垂直分段数(默认 16)
  phiStart: number,            // 水平起始角度(默认 0)
  phiLength: number,           // 水平扫描角度(默认 2π)
  thetaStart: number,          // 垂直起始角度(默认 0)
  thetaLength: number          // 垂直扫描角度(默认 π)
);

圆柱体(CylinderGeometry)

创建圆柱体,通过设置不同的顶部和底部半径,可以创建圆锥、圆台等形状。

javascript
// 基础圆柱体
const cylinder = new THREE.CylinderGeometry(1, 1, 2, 32);
 
// 圆锥(顶部半径为 0)
const cone = new THREE.CylinderGeometry(0, 1, 2, 32);
 
// 圆台
const frustum = new THREE.CylinderGeometry(0.5, 1, 2, 32);

构造参数

参数类型默认值说明
radiusTopnumber1顶部半径
radiusBottomnumber1底部半径
heightnumber1高度
radialSegmentsnumber32径向分段数
heightSegmentsnumber1高度分段数
openEndedbooleanfalse是否开口(无顶底面)
thetaStartnumber0起始角度(弧度)
thetaLengthnumber扫描角度(弧度)
typescript
new THREE.CylinderGeometry(
  radiusTop: number,      // 顶部半径(默认 1)
  radiusBottom: number,   // 底部半径(默认 1)
  height: number,         // 高度(默认 1)
  radialSegments: number, // 径向分段数(默认 32)
  heightSegments: number, // 高度分段数(默认 1)
  openEnded: boolean,     // 是否开口(默认 false)
  thetaStart: number,     // 起始角度(默认 0)
  thetaLength: number     // 扫描角度(默认 2π)
);

平面(PlaneGeometry)

创建平面,默认在 XY 平面上,面向 +Z 方向。

javascript
// 基础平面
const plane = new THREE.PlaneGeometry(2, 2);
 
// 带分段的平面
const segmentedPlane = new THREE.PlaneGeometry(4, 4, 10, 10);

构造参数

参数类型默认值说明
widthnumber1宽度
heightnumber1高度
widthSegmentsnumber1宽度分段数
heightSegmentsnumber1高度分段数
typescript
new THREE.PlaneGeometry(
  width: number,          // 宽度(默认 1)
  height: number,         // 高度(默认 1)
  widthSegments: number,  // 宽度分段数(默认 1)
  heightSegments: number  // 高度分段数(默认 1)
);

高级几何体

圆环(TorusGeometry)

创建圆环体(甜甜圈形状)。

javascript
// 基础圆环
const torus = new THREE.TorusGeometry(1, 0.4, 16, 100);
 
// 扁平圆环
const flatTorus = new THREE.TorusGeometry(2, 0.2, 8, 50);

构造参数

参数类型默认值说明
radiusnumber1圆环中心到管道中心的距离
tubenumber0.4管道半径
radialSegmentsnumber12径向分段数
tubularSegmentsnumber48管道分段数
arcnumber圆弧角度(弧度)
typescript
new THREE.TorusGeometry(
  radius: number,           // 圆环半径(默认 1)
  tube: number,             // 管道半径(默认 0.4)
  radialSegments: number,   // 径向分段数(默认 12)
  tubularSegments: number,  // 管道分段数(默认 48)
  arc: number               // 圆弧角度(默认 2π)
);

圆环结(TorusKnotGeometry)

创建圆环结(三叶结),通过 p 和 q 参数控制缠绕方式。

javascript
// 基础圆环结
const torusKnot = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);
 
// 自定义参数(p=3, q=4 的环面结)
const customKnot = new THREE.TorusKnotGeometry(1, 0.3, 100, 16, 3, 4);

构造参数

参数类型默认值说明
radiusnumber1整体半径
tubenumber0.4管道半径
tubularSegmentsnumber64管道分段数
radialSegmentsnumber8径向分段数
pnumber2缠绕次数 p(绕大圆)
qnumber3缠绕次数 q(绕小圆)
typescript
new THREE.TorusKnotGeometry(
  radius: number,           // 半径(默认 1)
  tube: number,             // 管道半径(默认 0.4)
  tubularSegments: number,  // 管道分段数(默认 64)
  radialSegments: number,   // 径向分段数(默认 8)
  p: number,                // 缠绕次数 p(默认 2)
  q: number                 // 缠绕次数 q(默认 3)
);

多面体

多面体几何体基于正多面体,通过 detail 参数可以增加细分级别。

正四面体(TetrahedronGeometry)

javascript
const tetrahedron = new THREE.TetrahedronGeometry(1);
// 4 个面,每个面是等边三角形

正八面体(OctahedronGeometry)

javascript
const octahedron = new THREE.OctahedronGeometry(1);
// 8 个面,每个面是等边三角形

正十二面体(DodecahedronGeometry)

javascript
const dodecahedron = new THREE.DodecahedronGeometry(1);
// 12 个面,每个面是正五边形

正二十面体(IcosahedronGeometry)

javascript
const icosahedron = new THREE.IcosahedronGeometry(1, 0);
// 20 个面,每个面是等边三角形
// 常用于创建近似球体或细分表面

多面体通用参数

参数类型默认值说明
radiusnumber1外接球半径
detailnumber0细分级别(0 为原始形状)
typescript
new THREE.XGeometry(
  radius: number,      // 半径(默认 1)
  detail: number       // 细分级别(默认 0)
);

圆锥体(ConeGeometry)

圆锥体是圆柱体的特殊形式,顶部半径为 0。

javascript
// 基础圆锥
const cone = new THREE.ConeGeometry(1, 2, 32);
 
// 开口圆锥
const openCone = new THREE.ConeGeometry(1, 2, 32, 1, true);

构造参数

参数类型默认值说明
radiusnumber1底部半径
heightnumber1高度
radialSegmentsnumber32径向分段数
heightSegmentsnumber1高度分段数
openEndedbooleanfalse是否开口
thetaStartnumber0起始角度
thetaLengthnumber扫描角度
typescript
new THREE.ConeGeometry(
  radius: number,         // 底部半径(默认 1)
  height: number,         // 高度(默认 1)
  radialSegments: number, // 径向分段数(默认 32)
  heightSegments: number, // 高度分段数(默认 1)
  openEnded: boolean,     // 是否开口(默认 false)
  thetaStart: number,     // 起始角度(默认 0)
  thetaLength: number     // 扫描角度(默认 2π)
);

二维形状几何体

圆形(CircleGeometry)

创建平面圆形或扇形。

javascript
// 完整圆形
const circle = new THREE.CircleGeometry(1, 32);
 
// 扇形(四分之一圆)
const sector = new THREE.CircleGeometry(1, 32, 0, Math.PI / 2);

构造参数

参数类型默认值说明
radiusnumber1半径
segmentsnumber32边数(值越大越圆滑)
thetaStartnumber0起始角度
thetaLengthnumber扫描角度
typescript
new THREE.CircleGeometry(
  radius: number,      // 半径(默认 1)
  segments: number,    // 分段数(默认 32)
  thetaStart: number,  // 起始角度(默认 0)
  thetaLength: number  // 扫描角度(默认 2π)
);

环形(RingGeometry)

创建平面环形(圆环面)。

javascript
// 基础环形
const ring = new THREE.RingGeometry(0.5, 1, 32);
 
// 部分环形(半圆环)
const partialRing = new THREE.RingGeometry(0.5, 1, 32, 1, 0, Math.PI);

构造参数

参数类型默认值说明
innerRadiusnumber0.5内半径
outerRadiusnumber1外半径
thetaSegmentsnumber32圆周分段数
phiSegmentsnumber1径向分段数(环形厚度分段)
thetaStartnumber0起始角度
thetaLengthnumber扫描角度
typescript
new THREE.RingGeometry(
  innerRadius: number,    // 内半径(默认 0.5)
  outerRadius: number,    // 外半径(默认 1)
  thetaSegments: number,  // 径向分段数(默认 32)
  phiSegments: number,    // 环形分段数(默认 1)
  thetaStart: number,     // 起始角度(默认 0)
  thetaLength: number     // 扫描角度(默认 2π)
);

特殊几何体

文字几何体(TextGeometry)

需要加载字体文件后创建 3D 文字。

javascript
import { FontLoader } from 'three/addons/loaders/FontLoader.js';
import { TextGeometry } from 'three/addons/geometries/TextGeometry.js';
 
const loader = new FontLoader();
 
loader.load('fonts/helvetiker_regular.typeface.json', (font) => {
  const textGeometry = new TextGeometry('Hello Three.js', {
    font: font,
    size: 1,
    height: 0.2,
    curveSegments: 12,
    bevelEnabled: true,
    bevelThickness: 0.03,
    bevelSize: 0.02,
    bevelOffset: 0,
    bevelSegments: 5
  });
  
  const textMesh = new THREE.Mesh(textGeometry, material);
  scene.add(textMesh);
});

构造参数

参数类型默认值说明
fontFont-字体对象(必需)
sizenumber100文字大小
heightnumber50挤出厚度
curveSegmentsnumber12曲线分段数
bevelEnabledbooleanfalse是否启用倒角
bevelThicknessnumber10倒角厚度
bevelSizenumber8倒角大小
bevelOffsetnumber0倒角偏移
bevelSegmentsnumber3倒角分段数
typescript
new TextGeometry(text: string, {
  font: Font,              // 字体对象(必需)
  size: number,            // 文字大小(默认 100)
  height: number,          // 文字厚度(默认 50)
  curveSegments: number,   // 曲线分段数(默认 12)
  bevelEnabled: boolean,   // 是否启用倒角(默认 false)
  bevelThickness: number,  // 倒角厚度(默认 10)
  bevelSize: number,       // 倒角大小(默认 8)
  bevelOffset: number,     // 倒角偏移(默认 0)
  bevelSegments: number    // 倒角分段数(默认 3)
});

拉伸几何体(ExtrudeGeometry)

从 2D 形状(Shape)拉伸成 3D 几何体。

javascript
// 创建 2D 形状
const shape = new THREE.Shape();
shape.moveTo(0, 0);
shape.lineTo(1, 0);
shape.lineTo(1, 1);
shape.lineTo(0, 1);
shape.lineTo(0, 0);
 
// 拉伸设置
const extrudeSettings = {
  depth: 2,           // 拉伸深度
  bevelEnabled: true, // 启用倒角
  bevelThickness: 0.2,
  bevelSize: 0.1,
  bevelSegments: 3
};
 
const extrudeGeometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);
const extrudeMesh = new THREE.Mesh(extrudeGeometry, material);
scene.add(extrudeMesh);

车削几何体(LatheGeometry)

通过旋转轮廓线创建旋转体(如花瓶、酒杯、碗等)。

javascript
// 定义轮廓点
const points = [];
for (let i = 0; i < 10; i++) {
  points.push(
    new THREE.Vector2(
      Math.sin(i * 0.2) * 2 + 1,  // x 坐标(半径)
      i * 0.5                      // y 坐标
    )
  );
}
 
// 创建车削几何体
const latheGeometry = new THREE.LatheGeometry(points, 30);
const latheMesh = new THREE.Mesh(latheGeometry, material);
scene.add(latheMesh);

构造参数

参数类型默认值说明
pointsVector2[]-轮廓点数组
segmentsnumber12圆周分段数
phiStartnumber0起始角度
phiLengthnumber旋转角度
typescript
new THREE.LatheGeometry(
  points: Vector2[],       // 轮廓点数组
  segments: number,        // 分段数(默认 12)
  phiStart: number,        // 起始角度(默认 0)
  phiLength: number        // 旋转角度(默认 2π)
);

管道几何体(TubeGeometry)

沿曲线路径创建管道形状。

javascript
// 定义自定义曲线
class CustomCurve extends THREE.Curve {
  getPoint(t) {
    const x = Math.cos(t * Math.PI * 2);
    const y = Math.sin(t * Math.PI * 2);
    const z = t * 2;
    return new THREE.Vector3(x, y, z);
  }
}
 
const curve = new CustomCurve();
 
// 创建管道几何体
const tubeGeometry = new THREE.TubeGeometry(curve, 100, 0.2, 8, false);
const tubeMesh = new THREE.Mesh(tubeGeometry, material);
scene.add(tubeMesh);

构造参数

参数类型默认值说明
pathCurve-路径曲线
tubularSegmentsnumber64管道分段数
radiusnumber1管道半径
radialSegmentsnumber8径向分段数
closedbooleanfalse是否闭合
typescript
new THREE.TubeGeometry(
  path: Curve,             // 路径曲线
  tubularSegments: number, // 管道分段数(默认 64)
  radius: number,          // 管道半径(默认 1)
  radialSegments: number,  // 径向分段数(默认 8)
  closed: boolean          // 是否闭合(默认 false)
);

几何体属性

顶点属性

所有几何体都包含以下核心属性:

javascript
const geometry = new THREE.BoxGeometry(1, 1, 1);
 
// 获取顶点位置
const position = geometry.attributes.position;
 
// 获取顶点数量
const vertexCount = position.count;
 
// 获取顶点法线
const normal = geometry.attributes.normal;
 
// 获取 UV 坐标
const uv = geometry.attributes.uv;
 
// 获取顶点颜色(可选)
const color = geometry.attributes.color;

常用顶点属性说明

属性名数据类型说明
positionFloat32Array顶点位置(x, y, z)
normalFloat32Array顶点法线方向
uvFloat32Array纹理坐标(u, v)
uv2Float32Array第二组纹理坐标
colorFloat32Array顶点颜色(RGB)
indexUint16Array/Uint32Array顶点索引

边界信息

边界信息用于视锥剔除、碰撞检测等。

javascript
// 计算边界球
geometry.computeBoundingSphere();
console.log('边界球半径:', geometry.boundingSphere.radius);
console.log('边界球中心:', geometry.boundingSphere.center);
 
// 计算边界框
geometry.computeBoundingBox();
console.log('边界框最小点:', geometry.boundingBox.min);
console.log('边界框最大点:', geometry.boundingBox.max);
 
// 获取几何体中心
const center = new THREE.Vector3();
geometry.computeBoundingBox();
geometry.boundingBox.getCenter(center);

几何体变换

直接修改几何体顶点数据的变换方法:

javascript
// 平移
geometry.translate(x, y, z);
 
// 旋转
geometry.rotateX(angle);
geometry.rotateY(angle);
geometry.rotateZ(angle);
 
// 缩放
geometry.scale(x, y, z);
 
// 居中(将几何体中心移到原点)
geometry.center();
注意

几何体变换会直接修改顶点数据,与 Mesh 的 position、rotation、scale 属性不同。后者是通过变换矩阵实现的,不会修改几何体数据。

使用示例

创建多个几何体

javascript
import * as THREE from 'three';
 
// 创建场景、相机、渲染器
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
 
// 创建材质
const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });
 
// 创建多个几何体
const box = new THREE.Mesh(
  new THREE.BoxGeometry(1, 1, 1),
  material
);
box.position.set(-3, 0, 0);
scene.add(box);
 
const sphere = new THREE.Mesh(
  new THREE.SphereGeometry(0.5, 32, 32),
  material
);
sphere.position.set(0, 0, 0);
scene.add(sphere);
 
const cylinder = new THREE.Mesh(
  new THREE.CylinderGeometry(0.5, 0.5, 1, 32),
  material
);
cylinder.position.set(3, 0, 0);
scene.add(cylinder);
 
// 添加光源
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(5, 5, 5);
scene.add(light);
 
const ambientLight = new THREE.AmbientLight(0x404040);
scene.add(ambientLight);
 
camera.position.z = 5;
 
// 动画循环
function animate() {
  requestAnimationFrame(animate);
  
  box.rotation.x += 0.01;
  box.rotation.y += 0.01;
  
  sphere.rotation.x += 0.01;
  sphere.rotation.y += 0.01;
  
  cylinder.rotation.x += 0.01;
  cylinder.rotation.y += 0.01;
  
  renderer.render(scene, camera);
}
 
animate();

使用线框模式

javascript
// 方法一:材质线框模式
const geometry = new THREE.IcosahedronGeometry(1, 0);
const wireframeMaterial = new THREE.MeshBasicMaterial({
  color: 0x00ff00,
  wireframe: true
});
const wireframeMesh = new THREE.Mesh(geometry, wireframeMaterial);
scene.add(wireframeMesh);
 
// 方法二:使用 WireframeGeometry
const wireframeGeometry = new THREE.WireframeGeometry(geometry);
const line = new THREE.LineSegments(
  wireframeGeometry,
  new THREE.LineBasicMaterial({ color: 0x00ff00 })
);
scene.add(line);

创建边缘几何体

javascript
// 创建立方体
const box = new THREE.BoxGeometry(1, 1, 1);
 
// 创建边缘几何体(阈值角度 15 度)
const edges = new THREE.EdgesGeometry(box, 15);
 
// 创建线条
const line = new THREE.LineSegments(
  edges,
  new THREE.LineBasicMaterial({ color: 0xffffff })
);
scene.add(line);

性能考虑

分段数优化

分段数直接影响顶点数量和渲染性能:

javascript
// 低多边形风格(性能优先)
const lowPolySphere = new THREE.SphereGeometry(1, 8, 8);
// 顶点数:约 81 个
 
// 标准质量
const standardSphere = new THREE.SphereGeometry(1, 32, 32);
// 顶点数:约 1,056 个
 
// 高质量渲染(质量优先)
const highQualitySphere = new THREE.SphereGeometry(1, 64, 64);
// 顶点数:约 4,224 个

LOD(细节层次)

根据距离使用不同细节级别的几何体:

javascript
function createSphereWithLOD() {
  const lod = new THREE.LOD();
  const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });
  
  // 近距离:高质量
  const highDetail = new THREE.Mesh(
    new THREE.SphereGeometry(1, 32, 32),
    material
  );
  lod.addLevel(highDetail, 0);
  
  // 中距离:中等质量
  const mediumDetail = new THREE.Mesh(
    new THREE.SphereGeometry(1, 16, 16),
    material
  );
  lod.addLevel(mediumDetail, 10);
  
  // 远距离:低质量
  const lowDetail = new THREE.Mesh(
    new THREE.SphereGeometry(1, 8, 8),
    material
  );
  lod.addLevel(lowDetail, 20);
  
  return lod;
}

几何体复用

相同形状的对象应共享几何体实例:

javascript
// ❌ 不推荐:每个网格创建新几何体
for (let i = 0; i < 100; i++) {
  const geometry = new THREE.BoxGeometry(1, 1, 1);
  const mesh = new THREE.Mesh(geometry, material);
  mesh.position.x = i * 2;
  scene.add(mesh);
}
 
// ✅ 推荐:复用几何体
const geometry = new THREE.BoxGeometry(1, 1, 1);
for (let i = 0; i < 100; i++) {
  const mesh = new THREE.Mesh(geometry, material);
  mesh.position.x = i * 2;
  scene.add(mesh);
}

内存管理

几何体使用后需要正确释放内存:

javascript
// 创建几何体
const geometry = new THREE.BoxGeometry(1, 1, 1);
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
 
// 不再需要时
scene.remove(mesh);
geometry.dispose();  // 释放几何体 GPU 内存
material.dispose();  // 释放材质内存

几何体对比速查表

几何体典型顶点数*适用场景性能影响
BoxGeometry24建筑、家具、UI 元素
PlaneGeometry4地面、墙壁、广告牌极低
SphereGeometry513行星、球体物体
CylinderGeometry130管道、柱子低-中
ConeGeometry65屋顶、冰淇淋
TorusGeometry806甜甜圈、轮胎
TorusKnotGeometry1,793装饰、抽象图形
IcosahedronGeometry12低多边形球体、粒子极低

*基于默认分段参数

常见问题解答

Q: 为什么我的球体看起来不圆滑?

A: 增加分段数参数。球体的圆滑度由 widthSegmentsheightSegments 参数决定:

javascript
// 锯齿明显的球体
const roughSphere = new THREE.SphereGeometry(1, 8, 8);
 
// 圆滑的球体
const smoothSphere = new THREE.SphereGeometry(1, 64, 64);

Q: 如何创建空心圆柱?

A: 使用 openEnded: true 参数:

javascript
const hollowCylinder = new THREE.CylinderGeometry(1, 1, 2, 32, 1, true);

Q: 平面几何体默认朝向哪里?

A: PlaneGeometry 默认在 XY 平面上,面朝 +Z 方向。如需改变朝向,可以旋转:

javascript
const plane = new THREE.PlaneGeometry(2, 2);
plane.rotateX(-Math.PI / 2);  // 水平放置,面朝 +Y

Q: 如何获取几何体的实际尺寸?

A: 使用边界框计算:

javascript
const geometry = new THREE.BoxGeometry(2, 3, 1);
geometry.computeBoundingBox();
const size = new THREE.Vector3();
geometry.boundingBox.getSize(size);
console.log('尺寸:', size);  // Vector3 {x: 2, y: 3, z: 1}

Q: 几何体变换和 Mesh 变换有什么区别?

A:

  • 几何体变换geometry.translate()):直接修改顶点数据,影响所有使用该几何体的网格
  • Mesh 变换mesh.position):通过变换矩阵实现,不修改几何体数据,可逆
javascript
// 几何体变换 - 永久修改顶点
const geo1 = new THREE.BoxGeometry(1, 1, 1);
geo1.translate(2, 0, 0);
 
// Mesh 变换 - 不修改几何体
const geo2 = new THREE.BoxGeometry(1, 1, 1);
const mesh = new THREE.Mesh(geo2, material);
mesh.position.set(2, 0, 0);

Q: 如何选择合适的分段数?

A: 根据以下因素权衡:

  1. 物体距离相机的远近:远距离物体可用较少分段
  2. 物体大小:大型物体需要更多分段
  3. 性能预算:移动端或复杂场景应减少分段
  4. 视觉效果需求:重要展示物体可增加分段

推荐值:

  • 球体:widthSegments: 32, heightSegments: 32
  • 圆柱:radialSegments: 32
  • 圆环:radialSegments: 16, tubularSegments: 48

最佳实践

  1. 合理设置分段数:根据距离和重要性设置合适的分段数,平衡质量和性能
  2. 复用几何体:相同形状的对象共享几何体实例,减少内存和 GPU 开销
  3. 及时释放内存:不再使用的几何体调用 dispose() 方法释放 GPU 内存
  4. 使用边界检测:通过边界框/球进行视锥剔除优化
  5. 选择合适几何体:根据需求选择最简单的几何体类型
  6. 预计算边界:在创建几何体后立即调用 computeBoundingBox()computeBoundingSphere()
  7. 使用索引缓冲区:对于复杂几何体,使用索引可以减少顶点数据量

相关链接