Browse Source

Examples: Updated external subdivision demo (#24930)

* Updated demo to v1.1.2

* Separated wireframe

* Updated screenshot

* Dispose typo

* Simplified lighting
Stephens Nunnally 2 years ago
parent
commit
a392c8d6aa

BIN
examples/screenshots/webgl_modifier_subdivision.jpg


+ 97 - 29
examples/webgl_modifier_subdivision.html

@@ -22,7 +22,7 @@
 				"imports": {
 					"three": "../build/three.module.js",
 					"three/addons/": "./jsm/",
-					"three-subdivide": "https://unpkg.com/three-subdivide@1.0.2/build/index.module.js"
+					"three-subdivide": "https://unpkg.com/three-subdivide@1.1.2/build/index.module.js"
 				}
 			}
 		</script>
@@ -36,16 +36,20 @@
 
 			let renderer, scene, camera;
 			let texture;
-			let meshMaterial, meshNormal, meshSmooth;
-			let wireMaterial, wireNormal, wireSmooth;
+			let meshNormal, meshSmooth;
+			let wireNormal, wireSmooth;
+			let wireMaterial;
 
 			const params = {
 				geometry: 'Box',
 				iterations: 3,
 				split: true,
 				uvSmooth: false,
+				preserveEdges: false,
 				flatOnly: false,
 				maxTriangles: 25000,
+				flatShading: false,
+				textured: true,
 				wireframe: false
 			};
 
@@ -70,6 +74,14 @@
 				controls.target.set( 0, 0, 0 );
 				controls.update();
 
+				scene.add( new THREE.HemisphereLight( 0xffffff, 0x737373, 1 ) );
+
+				const frontLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
+				const backLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
+				frontLight.position.set( 0, 1, 1 );
+				backLight.position.set( 0, 1, - 1 );
+				scene.add( frontLight, backLight );
+
 				texture = new THREE.TextureLoader().load( './textures/uv_grid_opengl.jpg', () => {
 
 					texture.wrapS = THREE.RepeatWrapping;
@@ -79,15 +91,8 @@
 
 				} );
 
-				meshMaterial = new THREE.MeshBasicMaterial( {
-					map: texture,
-					polygonOffset: true,
-					polygonOffsetFactor: 1, // positive value pushes polygon further away
-					polygonOffsetUnits: 1,
-					side: THREE.DoubleSide
-				} );
-				meshNormal = new THREE.Mesh( new THREE.BufferGeometry(), meshMaterial );
-				meshSmooth = new THREE.Mesh( new THREE.BufferGeometry(), meshMaterial );
+				meshNormal = new THREE.Mesh( new THREE.BufferGeometry(), new THREE.MeshBasicMaterial() );
+				meshSmooth = new THREE.Mesh( new THREE.BufferGeometry(), new THREE.MeshBasicMaterial() );
 				meshNormal.position.set( - 0.7, 0, 0 );
 				meshSmooth.position.set( 0.7, 0, 0 );
 				scene.add( meshNormal, meshSmooth );
@@ -114,7 +119,7 @@
 
 					const geom = params.geometry.toLowerCase();
 
-					params.split = geom === 'box' || geom === 'ring';
+					params.split = geom === 'box' || geom === 'ring' || geom === 'plane';
 					params.uvSmooth = geom === 'circle' || geom === 'plane' || geom === 'ring';
 
 					refreshDisplay();
@@ -123,18 +128,22 @@
 
 				folder1.add( params, 'iterations' ).min( 0 ).max( 5 ).step( 1 ).onFinishChange( updateMeshes );
 				const splitController = folder1.add( params, 'split' ).onFinishChange( updateMeshes );
-				const smoothController = folder1.add( params, 'uvSmooth' ).onFinishChange( updateMeshes );
-				folder1.add( params, 'flatOnly' ).onFinishChange ( updateMeshes );
+				const uvSmoothController = folder1.add( params, 'uvSmooth' ).onFinishChange( updateMeshes );
+				const preserveController = folder1.add( params, 'preserveEdges' ).onFinishChange( updateMeshes );
+				folder1.add( params, 'flatOnly' ).onFinishChange( updateMeshes );
 				folder1.add( params, 'maxTriangles' ).onFinishChange( updateMeshes );
 
