Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apply three.js subdivision modifier without changing outer geometry?

I am trying to take any three.js geometry and subdivide its existing faces into smaller faces. This would essentially give the geometry a higher "resolution". There is a subdivision modifier tool in the examples of three.js that works great for what I'm trying to do, but it ends up changing and morphing the original shape of the geometry. I'd like to retain the original shape.

View the Subdivision Modifier Example


Example of how the current subdivision modifier behaves:

enter image description here

Rough example of how I'd like it to behave:

enter image description here


The subdivision modifier is applied like this:

let originalGeometry = new THREE.BoxGeometry(1, 1, 1);
let subdivisionModifier = new THREE.SubdivisionModifier(3);
let subdividedGeometry = originalGeometry.clone();
subdivisionModifier.modify(subdividedGeometry);

I attempted to dig around the source of the subdivision modifier, but I wasn't sure how to modify it to get the desired result.

Note: The subdivision should be able to be applied to any geometry. My example of the desired result might make it seem that a three.js PlaneGeometry with increased segments would work, but I need this to be applied to a variety of geometries.

like image 602
jackrugile Avatar asked Jun 05 '17 16:06

jackrugile


2 Answers

Based on the suggestions in the comments by TheJim01, I was able to dig through the original source and modify the vertex weight, edge weight, and beta values to retain the original shape. My modifications should remove any averaging, and put all the weight toward the source shape.

There were three sections that had to be modified, so I went ahead and made it an option that can be passed into the constructor called retainShape, which defaults to false.

I made a gist with the modified code for SubdivisionGeometry.js.

View the modified SubdivisionGeometry.js Gist


Below is an example of a cube being subdivided with the option turned off, and turned on.

Left: new THREE.SubdivisionModifier(2, false);

Right: new THREE.SubdivisionModifier(2, true);

enter image description here

If anyone runs into any issues with this or has any questions, let me know!

like image 93
jackrugile Avatar answered Nov 07 '22 05:11

jackrugile


The current version of three.js has optional parameters for PlaneGeometry that specify the number of segments for the width and height; both default to 1. In the example below I set both widthSegments and heightSegments to 128. This has a similar effect as using SubdivisionModifier. In fact, SubdivisionModifier distorts the shape, but specifying the segments does not distort the shape and works better for me.

var widthSegments = 128;
var heightSegments = 128;
var geometry = new THREE.PlaneGeometry(10, 10, widthSegments, heightSegments);
//    var geometry = new THREE.PlaneGeoemtry(10,10); // segments default to 1
//    var modifier = new THREE.SubdivisionModifier( 7 );
//    geometry = modifier.modify(geometry);

https://threejs.org/docs/#api/en/geometries/PlaneGeometry

like image 1
Don Smith Avatar answered Nov 07 '22 05:11

Don Smith