如何在Three.js中创建包含3个以上顶点的面?
Question
I've written this Three.js code which creates a face with 3 vertices:
var geometry = new THREE.Geometry(); camera.position.set(1500, -1300, 1500); var vertex = [ new THREE.Vector3(1000, 0, 1000), new THREE.Vector3(2000, 0, 1000), new THREE.Vector3(2000, 0, 2000) ]; geometry.vertices = vertex; var faces = [ new THREE.Face3(0, 1, 2) ]; geometry.faces = faces; var Material = new THREE.MeshBasicMaterial( { color: 'blue'} ); var object = new THREE.Mesh( geometry, Material ); scene.add(object);
I want to create faces that have more vertices (like 4 or more). How can I achieve this?
Answer
Great question! First off, a quick heads-up: THREE.Geometry has been deprecated since Three.js r125, so I’ll cover both the legacy approach (to match your existing code) and the modern, recommended BufferGeometry method that’s now standard.
Legacy Approach (Using THREE.Geometry)
Three.js doesn’t support n-gons (faces with more than 3 vertices) directly—all rendered faces are triangles under the hood. To create a shape with more vertices, you’ll need to split your n-gon into multiple triangular faces.
For example, here’s how to make a 4-vertex quad by splitting it into two Face3 instances:
var geometry = new THREE.Geometry(); camera.position.set(1500, -1300, 1500); // 4 vertices defining a square var vertices = [ new THREE.Vector3(1000, 0, 1000), // Index 0 new THREE.Vector3(2000, 0, 1000), // Index 1 new THREE.Vector3(2000, 0, 2000), // Index 2 new THREE.Vector3(1000, 0, 2000) // Index 3 ]; geometry.vertices = vertices; // Split the quad into two connected triangles var faces = [ new THREE.Face3(0, 1, 2), // First triangle new THREE.Face3(0, 2, 3) // Second triangle ]; geometry.faces = faces; var material = new THREE.MeshBasicMaterial({ color: 'blue' }); var object = new THREE.Mesh(geometry, material); scene.add(object);
For pentagons or more complex shapes, follow the same logic: use a triangle fan (pick one central vertex and connect it to all others) or strip pattern to split the n-gon into overlapping triangles.
Modern Approach (Using BufferGeometry)
BufferGeometry is far more performance-efficient and the current recommended standard. Instead of Face3, you define an index array that maps vertex positions to triangular faces.
Here’s the same quad example using BufferGeometry:
// Define vertex positions (x, y, z for each vertex) const positions = new Float32Array([ 1000, 0, 1000, // Vertex 0 2000, 0, 1000, // Vertex 1 2000, 0, 2000, // Vertex 2 1000, 0, 2000 // Vertex 3 ]); // Create and configure the BufferGeometry const geometry = new THREE.BufferGeometry(); geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3)); // Define triangle indices: two triangles form the quad const indices = new Uint16Array([ 0, 1, 2, // First triangle 0, 2, 3 // Second triangle ]); geometry.setIndex(new THREE.BufferAttribute(indices, 1)); const material = new THREE.MeshBasicMaterial({ color: 'blue' }); const object = new THREE.Mesh(geometry, material); scene.add(object);
This method scales to any number of vertices—just add more positions to the array and extend the index array to split the shape into triangles.
Pro Tip: Auto-Triangulation for Complex Shapes
If you don’t want to manually split n-gons into triangles, use THREE.ShapeGeometry for 2D-based polygons. It automatically handles triangulation for you. Here’s how to make a pentagon:
// Create a 2D pentagon shape const shape = new THREE.Shape(); shape.moveTo(1500, 0); for (let i = 1; i < 5; i++) { const angle = (i * 2 * Math.PI) / 5; const x = 1500 + 500 * Math.cos(angle); const y = 0 + 500 * Math.sin(angle); shape.lineTo(x, y); } shape.lineTo(1500, 0); // Convert the 2D shape to 3D geometry const geometry = new THREE.ShapeGeometry(shape); const material = new THREE.MeshBasicMaterial({ color: 'blue' }); const object = new THREE.Mesh(geometry, material); scene.add(object);
This takes care of all the triangle splitting behind the scenes, which is a huge time-saver for complex polygons.
内容的提问来源于stack exchange,提问作者Przemysław Niemiec

