52

I've asked this and got the answer:

var geom = new THREE.Geometry(); 
var v1 = new THREE.Vector3(0,0,0);
var v2 = new THREE.Vector3(0,500,0);
var v3 = new THREE.Vector3(0,500,500);

geom.vertices.push(new THREE.Vertex(v1));
geom.vertices.push(new THREE.Vertex(v2));
geom.vertices.push(new THREE.Vertex(v3));

var object = new THREE.Mesh( geom, new THREE.MeshNormalMaterial() );
scene.addObject(object);

I expected this to work but it didn't.

1
  • 4
    I know this question is old but just for reference this article and this one cover this topic Commented Jun 14, 2019 at 6:58

3 Answers 3

81

You've added vertices, but forgot to put those vertices into a face and add that to the geometry:

geom.faces.push( new THREE.Face3( 0, 1, 2 ) );

so your snippet becomes:

var geom = new THREE.Geometry(); 
var v1 = new THREE.Vector3(0,0,0);
var v2 = new THREE.Vector3(0,500,0);
var v3 = new THREE.Vector3(0,500,500);

geom.vertices.push(v1);
geom.vertices.push(v2);
geom.vertices.push(v3);

geom.faces.push( new THREE.Face3( 0, 1, 2 ) );

var object = new THREE.Mesh( geom, new THREE.MeshNormalMaterial() );
scene.addObject(object);

The idea is that a Face3 instance references 3 vertices(the x,y,z coords you've added previously to the geometry) by using the indices of the vertices in the list/array. Currently you only have 3 vertices and you want to connect them,so your face references index 0,1 and 2 in the vertices array.

Since you're using a mesh normals material, you might want to compute normals for the geometry. Also, make sure your object can be visible (is not to big or to close to the camera to be clipped out, is facing the right direction - towards the camera, etc.) Since you're drawing in the YZ plane, to see your triangle, something like this should work:

var geom = new THREE.Geometry(); 
var v1 = new THREE.Vector3(0,0,0);
var v2 = new THREE.Vector3(0,500,0);
var v3 = new THREE.Vector3(0,500,500);

geom.vertices.push(v1);
geom.vertices.push(v2);
geom.vertices.push(v3);
                
geom.faces.push( new THREE.Face3( 0, 1, 2 ) );
geom.computeFaceNormals();
                
var object = new THREE.Mesh( geom, new THREE.MeshNormalMaterial() );
                
object.position.z = -100;//move a bit back - size of 500 is a bit big
object.rotation.y = -Math.PI * .5;//triangle is pointing in depth, rotate it -90 degrees on Y
                
scene.add(object);

Update: THREE.Geometry and THREE.Face3 are deprecated: THREE.BufferGeometry is recommended instead.

const geometry = new THREE.BufferGeometry();

const positions = [
0,   0, 0,    // v1
0, 500, 0,   // v2
0, 500, 500  // v3
];

geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) );
geometry.computeVertexNormals();

const object = new THREE.Mesh( geometry, new THREE.MeshNormalMaterial() );
scene.add(object);

In short, as opposed to providing vertex positions and Face3 objects with 3 vertex indices now you would use a flat array in x1, y1, z1, x2, y2, z2, ..., xn, yn, zn order (every 3 x,y,z triplets in order define a face).

Additionally, it's possible to compute and provide vertex colours and normals. There are plenty of three.js example to start with, including:

webgl_buffergeometry three.js triangles example

webgl_buffergeometry_indexed three.js subdivided plane example

Sign up to request clarification or add additional context in comments.

3 Comments

Well, THREE.Geometry was deprecated after some years.. mainly for performance discourse.threejs.org/t/…
@jiyinyiyong Thank you for that ! It's been a while since I posted this answer :) I've added a few minimal notes.
Haha, I just debugged that last night, turned out .computeVertexNormals() must be called, otherwise the object is not displayed in correct color without normals.
30

You can automate your triangulation

For big polygons it can be quite a job to manually add the faces. You can automate the process of adding faces to the mesh using the triangulateShape method in THREE.ShapeUtils like this:

var vertices = [your vertices array];
var holes = [];
var triangles, mesh;
var geometry = new THREE.BufferGeometry();
var material = new THREE.MeshBasicMaterial();

geometry.setFromPoints(vertices);

triangles = THREE.ShapeUtils.triangulateShape(vertices, holes);
geometry.setIndex(triangles.flat());

mesh = new THREE.Mesh(geometry, material);

Where vertices is your array of vertices and with holes you can define holes in your polygon.

Note: Be careful, if your polygon is self intersecting it will throw an error. Make sure your vertices array is representing a valid (non intersecting) polygon.

5 Comments

This method seems to completely ignore Z axis, and work only in 2D. Doesn't work at all with 3d vertices.
THREE.Shape.Utils.triangulateShape doesn't work anymore.
@GamsterKatalin Check my updated answer. In newer versions it is: THREE.ShapeUtils.triangulateShape.
Your answer doesn't automate triangulation for 3d vertices (giving me a lot of warnings because x-y points are duplicated, triangulation failing in the end), so now I am trying to figure out the rationale behind generating those index points that face3 is built out of: github.com/josdirksen/learning-threejs/blob/master/chapter-02/… considering that they are hundreds of vertices from autocad objects.
@GamsterKatalin Triangulation is only for 2D shapes. Currently you won't find any triangulation libraries in javascript that work in 3D. You will have to work around. One solution would be to use a rotation matrix to rotate your 3D shape into the x-y plane and then triangulate and rotate the result back with the inverse matrix.
10

THREE.Vertex has been deprecated in the newest version of Three.js so that part is not needed anymore:

geom.vertices.push(v1);
geom.vertices.push(v2);
geom.vertices.push(v3);

1 Comment

Note that this refers to an earlier revision of George Profenza's answer. Nothing should be removed from Profenza's current code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.