-
-
Notifications
You must be signed in to change notification settings - Fork 35.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
184 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<title>three.js webgpu - morph targets</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"> | ||
</head> | ||
|
||
<body> | ||
<div id="container"></div> | ||
<div id="info"> | ||
<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - morph targets<br/> | ||
by <a href="https://discoverthreejs.com/" target="_blank" rel="noopener">Discover three.js</a> | ||
</div> | ||
|
||
<!-- Import maps polyfill --> | ||
<!-- Remove this when import maps will be widely supported --> | ||
<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script> | ||
|
||
<script type="importmap"> | ||
{ | ||
"imports": { | ||
"three": "../build/three.module.js", | ||
"three/addons/": "./jsm/", | ||
"three/nodes": "./jsm/nodes/Nodes.js" | ||
} | ||
} | ||
</script> | ||
|
||
<script type="module"> | ||
|
||
import * as THREE from 'three'; | ||
|
||
import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; | ||
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; | ||
|
||
import WebGPU from 'three/addons/capabilities/WebGPU.js'; | ||
import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js'; | ||
|
||
let container, camera, scene, renderer, mesh; | ||
|
||
init(); | ||
|
||
function init() { | ||
|
||
if ( WebGPU.isAvailable() === false ) { | ||
|
||
document.body.appendChild( WebGPU.getErrorMessage() ); | ||
|
||
throw new Error( 'No WebGPU support' ); | ||
|
||
} | ||
|
||
container = document.getElementById( 'container' ); | ||
|
||
scene = new THREE.Scene(); | ||
scene.background = new THREE.Color( 0x8FBCD4 ); | ||
|
||
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 20 ); | ||
camera.position.z = 10; | ||
scene.add( camera ); | ||
|
||
scene.add( new THREE.AmbientLight( 0x8FBCD4, 1.5 ) ); | ||
|
||
const pointLight = new THREE.PointLight( 0xffffff, 200 ); | ||
camera.add( pointLight ); | ||
|
||
const geometry = createGeometry(); | ||
|
||
const material = new THREE.MeshPhongMaterial( { | ||
color: 0xff0000, | ||
flatShading: true | ||
} ); | ||
|
||
mesh = new THREE.Mesh( geometry, material ); | ||
scene.add( mesh ); | ||
|
||
initGUI(); | ||
|
||
renderer = new WebGPURenderer( { antialias: true } ); | ||
renderer.setPixelRatio( window.devicePixelRatio ); | ||
renderer.setSize( window.innerWidth, window.innerHeight ); | ||
renderer.setAnimationLoop( function () { | ||
|
||
renderer.render( scene, camera ); | ||
|
||
} ); | ||
container.appendChild( renderer.domElement ); | ||
|
||
const controls = new OrbitControls( camera, renderer.domElement ); | ||
controls.enableZoom = false; | ||
|
||
window.addEventListener( 'resize', onWindowResize ); | ||
|
||
} | ||
|
||
function createGeometry() { | ||
|
||
const geometry = new THREE.BoxGeometry( 2, 2, 2, 32, 32, 32 ); | ||
|
||
// create an empty array to hold targets for the attribute we want to morph | ||
// morphing positions and normals is supported | ||
geometry.morphAttributes.position = []; | ||
|
||
// the original positions of the cube's vertices | ||
const positionAttribute = geometry.attributes.position; | ||
|
||
// for the first morph target we'll move the cube's vertices onto the surface of a sphere | ||
const spherePositions = []; | ||
|
||
// for the second morph target, we'll twist the cubes vertices | ||
const twistPositions = []; | ||
const direction = new THREE.Vector3( 1, 0, 0 ); | ||
const vertex = new THREE.Vector3(); | ||
|
||
for ( let i = 0; i < positionAttribute.count; i ++ ) { | ||
|
||
const x = positionAttribute.getX( i ); | ||
const y = positionAttribute.getY( i ); | ||
const z = positionAttribute.getZ( i ); | ||
|
||
spherePositions.push( | ||
|
||
x * Math.sqrt( 1 - ( y * y / 2 ) - ( z * z / 2 ) + ( y * y * z * z / 3 ) ), | ||
y * Math.sqrt( 1 - ( z * z / 2 ) - ( x * x / 2 ) + ( z * z * x * x / 3 ) ), | ||
z * Math.sqrt( 1 - ( x * x / 2 ) - ( y * y / 2 ) + ( x * x * y * y / 3 ) ) | ||
|
||
); | ||
|
||
// stretch along the x-axis so we can see the twist better | ||
vertex.set( x * 2, y, z ); | ||
|
||
vertex.applyAxisAngle( direction, Math.PI * x / 2 ).toArray( twistPositions, twistPositions.length ); | ||
|
||
} | ||
|
||
// add the spherical positions as the first morph target | ||
geometry.morphAttributes.position[ 0 ] = new THREE.Float32BufferAttribute( spherePositions, 3 ); | ||
|
||
// add the twisted positions as the second morph target | ||
geometry.morphAttributes.position[ 1 ] = new THREE.Float32BufferAttribute( twistPositions, 3 ); | ||
|
||
return geometry; | ||
|
||
} | ||
|
||
function initGUI() { | ||
|
||
// Set up dat.GUI to control targets | ||
const params = { | ||
Spherify: 0, | ||
Twist: 0, | ||
}; | ||
const gui = new GUI( { title: 'Morph Targets' } ); | ||
|
||
gui.add( params, 'Spherify', 0, 1 ).step( 0.01 ).onChange( function ( value ) { | ||
|
||
mesh.morphTargetInfluences[ 0 ] = value; | ||
|
||
} ); | ||
gui.add( params, 'Twist', 0, 1 ).step( 0.01 ).onChange( function ( value ) { | ||
|
||
mesh.morphTargetInfluences[ 1 ] = value; | ||
|
||
} ); | ||
|
||
} | ||
|
||
function onWindowResize() { | ||
|
||
camera.aspect = window.innerWidth / window.innerHeight; | ||
camera.updateProjectionMatrix(); | ||
|
||
renderer.setSize( window.innerWidth, window.innerHeight ); | ||
|
||
} | ||
|
||
</script> | ||
|
||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters