Browse Source

Add example with high number of morph targets (#22514)

* feat:add webgl_morphtargets_face example

* switch to RoomEnvironment

* fix formatting

* improve color

* add newline at EOF

* Switch to gltfpack compressed model

* Generate screenshot
Lewy Blue 3 years ago
parent
commit
777a4be002

+ 2 - 1
examples/files.json

@@ -1,4 +1,4 @@
- {
+{
 	"webgl": [
 		"webgl_animation_cloth",
 		"webgl_animation_keyframes",
@@ -175,6 +175,7 @@
 		"webgl_modifier_simplifier",
 		"webgl_modifier_tessellation",
 		"webgl_morphtargets",
+		"webgl_morphtargets_face",
 		"webgl_morphtargets_horse",
 		"webgl_morphtargets_sphere",
 		"webgl_multiple_canvases_circle",

BIN
examples/models/gltf/facecap.glb


BIN
examples/screenshots/webgl_morphtargets_face.jpg


+ 130 - 0
examples/webgl_morphtargets_face.html

@@ -0,0 +1,130 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<title>three.js webgl - morph targets - face</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+		<link type="text/css" rel="stylesheet" href="main.css">
+		<style>
+			body {
+				color: black;
+			}
+			a {
+				color: #f00;
+			}
+		</style>
+	</head>
+	<body>
+
+		<div id="info">
+			<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> webgl - morph targets - face<br/>
+			model by <a href="https://www.bannaflak.com/face-cap" target="_blank" rel="noopener">Face Cap</a>
+		</div>
+
+		<script type="module">
+
+			import * as THREE from '../build/three.module.js';
+
+			import Stats from './jsm/libs/stats.module.js';
+
+			import { OrbitControls } from './jsm/controls/OrbitControls.js';
+
+			import { GLTFLoader } from './jsm/loaders/GLTFLoader.js';
+			import { KTX2Loader } from './jsm/loaders/KTX2Loader.js';
+			import { MeshoptDecoder } from './jsm/libs/meshopt_decoder.module.js';
+
+			import { RoomEnvironment } from './jsm/environments/RoomEnvironment.js';
+
+			init();
+
+			function init() {
+
+				let mixer;
+
+				const clock = new THREE.Clock();
+
+				const container = document.createElement( 'div' );
+				document.body.appendChild( container );
+
+				const camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 20 );
+				camera.position.set( - 1.8, 0.8, 3 );
+
+				const scene = new THREE.Scene();
+
+				const renderer = new THREE.WebGLRenderer( { antialias: true } );
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+				renderer.toneMapping = THREE.ACESFilmicToneMapping;
+				renderer.outputEncoding = THREE.sRGBEncoding;
+
+				container.appendChild( renderer.domElement );
+
+				const ktx2Loader = new KTX2Loader()
+					.setTranscoderPath( 'js/libs/basis/' )
+					.detectSupport( renderer );
+
+				new GLTFLoader()
+					.setKTX2Loader( ktx2Loader )
+					.setMeshoptDecoder( MeshoptDecoder )
+					.load( 'models/gltf/facecap.glb', ( gltf ) => {
+
+						const mesh = gltf.scene.children[ 0 ];
+
+						scene.add( mesh );
+
+						mixer = new THREE.AnimationMixer( mesh );
+
+						mixer.clipAction( gltf.animations[ 0 ] ).play();
+
+					} );
+
+				const environment = new RoomEnvironment();
+				const pmremGenerator = new THREE.PMREMGenerator( renderer );
+
+				scene.background = new THREE.Color( 0xD5F7F7 );
+				scene.environment = pmremGenerator.fromScene( environment ).texture;
+
+				const controls = new OrbitControls( camera, renderer.domElement );
+				controls.minDistance = 2.5;
+				controls.maxDistance = 5;
+				controls.minAzimuthAngle = - Math.PI / 2;
+				controls.maxAzimuthAngle = Math.PI / 2;
+				controls.maxPolarAngle = Math.PI / 1.8;
+				controls.target.set( 0, 0, - 0.2 );
+				controls.enableDamping = true;
+
+				const stats = new Stats();
+				container.appendChild( stats.dom );
+
+				renderer.setAnimationLoop( () => {
+
+					const delta = clock.getDelta();
+
+					if ( mixer ) {
+
+						mixer.update( delta );
+
+					}
+
+					renderer.render( scene, camera );
+
+					controls.update();
+
+					stats.update();
+
+				} );
+
+				window.addEventListener( 'resize', () => {
+
+					camera.aspect = window.innerWidth / window.innerHeight;
+					camera.updateProjectionMatrix();
+
+					renderer.setSize( window.innerWidth, window.innerHeight );
+
+				} );
+
+			}
+		</script>
+	</body>
+</html>