How to smooth an OBJ with threejs?

45%20PM

I understand there are ways to smooth OBJs in blender/etc.

But, is there any way to do it with just threejs?

Things to try:

  • mesh.material.flatShading = false
  • mesh.geometry.computeVertexNormals()
  • If neither of the above works, you may need to merge vertices. THREE.BufferGeometry doesn’t implement this yet unfortunately, so you’d need to convert the mesh geometry to THREE.Geometry, merge, then optionally convert back to BufferGeometry.
1 Like

Thanks for the response. Gave it a go!

mesh.material.flatShading = false
nope :((

mesh.geometry.computeVertexNormals()
nope :((

“convert the mesh geometry to THREE.Geometry , merge, then optionally convert back to BufferGeometry”.
^ how would one do such magic?

here is the geo:
15%20PM

I believe it should be:

var a = new THREE.Geometry().fromBufferGeometry( mesh.geometry );
a.mergeVertices();
mesh.geometry.fromGeometry( a );

see three.js docs for details. :slight_smile:

1 Like

Sadly no luck :((
Does this look correct?

		object.traverse( function ( child ) {
			if ( child instanceof THREE.Object3D ) {
				if(child.geometry !== undefined){ 

					console.log("~ geometry ~");
					console.log(child.geometry);

					var a = new THREE.Geometry().fromBufferGeometry( child.geometry );
					a.mergeVertices();
					child.geometry.fromGeometry( a );

					console.log("~ smooth geometry ~");
					console.log(child.geometry);

				}
			}
		});

No errors, but no effect? Combining that with the other two suggestions above may help. Otherwise, are you able to create a demo?

There is one other way that you can do the smoothing.

Just like you would do a subdivision in any 3d modelling application, you can do it in threejs as well using subdivision modifier.

Here’s an example https://threejs.org/examples/?q=subd#webgl_modifier_subdivision

1 Like

@donmccurdy

https://fuzzywobble.com/projects/webgl/obj_test_smoothing/web/index.html

^ demo

Hi @fuzzy_wobble,

your OBJ model does not define any normals and has many identical vertices defined more than once. If you use OBJLoader2 with setUseIndices( true ) it removes identical vertices along and it computes vertexNormals if they are not defined afterwards, then the ballon_dog looks as follows:
image
OBJLoader2 identified 6873 multiple vertex definitions.

As I understand it, geometry.mergeVertices() + geometry.computeVertexNormals() should have the same effect. Did you try both together with OBJLoader?

Kai

2 Likes

looks fine and it works for me.

Since the support for THREE.Geometry is completly removed in v125 the accepted solution is broken.
As THREE.Geometry is deprecated it seems there is no built in future-proof implementation to achieve this ? Or is planned to get the THREE.Geometry-related methods implemented in THREE.BufferGeometry ?

If you refer to the mergeVertices you can use BufferGeometryUtils.mergeVertices(geometry), see docs

5 Likes

After v125 I had the same issue and solved it with the following:

child.geometry.deleteAttribute(‘normal’);
child.geometry = mergeVertices(child.geometry);
child.geometry.computeVertexNormals(child.geometry);

without .deleteAttribute(‘normal’) there was no effect from mergeVerticies or computeVertexNormals.

2 Likes

Good job that you figured it out. The reason why your fix worked is that mergeVertices considers All attributes of the vertex to decide whether its close enough to merge with neighboring vertices… for instance… 2 vertices with the same position but different UV coordinates… should not be merged… and also if they have 2 different normals, then it considers them too different to merge. By deleting the normals, you allow mergeVertices to merge based only on position+uv which gives its more freedom to merge.

1 Like

computeVertexNormals() has no parameters. The complete code snippet should look like so:

child.geometry.deleteAttribute( ‘normal’ );
child.geometry = BufferGeometryUtils.mergeVertices( geometry );
child.geometry.computeVertexNormals();

If the OBJ has a uv and/or color attribute, you might have to delete them as well since vertices can only be merged if the entire vertex data are equal. That would be not true if e.g. two identical vertices have different uv coordiantes or color values.

2 Likes