-				const folder2 = gui.addFolder( 'View' );
-				folder2.add( params, 'wireframe' ).onFinishChange( updateMeshes );
+				const folder2 = gui.addFolder( 'Material' );
+				folder2.add( params, 'flatShading' ).onFinishChange( updateMaterial );
+				folder2.add( params, 'textured' ).onFinishChange( updateMaterial );
+				folder2.add( params, 'wireframe' ).onFinishChange( updateWireframe );
 
 				function refreshDisplay() {
 
 					geomController.updateDisplay();
 					splitController.updateDisplay();
-					smoothController.updateDisplay();
+					uvSmoothController.updateDisplay();
+					preserveController.updateDisplay();
 
 					updateMeshes();
 
@@ -159,7 +168,7 @@
 						return new THREE.ConeGeometry( 0.6, 1.5, 5, 3 );
 
 					case 'cylinder':
-						return new THREE.CylinderGeometry( 0.5, 0.5, 1, 5, 5 );
+						return new THREE.CylinderGeometry( 0.5, 0.5, 1, 5, 4 );
 
 					case 'dodecahedron':
 						return new THREE.DodecahedronGeometry( 0.6 );
@@ -175,8 +184,8 @@
 
 						for ( let i = 0; i < 65; i += 5 ) {
 
-							let x = ( Math.sin( i * 0.2 ) * Math.sin( i * 0.1 ) * 15 + 50 ) * 1.2;
-							let y = ( i - 5 ) * 3;
+							const x = ( Math.sin( i * 0.2 ) * Math.sin( i * 0.1 ) * 15 + 50 ) * 1.2;
+							const y = ( i - 5 ) * 3;
 							points.push( new THREE.Vector2( x * 0.0075, y * 0.005 ) );
 
 						}
@@ -214,14 +223,8 @@
 			function updateMeshes() {
 
 				const normalGeometry = getGeometry();
-				const smoothGeometry = LoopSubdivision.modify(
-					normalGeometry,
-					params.iterations,
-					params.split,
-					params.uvSmooth,
-					params.flatOnly,
-					params.maxTriangles
-				);
+
+				const smoothGeometry = LoopSubdivision.modify( normalGeometry, params.iterations, params );
 
 				meshNormal.geometry.dispose();
 				meshSmooth.geometry.dispose();
@@ -233,6 +236,71 @@
 				wireNormal.geometry = normalGeometry.clone();
 				wireSmooth.geometry = smoothGeometry.clone();
 
+				updateMaterial();
+
+			}
+
+			function disposeMaterial( material ) {
+
+				const materials = Array.isArray( material ) ? material : [ material ];
+
+				for ( let i = 0; i < materials.length; i ++ ) {
+
+					if ( materials[ i ].dispose ) materials[ i ].dispose();
+
+				}
+
+			}
+
+			function updateMaterial() {
+
+				disposeMaterial( meshNormal.material );
+				disposeMaterial( meshSmooth.material );
+
+				const materialParams = {
+					color: ( params.textured ) ? 0xffffff : 0x808080,
+					flatShading: params.flatShading,
+					map: ( params.textured ) ? texture : null,
+					polygonOffset: true,
+					polygonOffsetFactor: 1, // positive value pushes polygon further away
+					polygonOffsetUnits: 1
+				};
+
+				switch ( params.geometry.toLowerCase() ) {
+
+					case 'circle':
+					case 'lathe':
+					case 'plane':
+					case 'ring':
+
+						materialParams.side = THREE.DoubleSide;
+						break;
+
+					case 'box':
+					case 'capsule':
+					case 'cone':
+					case 'cylinder':
+					case 'dodecahedron':
+					case 'icosahedron':
+					case 'octahedron':
+					case 'sphere':
+					case 'tetrahedron':
+					case 'torus':
+					case 'torusknot':
+
+						materialParams.side = THREE.FrontSide;
+						break;
+
+				}
+
+				meshNormal.material = meshSmooth.material = new THREE.MeshStandardMaterial( materialParams );
+
+				render();
+
+			}
+
+			function updateWireframe() {
+
 				wireNormal.visible = wireSmooth.visible = params.wireframe;
 
 				render();