如何在Three.js中制作非对称矩形棱台(Prismoid)?
自定义BufferGeometry构建异形棱台/平行六面体
对于你需要的这种上下底面为任意矩形、顶部可偏移的拟柱体,Three.js没有内置适配的几何体,最直接高效的方式是手动基于BufferGeometry构建顶点与面数据,具体实现步骤如下:
1. 明确核心参数
先定义形状的关键尺寸与偏移量:
- 底面:宽度
baseWidth、深度baseDepth、高度baseY - 顶面:宽度
topWidth、深度topDepth、高度topY - 顶部偏移:X轴偏移
offsetX、Z轴偏移offsetZ(用来实现非中心对齐)
2. 手动构建顶点数据
按顺时针顺序定义8个顶点(底面4个+顶面4个):
// 底面四个顶点(左下、右下、右上、左上) const baseVerts = [ -baseWidth/2, baseY, -baseDepth/2, baseWidth/2, baseY, -baseDepth/2, baseWidth/2, baseY, baseDepth/2, -baseWidth/2, baseY, baseDepth/2, ]; // 顶面四个顶点(对应底面的偏移位置) const topVerts = [ -topWidth/2 + offsetX, topY, -topDepth/2 + offsetZ, topWidth/2 + offsetX, topY, -topDepth/2 + offsetZ, topWidth/2 + offsetX, topY, topDepth/2 + offsetZ, -topWidth/2 + offsetX, topY, topDepth/2 + offsetZ, ]; // 合并所有顶点 const vertices = [...baseVerts, ...topVerts];
3. 定义三角面索引
Three.js的几何体需要用三角面来渲染,按顺序定义底面、顶面和四个侧面的三角面:
const indices = [ // 底面(两个三角面拼接成矩形) 0, 1, 2, 0, 2, 3, // 顶面(注意顶点顺序要和底面一致,避免法线反向) 4, 6, 5, 4, 7, 6, // 四个侧面(每个侧面用两个三角面) 0, 4, 5, 0, 5, 1, 1, 5, 6, 1, 6, 2, 2, 6, 7, 2, 7, 3, 3, 7, 4, 3, 4, 0, ];
4. 生成BufferGeometry与网格
把顶点和索引数据转为BufferAttribute,创建几何体并计算法向量(让光照正常生效):
const geometry = new THREE.BufferGeometry(); // 设置顶点位置属性 geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3)); // 设置三角面索引 geometry.setIndex(new THREE.Uint16BufferAttribute(indices, 1)); // 自动计算法向量 geometry.computeVertexNormals(); // 创建网格并添加到场景 const material = new THREE.MeshStandardMaterial({ color: 0x4287f5 }); const prismatoid = new THREE.Mesh(geometry, material); scene.add(prismatoid);
5. 扩展优化建议
- 可以把上述逻辑封装成自定义几何体类(比如
PrismatoidGeometry),继承BufferGeometry,方便后续复用 - 如果需要纹理映射,手动添加
uv属性即可,按顶点顺序对应纹理坐标 - 若要支持更复杂的形状(比如顶面和底面顶点数不同),可以调整顶点和面的定义逻辑
内容的提问来源于stack exchange,提问作者shieldgenerator7
相关产品推荐
相关产品推荐

