Subdivision modifier not working

I wanted to try the subdivision modifier, so I started by applying it to a basic cube to learn how to use it, I tried to replicate what I’ve seen in several examples but I can’t make it work, nevermind more complex models. This is the code that creates the cube and is supposed to apply the modifier

var geometry = new THREE.BoxGeometry(10,10,10);

var smooth = geometry.clone();
smooth.mergeVertices();

var divisions = 3;
var modifier = new THREE.SubdivisionModifier(divisions);

modifier.modify(smooth);

const edges = new THREE.EdgesGeometry(smooth);
const line = new THREE.LineSegments(edges,new THREE.LineBasicMaterial({color: 0xffffff}));
scene.add(line);

var cube = new THREE.Mesh(smooth,material);
scene.add(cube);

I’m fairly new to three.js and 3d modeling in general so I’m probably missing something, maybe it’s just adding more faces while not changing the shape? Shouldn’t the new edges show up anyway due to the edges geometry section I added?

I’ve seen I could achieve a similar result through smooth shading, what’s the difference? How would I do it?

SubdivisionModifier.modify() actually returns a new geometry and does not change the given one. So change your code to:

const geometry = new THREE.BoxBufferGeometry();

const divisions = 3;
const modifier = new SubdivisionModifier(divisions);

const smooth = modifier.modify(geometry);
1 Like

It works, thanks. Now if I wanted to apply the same modifier to an imported gltf model I would have to use traverse in the loader, get the geometry and do the same thing? Do I have to convert the imported geometry in some way?

Correct. A pre-processing of the geometry should not be necessary. Although the modifier can’t handle all possible attribute data like tangents. But vertex, normal and uv data should work.

1 Like

Thanks, I tried it on an object, and it works, but the new “subdivided” object (newMesh) is now way bigger than the original one (mesh) for some reason. It’s a bit messy because I was trying to see what works and what doesn’t

mesh = gltf.scene;
originalGeometry = mesh.children[0].geometry;

var divisions = 1;
var modifier = new THREE.SubdivisionModifier(divisions);

var smoothGeometry = modifier.modify(originalGeometry);
newMesh = new THREE.Mesh(smoothGeometry,material2);

scene.add(newMesh);
scene.add(mesh);

If you select a geometry in this way, you might miss the transformation of the mesh and its parent objects. Meaning the values of position, rotation and scale. Try at least this:

newMesh.position.copy( mesh.children[ 0 ].position );
newMesh.rotation.copy( mesh.children[ 0 ].rotation );
newMesh.scale.copy( mesh.children[ 0 ].scale );

However, the transformation of mesh is still missing in this case.

1 Like

It works thanks. Problem is, I implemented a slider to scale the model, but when I do use the slider it goes back to its huge size. I can “solve” it by multyplying the scale factors by some constants to counter the big scale but still, I haven’t understood where the big size of the new mesh comes from. I even created a new model from scratch with the correct small size since the beginning but still, when I apply the modifier the new mesh is way bigger than the base one unless I copy the scale