|
@@ -24,46 +24,29 @@
|
|
|
|
|
|
var camera, scene, renderer, stats;
|
|
|
|
|
|
- var materialShader;
|
|
|
-
|
|
|
init();
|
|
|
animate();
|
|
|
|
|
|
function init() {
|
|
|
|
|
|
- camera = new THREE.PerspectiveCamera( 27, window.innerWidth / window.innerHeight, 1, 10000 );
|
|
|
- camera.position.z = 1500;
|
|
|
+ camera = new THREE.PerspectiveCamera( 27, window.innerWidth / window.innerHeight, 0.1, 100 );
|
|
|
+ camera.position.z = 20;
|
|
|
|
|
|
scene = new THREE.Scene();
|
|
|
|
|
|
- var material = new THREE.MeshNormalMaterial();
|
|
|
- material.onBeforeCompile = function ( shader ) {
|
|
|
-
|
|
|
- shader.uniforms.time = { value: 0 };
|
|
|
-
|
|
|
- shader.vertexShader = 'uniform float time;\n' + shader.vertexShader;
|
|
|
- shader.vertexShader = shader.vertexShader.replace(
|
|
|
- '#include <begin_vertex>',
|
|
|
- [
|
|
|
- 'float theta = sin( time + position.y ) / 2.0;',
|
|
|
- 'float c = cos( theta );',
|
|
|
- 'float s = sin( theta );',
|
|
|
- 'mat3 m = mat3( c, 0, s, 0, 1, 0, -s, 0, c );',
|
|
|
- 'vec3 transformed = vec3( position ) * m;',
|
|
|
- 'vNormal = vNormal * m;'
|
|
|
- ].join( '\n' )
|
|
|
- );
|
|
|
-
|
|
|
- materialShader = shader;
|
|
|
-
|
|
|
- };
|
|
|
-
|
|
|
var loader = new GLTFLoader();
|
|
|
loader.load( 'models/gltf/LeePerrySmith/LeePerrySmith.glb', function ( gltf ) {
|
|
|
|
|
|
- var mesh = new THREE.Mesh( gltf.scene.children[ 0 ].geometry, material );
|
|
|
- mesh.position.y = - 50;
|
|
|
- mesh.scale.setScalar( 100 );
|
|
|
+ var geometry = gltf.scene.children[ 0 ].geometry;
|
|
|
+
|
|
|
+ var mesh = new THREE.Mesh( geometry, buildTwistMaterial( 2.0 ) );
|
|
|
+ mesh.position.x = - 3.5;
|
|
|
+ mesh.position.y = - 0.5;
|
|
|
+ scene.add( mesh );
|
|
|
+
|
|
|
+ var mesh = new THREE.Mesh( geometry, buildTwistMaterial( - 2.0 ) );
|
|
|
+ mesh.position.x = 3.5;
|
|
|
+ mesh.position.y = - 0.5;
|
|
|
scene.add( mesh );
|
|
|
|
|
|
} );
|
|
@@ -88,6 +71,42 @@
|
|
|
|
|
|
}
|
|
|
|
|
|
+ function buildTwistMaterial( amount ) {
|
|
|
+
|
|
|
+ var material = new THREE.MeshNormalMaterial();
|
|
|
+ material.onBeforeCompile = function ( shader ) {
|
|
|
+
|
|
|
+ shader.uniforms.time = { value: 0 };
|
|
|
+
|
|
|
+ shader.vertexShader = 'uniform float time;\n' + shader.vertexShader;
|
|
|
+ shader.vertexShader = shader.vertexShader.replace(
|
|
|
+ '#include <begin_vertex>',
|
|
|
+ [
|
|
|
+ `float theta = sin( time + position.y ) / ${ amount.toFixed( 1 ) };`,
|
|
|
+ 'float c = cos( theta );',
|
|
|
+ 'float s = sin( theta );',
|
|
|
+ 'mat3 m = mat3( c, 0, s, 0, 1, 0, -s, 0, c );',
|
|
|
+ 'vec3 transformed = vec3( position ) * m;',
|
|
|
+ 'vNormal = vNormal * m;'
|
|
|
+ ].join( '\n' )
|
|
|
+ );
|
|
|
+
|
|
|
+ material.userData.shader = shader;
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
+ // Make sure WebGLRenderer doesnt reuse a single program
|
|
|
+
|
|
|
+ material.customProgramCacheKey = function () {
|
|
|
+
|
|
|
+ return amount;
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
+ return material;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
//
|
|
|
|
|
|
function onWindowResize() {
|
|
@@ -116,11 +135,21 @@
|
|
|
|
|
|
function render() {
|
|
|
|
|
|
- if ( materialShader ) {
|
|
|
+ scene.traverse( function ( child ) {
|
|
|
+
|
|
|
+ if ( child.isMesh ) {
|
|
|
+
|
|
|
+ const shader = child.material.userData.shader;
|
|
|
+
|
|
|
+ if ( shader ) {
|
|
|
|
|
|
- materialShader.uniforms.time.value = performance.now() / 1000;
|
|
|
+ shader.uniforms.time.value = performance.now() / 1000;
|
|
|
|
|
|
- }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ } );
|
|
|
|
|
|
renderer.render( scene, camera );
|
|
|
|