如何基于给定底面四点与高度在Three.js中构建立方体?
解决方法:正确使用ExtrudeGeometry 或 手动构建BufferGeometry
方案1:修正ExtrudeGeometry的用法
你遇到的顶面缺失、底面坐标错误,核心原因是没正确定义挤出的形状轮廓,或参数设置有误。按以下步骤调整即可:
- 将JSON里的底面点转换成Three.js的
Shape对象,点的顺序必须是顺时针/逆时针闭合的矩形(你提供的原始点顺序会导致形状异常,需调整为[0,0,0] → [0,-1,0] → [1,-1,0] → [1,0,0],最后回到起点闭合路径) - 配置ExtrudeGeometry参数时,关闭倒角、设置正确高度,避免额外变形。
示例代码:
// 解析JSON数据 const jsonData = { "points": [ {"x": 0, "y": 0, "z": 0}, {"x": 0, "y": -1, "z": 0}, {"x": 1, "y": -1, "z": 0}, {"x": 1, "y": 0, "z": 0} ] }; // 创建闭合的Shape轮廓 const shape = new THREE.Shape(); const firstPoint = jsonData.points[0]; shape.moveTo(firstPoint.x, firstPoint.y); jsonData.points.forEach(point => shape.lineTo(point.x, point.y)); shape.lineTo(firstPoint.x, firstPoint.y); // 闭合路径 // 生成挤出几何体 const extrudeSettings = { depth: 1, // 立方体高度 bevelEnabled: false, // 关闭倒角,保证规则形状 curveSegments: 1 // 不需要细分直线段 }; const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings); // 创建网格并添加到场景 const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); const mesh = new THREE.Mesh(geometry, material); scene.add(mesh);
方案2:手动构建BufferGeometry(更灵活)
如果ExtrudeGeometry仍有问题,或需要精准控制顶点,可手动生成立方体的所有面:
- 复制底面点,将z值加上高度得到顶面点
- 定义6个面的顶点索引(注意面的法线方向,避免背面消隐)
- 构建BufferGeometry并设置属性
示例代码:
const jsonData = { "points": [ {"x": 0, "y": 0, "z": 0}, {"x": 0, "y": -1, "z": 0}, {"x": 1, "y": -1, "z": 0}, {"x": 1, "y": 0, "z": 0} ] }; const height = 1; // 生成顶面点 const topPoints = jsonData.points.map(p => ({x: p.x, y: p.y, z: p.z + height})); // 合并底面+顶面所有顶点 const allPoints = [...jsonData.points, ...topPoints]; // 定义6个面的三角形索引(每个面由2个三角形组成) const indices = [ // 底面 0, 1, 2, 0, 2, 3, // 顶面 4, 7, 6, 4, 6, 5, // 四个侧面 0, 1, 5, 0, 5, 4, 1, 2, 6, 1, 6, 5, 2, 3, 7, 2, 7, 6, 3, 0, 4, 3, 4, 7 ]; // 创建BufferGeometry const geometry = new THREE.BufferGeometry(); const positions = new Float32Array(allPoints.flatMap(p => [p.x, p.y, p.z])); geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3)); geometry.setIndex(new THREE.BufferAttribute(new Uint16Array(indices), 1)); geometry.computeVertexNormals(); // 计算法线,适配光照 // 创建网格并添加到场景 const material = new THREE.MeshLambertMaterial({ color: 0x00ff00 }); const mesh = new THREE.Mesh(geometry, material); scene.add(mesh);
之前ExtrudeGeometry出错的原因
- 原始点顺序不是闭合的矩形,导致Shape轮廓异常,挤出后顶面无法生成
- 未关闭
bevelEnabled,默认倒角会让形状变形 - 点的顺序不符合Three.js的面法线规则(逆时针为正面),导致底面显示异常
内容的提问来源于stack exchange,提问作者Kronosaurus
相关产品推荐
相关产品推荐

