You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Three.js渲染由输入顶点定义的直边多边形?

嘿,完全不用碰贝塞尔曲线哦!Three.js渲染直边多边形其实很直接,毕竟WebGL底层是靠三角形绘制图形的,咱只要把多边形拆成合适的三角形(或者直接画边框)就行,给你一步步说:

1. 整理顶点数据

首先把你的(x,y,z)顶点转换成扁平化的数组,比如你有四个顶点(0,0,0)、(1,0,0)、(1,1,0)、(0,1,0),就转成:

const vertices = [0,0,0, 1,0,0, 1,1,0, 0,1,0];

这样Three.js能直接用Float32BufferAttribute来处理。

2. 创建几何体

用BufferGeometry(性能比旧的Geometry好太多),把顶点数据设置进去。如果要渲染填充的多边形,关键是要给几何体加索引(indices)——因为WebGL只能画三角形,所以得把多边形拆成多个三角形:

const geometry = new THREE.BufferGeometry();
// 传入顶点数组,第二个参数3表示每3个元素对应一个顶点的x/y/z
geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));

// 举个四边形的索引:拆成两个三角形
const indices = [
  0, 1, 2,  // 第一个三角形:顶点0→1→2
  0, 2, 3   // 第二个三角形:顶点0→2→3
];
geometry.setIndex(indices);

如果是复杂的凹多边形,手动拆三角太麻烦,可以用Three.js自带的THREE.TriangulationUtils.triangulateShape()来自动生成索引,省不少事。

3. 选合适的材质
  • 要填充的多边形:用MeshBasicMaterial(不受光照影响)或者MeshLambertMaterial/MeshPhongMaterial(受光照影响),记得加side: THREE.DoubleSide,不然多边形背面可能看不见:
    const fillMaterial = new THREE.MeshBasicMaterial({
      color: 0x00ff00,
      side: THREE.DoubleSide
    });
    
  • 只要边框:用LineBasicMaterial,然后配合LineLoop(自动把最后一个顶点连回第一个):
    const lineMaterial = new THREE.LineBasicMaterial({ color: 0x0000ff });
    
4. 创建网格/线条并加入场景
  • 填充多边形:用Mesh把几何体和材质组合起来,加到场景:
    const polygonMesh = new THREE.Mesh(geometry, fillMaterial);
    scene.add(polygonMesh);
    
  • 边框:用LineLoop:
    const polygonBorder = new THREE.LineLoop(geometry, lineMaterial);
    scene.add(polygonBorder);
    
完整示例代码
// 初始化基础场景、相机、渲染器(这部分是Three.js基础操作)
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 vertices = [
  0, 0, 0,
  2, 0, 0,
  2, 1, 0,
  1, 2, 0,
  0, 1, 0
];

// 创建几何体
const geometry = new THREE.BufferGeometry();
geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));

// 自动三角化(适合复杂多边形)
const shapePoints = vertices.reduce((acc, val, idx) => {
  if (idx % 3 === 0) acc.push(new THREE.Vector2(val, vertices[idx+1]));
  return acc;
}, []);
const indices = THREE.TriangulationUtils.triangulateShape(shapePoints, []);
geometry.setIndex(indices);

// 填充材质+网格
const fillMaterial = new THREE.MeshBasicMaterial({ color: 0xff9900, side: THREE.DoubleSide });
const polygon = new THREE.Mesh(geometry, fillMaterial);
scene.add(polygon);

// 边框材质+线条
const lineMaterial = new THREE.LineBasicMaterial({ color: 0x000000, linewidth: 2 });
const border = new THREE.LineLoop(geometry, lineMaterial);
scene.add(border);

// 调整相机位置
camera.position.z = 5;

// 渲染循环
function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}
animate();

注意哈:如果你的多边形是3D空间里的(不是平面),只要顶点坐标是对的,上面的方法同样适用——Three.js会自动处理3D空间的面渲染。

内容的提问来源于stack exchange,提问作者Mandroid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 11:02:51