THREE.Geometry will be removed from core with r125

copy looks like there error comes from three.js/BufferGeometry.js at bd095516a119979c9e3684e9f577028506240136 · mrdoob/three.js · GitHub

It’s possible that the BufferGeometry contains interleaved attributes, and some old code is present in that demo from prior to our adding support for cloning interleaved attributes? This should probably be debugged in a new thread I think.


you are right the BufferGeometry have interleaved attributes from glb Model with meshopt

no the problem was undefined uv attribute, all works fine

I’m drawing lines and using TypeScript. Geometry was removed from the Three namespace so I can’t use the static methods on the class as you suggest in the migration section @Mugen87. Is this a bug in the type definitions or am I missing something?

Both methods were added to the d.ts file here:

Probably related to this, but can anyone point me in the right direction in how to achieve Geometry.mergeVertices() for the BufferGeometry?

I am doing it using BufferGeometryUtils.mergeVertices() but the result is very different.

I have

const hull = new ConvexGeometry(vertices) // this is a BufferGeometry

console.log(hull.attributes.position.count) // --> 558

// Geometry mergeVertices
const hullGeometry = new Geometry().fromBufferGeometry(hull)
console.log(hullGeometry.vertices.length) // --> 95

// BufferGeometry mergeVertices
const hullBufferGeometry = BufferGeometryUtils.mergeVertices(hull)
console.log(hullBufferGeometry.attributes.position.count) // --> 556 but it should be 95

jsfiddle here

I am doing this for a physics engine, and the result that works is the one with 95 vertices.

1 Like

You have to delete the normal attribute. Geometry data can only be merged if all vertex data (position, normal, uv etc.) are equal.


All good man, I got it all sorted (literally sorted, had to do materialIndex sorting in BufferGeometry groups to prevent an insane amount of excessive draw calls when using merged BufferGeometry and multiple materials) and am now THREE.Geometry free! Thank you =]


From what I have found CSG works with the geometry objects not the new buffer geometry. I see in the source that it explicitly converts it to THREE.Geometry. Will you have support in the future for subtracting / intersecting / union object?

The official repository does not maintain a CSG library. You have to ask the respective maintainers for buffer geometry support.


The following entry for r126 can be found in Releases · mrdoob/three.js · GitHub.

It is no longer required for intersection as it used to be for BufferGeometry.
But you can still use Face3 if you add examples/jsm/deprecated/Geometry.js.

Do I understand it correctly that now instead of Face3 these lines of code are used?


1 Like

Is there any solution at the moment for the Subdivision Modifier? Now that Face3 is deprecated along with Geometry, existing example of the modifier does not work.

SubdivisionModifier has been removed from the repository with r125. So there is no support for it with newer three.js versions anymore.

1 Like

I had to use SubdivisionModifier recently. If you don’t need any of the newest features, but need subdivisions, you could just install r124.


I use this modifier as a solution to make my 3D models weight very little to reduce Network bandwidth. I send to my client low-poly 3Ds and make them smoother with SubdivisionModifier. I can’t believe SubdivisionModifier being removed completely from 3D solutions, as it is very used in this area. I believe someone would come with a solution for it with the new repo.

I have relied on Geometry only to extract Face normal data to generate STLs from 3D objects. How do I now compute face normals from a BufferGeometry?


You extract the vertices from the position buffer attribute, configure an instance of Triangle with these data and then use Triangle.getNormal().

1 Like

@cabada As a workaround, you can copy the source code of SubdivisionModifier into your own repo and import the deprecated Geometry class from examples/jsm/deprecated/Geometry.js.

SubdivisionModifier was not only removed because it depends on Geometry. It actually never worked properly. Since the maintenance and development effort for this class was just too high, we have decided to no longer support such a modifier. Read the respective PR for more information and alternative workflows.


Hi guys, I am having problems migrating to 125

This is my code

  this.geometry = new THREE.ParametricGeometry(
    (u: number, v: number, result: THREE.Vector3) =>
      this.parametricGeometry.bind(this)(u, v, result, this.getMinX(), this.getMaxX(), this.getMinY(), this.getMaxY()),
    this.getMaxX() - this.getMinX(),
    this.getMaxY() - this.getMinY()

    (face: THREE.Face3) =>
      [face.a, face.b, face.c].forEach(index =>
          new THREE.Color().setHSL(NgxVt.mod(0.68 - (0.83 * ((this.geometry.vertices[index].z - this.getMinZ()) / (this.getMaxZ() - this.getMinZ()))), 1), 1, 0.5)

  this.material = new THREE.MeshBasicMaterial({
    vertexColors: true,
    side: THREE.DoubleSide,
    wireframe: true

  this.material.needsUpdate = true;

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

Now thanks to the snippet provided from @Mugen87 I am doing this :

  const positionAttribute = this.geometry.getAttribute('position');

  const colors = [];
  const color = new THREE.Color();
  const localVertex = new THREE.Vector3();

  for (let vertexIndex = 0; vertexIndex < positionAttribute.count; vertexIndex++) {
    localVertex.fromBufferAttribute(positionAttribute, vertexIndex);
    color.setHSL(NgxVt.mod(0.68 - (0.83 * ((localVertex.z - this.getMinZ()) / (this.getMaxZ() - this.getMinZ()))), 1), 1, 0.5);
    colors.push(color.r, color.g, color.b);

  this.geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));

But my Mesh stay black. I can’t see any color. What’s the equivalent code of what I was doing before ? THREE.Face hasn’t vertexColors attribyte anymore and I can’t find nothing about this in the documentation.

Please help.

Do you mind demonstrating the issue with a complete live example?

BTW: When you create a new material, there is no need to set needsUpdate to true.