第三篇:几何体入门:内置几何体全解析
第三篇:几何体入门:内置几何体全解析
引言
几何体是Three.js世界的基石,它们定义了3D物体的形状和结构。Three.js提供20+种内置几何体,从基础立方体到复杂多面体,覆盖90%的3D建模需求。本文将深入解析12种核心几何体,并通过Vue3实现交互式参数调节面板,助你掌握几何造型的核心技术。
1. 几何体核心概念
1.1 顶点(Vertex)与面(Face)
几何体由两大基本元素构成:
- 顶点(Vertex):3D空间中的点,包含(x,y,z)坐标
- 面(Face):由三个顶点组成的三角形(Three.js仅支持三角面)
- 示例:立方体有8个顶点和12个面(6个面×2个三角形)
1.2 几何体类型对比
几何体名称 | 顶点数 | 面数 | 主要参数 | 应用场景 |
---|---|---|---|---|
BoxGeometry | 8 | 12 | 宽/高/深 | 建筑/家具 |
SphereGeometry | 482 | 960 | 半径/分段数 | 星球/粒子 |
CylinderGeometry | 136 | 240 | 顶径/底径/高度 | 柱体/管道 |
TorusGeometry | 800 | 1600 | 半径/管道径/分段数 | 圆环/轮胎 |
IcosahedronGeometry | 12 | 20 | 半径/细节层级 | 低模球体 |
2. 12大核心几何体详解
2.1 立方体(BoxGeometry)
<script setup>
import { ref } from 'vue';const boxParams = ref({width: 1,height: 1,depth: 1,widthSegments: 1,heightSegments: 1,depthSegments: 1
});// 创建立方体
const createBox = () => {return new THREE.BoxGeometry(boxParams.value.width,boxParams.value.height,boxParams.value.depth,boxParams.value.widthSegments,boxParams.value.heightSegments,boxParams.value.depthSegments);
};
</script>
参数解析:
widthSegments
:宽度分段数(影响表面细分)- 当分段数>1时,可用于变形动画或曲面效果
2.2 球体(SphereGeometry)
const sphere = new THREE.SphereGeometry(1, // 半径32, // 经度分段数(水平细分数)16, // 纬度分段数(垂直细分数)0, // 水平起始角度(0-Math.PI*2)Math.PI * 2, // 水平覆盖角度0, // 垂直起始角度(0-Math.PI)Math.PI // 垂直覆盖角度
);
分段数影响:
2.3 圆柱体(CylinderGeometry)
const cylinder = new THREE.CylinderGeometry(0.5, // 顶部半径1, // 底部半径2, // 高度16, // 径向分段数4, // 高度分段数false // 是否开启顶盖/底盖
);
特殊形态:
- 圆锥:顶部半径=0
- 棱柱:分段数=4/6/8
- 圆台:顶部半径≠底部半径
2.4 圆环(TorusGeometry)
const torus = new THREE.TorusGeometry(1, // 圆环半径0.3, // 管道半径16, // 径向分段数100, // 管道分段数Math.PI * 2 // 圆弧角度(缺省为整圆)
);
应用场景:行星环、戒指、管道弯曲
3. 其他实用几何体
3.1 平面(PlaneGeometry)
const plane = new THREE.PlaneGeometry(10, // 宽度10, // 高度10, // 宽度分段10 // 高度分段
);
用途:地面、水面、公告板
3.2 圆环缓冲(TorusKnotGeometry)
const knot = new THREE.TorusKnotGeometry(1, // 半径0.3, // 管道半径100, // 管道分段16, // 交叉分段2, // P值(控制缠绕次数)3 // Q值(控制围绕轴旋转次数)
);
数学原理:通过参数方程生成复杂拓扑结构
3.3 二十面体(IcosahedronGeometry)
const ico = new THREE.IcosahedronGeometry(1, // 半径2 // 细节层级(0=基础,每+1细分4倍面数)
);
特点:最接近球体的多面体,常用于低模风格
4. Vue3实战:几何体参数调节器
4.1 项目结构
src/├── components/│ ├── GeometryController.vue // 参数控制面板│ ├── GeometryViewer.vue // 3D显示组件│ └── ParamSlider.vue // 通用滑动条└── App.vue
4.2 核心代码实现
<!-- GeometryController.vue -->
<script setup>
import { ref, watch } from 'vue';// 支持的几何体类型
const GEOMETRY_TYPES = {BOX: 'Box',SPHERE: 'Sphere',CYLINDER: 'Cylinder',TORUS: 'Torus'
};const currentType = ref(GEOMETRY_TYPES.BOX);// 几何体参数响应式对象
const params = ref({// 立方体参数[GEOMETRY_TYPES.BOX]: {width: 2, height: 1, depth: 1,widthSegments: 1, heightSegments: 1, depthSegments: 1},// 球体参数[GEOMETRY_TYPES.SPHERE]: {radius: 1, widthSegments: 32, heightSegments: 16,phiStart: 0, phiLength: Math.PI * 2,thetaStart: 0, thetaLength: Math.PI},// 圆柱体参数[GEOMETRY_TYPES.CYLINDER]: {radiusTop: 0.5, radiusBottom: 1, height: 2,radialSegments: 32, heightSegments: 8},// 圆环参数[GEOMETRY_TYPES.TORUS]: {radius: 1, tube: 0.3, radialSegments: 100, tubularSegments: 16}
});// 生成当前几何体的配置项
const currentParams = computed(() => ({type: currentType.value,...params.value[currentType.value]
}));// 发射更新事件
const emit = defineEmits(['update']);
watch(currentParams, (val) => {emit('update', val);
}, { deep: true });
</script><template><div class="controller"><select v-model="currentType"><option v-for="(type, key) in GEOMETRY_TYPES" :value="type" :key="key">{{ type }}</option></select><template v-if="currentType === GEOMETRY_TYPES.BOX"><ParamSlider label="宽度" v-model="params.BOX.width" :min="0.1" :max="5" :step="0.1"/><ParamSlider label="高度" v-model="params.BOX.height" :min="0.1" :max="5" :step="0.1"/><ParamSlider label="深度" v-model="params.BOX.depth" :min="0.1" :max="5" :step="0.1"/><!-- 其他参数 --></template><!-- 其他几何体参数控制 --></div>
</template>
4.3 几何体动态更新
<!-- GeometryViewer.vue -->
<script setup>
import { ref, watch } from 'vue';
import * as THREE from 'three';const props = defineProps(['geometryParams']);
let geometry = ref(null);
let mesh = ref(null);// 根据参数创建几何体
const createGeometry = (params) => {switch(params.type) {case 'Box':return new THREE.BoxGeometry(...Object.values(params));case 'Sphere':return new THREE.SphereGeometry(...Object.values(params));// 其他几何体...}
};// 监听参数变化
watch(() => props.geometryParams, (newParams) => {// 释放旧几何体内存if (geometry.value) geometry.value.dispose();// 创建新几何体geometry.value = createGeometry(newParams);// 更新网格if (mesh.value) {mesh.value.geometry = geometry.value;} else {const material = new THREE.MeshNormalMaterial();mesh.value = new THREE.Mesh(geometry.value, material);scene.add(mesh.value);}
}, { immediate: true });
</script>
4.4 性能优化:几何体复用
// 使用BufferGeometryUtils合并几何体
import { mergeBufferGeometries } from 'three/examples/jsm/utils/BufferGeometryUtils';const geometries = [];
for (let i = 0; i < 100; i++) {const box = new THREE.BoxGeometry(0.2, 0.2, 0.2);box.translate(Math.random()*10-5, Math.random()*10-5, Math.random()*10-5);geometries.push(box);
}// 合并为单个几何体(减少Draw Call)
const mergedGeometry = mergeBufferGeometries(geometries);
const mesh = new THREE.Mesh(mergedGeometry, material);
scene.add(mesh);
5. 几何体操作进阶技巧
5.1 顶点修改:创建波浪平面
const plane = new THREE.PlaneGeometry(10, 10, 50, 50);
const positions = plane.attributes.position.array;// 遍历顶点添加波浪效果
for (let i = 0; i < positions.length; i += 3) {const x = positions[i];const z = positions[i+2];// 使用正弦函数生成高度positions[i+1] = Math.sin(x * 0.5) * Math.cos(z * 0.5) * 1.5;
}// 通知Three.js更新
plane.attributes.position.needsUpdate = true;
5.2 UV坐标操作:纹理映射
const geometry = new THREE.BoxGeometry(2, 2, 2);
const uvs = geometry.attributes.uv.array;// 修改UV坐标实现特殊纹理映射
for (let i = 0; i < uvs.length; i += 2) {uvs[i] *= 2; // U坐标拉伸uvs[i+1] *= 2; // V坐标拉伸
}geometry.attributes.uv.needsUpdate = true;// 应用纹理
const texture = new THREE.TextureLoader().load('brick.jpg');
const material = new THREE.MeshBasicMaterial({ map: texture });
5.3 法线重计算
geometry.computeVertexNormals(); // 自动计算法线// 手动修改法线
const normals = geometry.attributes.normal.array;
for (let i = 0; i < normals.length; i += 3) {normals[i] = 0; // X分量normals[i+1] = 1; // Y分量(指向正上方)normals[i+2] = 0; // Z分量
}
geometry.attributes.normal.needsUpdate = true;
6. 性能优化指南
6.1 几何体选择策略
graph TDA[选择几何体] --> B{需要变形?}B -->|是| C[高分段几何体]B -->|否| D{静态物体?}D -->|是| E[使用BufferGeometry]D -->|否| F[使用基础几何体]
6.2 内存管理最佳实践
-
几何体复用:相同物体共享几何体
const boxGeometry = new THREE.BoxGeometry(); const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });const mesh1 = new THREE.Mesh(boxGeometry, material); const mesh2 = new THREE.Mesh(boxGeometry, material.clone());
-
及时释放内存:
// 组件卸载时 onUnmounted(() => {geometry.dispose();material.dispose(); });
-
避免每帧创建:在动画循环外创建几何体
6.3 实例化渲染(InstancedMesh)
const geometry = new THREE.BoxGeometry(0.2, 0.2, 0.2);
const material = new THREE.MeshBasicMaterial();
const instances = new THREE.InstancedMesh(geometry, material, 1000);// 设置每个实例的位置和旋转
const matrix = new THREE.Matrix4();
for (let i = 0; i < 1000; i++) {matrix.setPosition(Math.random() * 100 - 50,Math.random() * 100 - 50,Math.random() * 100 - 50);instances.setMatrixAt(i, matrix);
}scene.add(instances);
性能提升:1000个立方体,Draw Call从1000次降为1次
7. 常见问题解答
Q1:如何创建自定义形状?
- 简单形状:组合基础几何体(Group)
- 复杂形状:使用
BufferGeometry
手动设置顶点 - 专业建模:Blender创建后导出GLTF
Q2:几何体分段数设置多少合适?
- 静态物体:低分段(如Box用1x1x1)
- 曲面物体:32-64分段(球体/圆柱)
- 变形物体:≥64分段(波浪平面)
- 性能临界点:单物体面数<10000
Q3:几何体显示为黑色怎么办?
- 检查材质是否需要光照(
MeshBasicMaterial
不受光) - 确认场景中有灯光
- 验证法线方向是否正确(使用
MeshNormalMaterial
调试)
8. 总结
通过本文,你已掌握:
- 12种核心几何体的创建与参数配置
- 顶点(Vertex)与面(Face)的底层原理
- Vue3实现几何体参数实时调节器
- 几何体内存管理与性能优化技巧
- 高级操作:顶点修改、UV映射、法线计算
关键点:Three.js中所有几何体最终都转换为
BufferGeometry
,它使用TypedArray
直接操作二进制数据,比传统Geometry
性能提升3-5倍。
下一篇预告
第四篇:材质与纹理:让物体"真实"起来
你将学习:
- 6种核心材质特性对比(Basic/Standard/Physical)
- 纹理贴图技术:漫反射/法线/环境遮挡贴图
- UV映射原理与自定义UV展开
- PBR(物理渲染)材质工作流
- Vue3实现材质实时编辑器
准备好为几何体注入灵魂了吗?让我们进入Three.js的视觉魔法世界!