root/other-projects/nz-flag-design/trunk/render-3d/flag.html @ 29475

Revision 29475, 15.2 KB (checked in by davidb, 6 years ago)

Initial set of files

Line 
1<!DOCTYPE html>
2
3<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
4
5        <title>three.js webgl - 3D Flag</title>
6        <meta charset="utf-8">
7        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
8        <style>
9            body {
10                font-family: Monospace;
11                background-color: #000;
12                color: #000;
13                margin: 0px;
14                overflow: hidden;
15                position: fixed;
16            }
17
18            #info {
19                text-align: center;
20                padding: 10px;
21                z-index: 10;
22                width: 100%;
23                position: absolute;
24                top: 10%;
25            }
26
27            a {
28                text-decoration: underline;
29                cursor: pointer;
30            }
31           
32        </style>
33    <style type="text/css"></style></head>
34
35    <body>
36        <div id="info" style="color : white">
37            Toggle: <a onclick="fine = !fine;">Sunny</a> |
38            <a onclick="wind = !wind;">Wind</a> |
39            <a onclick="raining = !raining;">Rain</a> |
40            <a onclick="snowing = !snowing;">Snow</a>
41           
42        </div>
43
44        <script type="text/javascript" src="./Flag_files/three.js"></script>
45        <script type="text/javascript" src="./Flag_files/Detector.js"></script>
46        <script type="text/javascript" src="./Flag_files/Stats.js"></script>
47        <script type="text/javascript" src="./Flag_files/Flag.js"></script>
48        <script type="text/javascript" src="./Flag_files/OrbitControls.js"></script>
49        <script type="text/javascript" src="./weather/weather.js"></script>
50        <script type="text/javascript" src="./weather/rain.js"></script>
51        <script type="text/javascript" src="./weather/snow.js"></script>
52       
53        <script type="text/javascript" src="./Flag_files/KeyboardState.js"></script>
54
55        <script type="x-shader/x-fragment" id="fragmentShaderDepth">
56
57            uniform sampler2D texture;
58            varying vec2 vUV;
59
60            vec4 pack_depth( const in float depth ) {
61
62                const vec4 bit_shift = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );
63                const vec4 bit_mask  = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );
64                vec4 res = fract( depth * bit_shift );
65                res -= res.xxyz * bit_mask;
66                return res;
67
68            }
69
70            void main() {
71
72                vec4 pixel = texture2D( texture, vUV );
73
74                if ( pixel.a < 0.5 ) discard;
75
76                gl_FragData[ 0 ] = pack_depth( gl_FragCoord.z );
77
78            }
79        </script>
80
81        <script type="x-shader/x-vertex" id="vertexShaderDepth">
82
83            varying vec2 vUV;
84
85            void main() {
86
87                vUV = 0.75 * uv;
88
89                vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
90
91                gl_Position = projectionMatrix * mvPosition;
92
93            }
94
95        </script>
96
97        <script type="text/javascript">
98            var keyboard = new KeyboardState();
99            var clothTextures = [];
100           
101            /* testing cloth simulation */
102           
103            var flagRelease;
104            var initial = true;
105           
106            var pins = [];
107            for (var j=0;j<=cloth.h;j++)
108            pins.push(cloth.index(0, j));
109           
110            /*  Light variables   */
111            var light;
112
113            /*  Weather variables  */
114            var weatherSystem;
115            var raining = false;
116            var snowing = false;
117            var snowSystem;
118            var rainSystem;
119           
120            /*  Mouse variables     */
121            var mouseX;
122            var mouseY;
123            var clickPos = '';
124            var mouseDown = false;
125           
126            if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
127
128            var container, stats;
129            var camera, scene, renderer;
130           
131            var cameraRot = 90;
132            var cameraElevation = 0;
133            var controls;
134
135            var clothGeometry;
136            var sphere;
137            var object, tmpFlag, arrow;
138
139            var rotate = false;
140           
141            // array for holding existing flags
142           
143            var flags = ["./images/flag.png", "./images/random.png", "./images/canada.png"];
144            var flagSelector = 0;
145            var materials;
146            var vertexShader;
147            var fragmentShader;
148            var uniforms;
149
150            init();
151            animate();
152
153            function init() {
154           
155                container = document.createElement( 'div' );
156                document.body.appendChild( container );
157               
158               
159               
160                // scene
161
162                scene = new THREE.Scene();
163
164                scene.fog = new THREE.Fog( 0x404040, 500, 10000 );
165                scene.fog.color.setHSL( 0.1, 0.1, 0.8 );
166
167                // camera
168
169                camera = new THREE.PerspectiveCamera( 20, window.innerWidth / window.innerHeight, 1, 10000 );
170                camera.position.y = 50;
171                camera.position.z = 1500;
172                scene.add( camera );
173                controls = new THREE.OrbitControls( camera );
174                controls.addEventListener( 'change', render );
175               
176                // lights
177               
178                scene.add( new THREE.AmbientLight( 0x404040 ) );
179
180                light = new THREE.DirectionalLight( 0xffffff, 1 );
181                light.color.setHSL( 0.6, 0.125, 1 );
182                light.position.set( 50, 200, 100 );
183                light.position.multiplyScalar( 1.3 );
184
185                light.castShadow = true;
186                light.shadowCameraVisible = true;
187
188                light.shadowMapWidth = 2048;
189                light.shadowMapHeight = 2048;
190
191                var d = 200;
192
193                light.shadowCameraLeft = -d;
194                light.shadowCameraRight = d;
195                light.shadowCameraTop = d;
196                light.shadowCameraBottom = -d;
197
198                light.shadowCameraFar = 1000;
199                light.shadowDarkness = 0.5;
200
201                scene.add( light );
202               
203                /*light = new THREE.DirectionalLight( 0xffffff, 1.25 );
204                light.color.setHSL( 0.3, 0.95, 1 );
205                light.position.set( 0, -1, 0 );*/
206
207                //scene.add( light );
208               
209                /* Weather init */
210               
211                rainSystem = new rain();
212                snowSystem = new snow();
213                weatherSystem = new weatherSystem(scene);
214                //weatherSystem.set(rainSystem);
215           
216           
217                /* ------------------ */
218               
219                // load flag textures
220                var i;
221               
222                for(i = 0; i < flags.length; i++){
223                    clothTextures[i] = THREE.ImageUtils.loadTexture( flags[i] );
224                    clothTextures[i].wrapS = clothTextures[i].wrapT = THREE.RepeatWrapping;
225                    clothTextures[i].anisotropy = 16;
226                }
227                createFlag();
228               
229                // weather
230               
231
232               
233               
234               
235
236                // sphere
237
238                var ballGeo = new THREE.SphereGeometry( ballSize, 20, 20 );
239                var ballMaterial = new THREE.MeshPhongMaterial( { color: 0xffffff } );
240
241                sphere = new THREE.Mesh( ballGeo, ballMaterial );
242                sphere.castShadow = true;
243                sphere.receiveShadow = true;
244                //scene.add( sphere );
245
246                // arrow
247
248                arrow = new THREE.ArrowHelper( new THREE.Vector3( 0, 1, 0 ), new THREE.Vector3( 0, 0, 0 ), 50, 0xff0000 );
249                arrow.position.set( -200, -50, -200 );
250                scene.add( arrow );
251
252   
253
254                // ground
255
256                var initColor = new THREE.Color( 0x00ff00 );
257                initColor.setHSL( 0.3, 0.85, 0.8 );
258                var initTexture = THREE.ImageUtils.generateDataTexture( 1, 1, initColor );
259
260                var groundMaterial = new THREE.MeshPhongMaterial( { color: 0xffffff, specular: 0x111111, map: initTexture, perPixel: true } );
261
262                var groundTexture = THREE.ImageUtils.loadTexture( "./images/grass.jpg", undefined, function() { groundMaterial.map = groundTexture } );
263                groundTexture.wrapS = groundTexture.wrapT = THREE.RepeatWrapping;
264                groundTexture.repeat.set( 32, 32 );
265                groundTexture.anisotropy = 16;
266
267                var mesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 20000, 20000 ), groundMaterial );
268                mesh.position.y = -250;
269                mesh.rotation.x = - Math.PI / 2;
270                mesh.receiveShadow = true;
271                scene.add( mesh );
272
273                // poles
274
275                var poleGeo = new THREE.BoxGeometry( 5, 750, 5 );
276                var poleMat = new THREE.MeshPhongMaterial( { color: 0xffffff, specular: 0x111111, shininess: 100, perPixel: true } );
277
278                var mesh = new THREE.Mesh( poleGeo, poleMat );
279                mesh.position.y = -25; //-250
280                mesh.position.x = 0;
281                mesh.receiveShadow = true;
282                mesh.castShadow = true;
283                scene.add( mesh );
284
285
286                var gg = new THREE.BoxGeometry( 10, 10, 10 );
287                var mesh = new THREE.Mesh( gg, poleMat );
288                mesh.position.y = -250;
289                mesh.position.x = 0; //125
290                mesh.receiveShadow = true;
291                mesh.castShadow = true;
292                scene.add( mesh );
293
294
295                //
296                renderer = new THREE.WebGLRenderer( { antialias: true } );
297                renderer.setSize( window.innerWidth, window.innerHeight );
298                renderer.setClearColor( scene.fog.color );
299
300                container.appendChild( renderer.domElement );
301
302                renderer.gammaInput = true;
303                renderer.gammaOutput = true;
304                renderer.physicallyBasedShading = true;
305
306                renderer.shadowMapEnabled = true;
307
308                //
309
310                stats = new Stats();
311                stats.domElement.style.position = 'absolute';
312                stats.domElement.style.top = '0px';
313                container.appendChild( stats.domElement );
314
315                stats.domElement.children[ 0 ].children[ 0 ].style.color = "#aaa";
316                stats.domElement.children[ 0 ].style.background = "transparent";
317                stats.domElement.children[ 0 ].children[ 1 ].style.display = "none";
318
319                //
320
321                window.addEventListener( 'resize', onWindowResize, false );
322
323                sphere.visible = !true
324
325            }
326           
327            //
328           
329            function createFlag() {
330           
331                // create materials
332                materials = [
333                    new THREE.MeshPhongMaterial( { alphaTest: 0.5, ambient: 0xffffff, color: 0xffffff, specular: 0x030303, emissive: 0x111111, shininess: 20, perPixel: true, metal: false, map: clothTextures[flagSelector], side: THREE.DoubleSide } ),
334                    new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true, transparent: true, opacity: 0.9     } )
335                ];
336   
337               
338               
339                if(initial){
340                   
341                    // cloth geometry
342
343                    clothGeometry = new THREE.ParametricGeometry( clothFunction, cloth.w, cloth.h, true );
344                    clothGeometry.dynamic = true;
345                    clothGeometry.computeFaceNormals();
346
347                    uniforms = { texture:  { type: "t", value: 0, texture: clothTextures[0] } };
348                    vertexShader = document.getElementById( 'vertexShaderDepth' ).textContent;
349                    fragmentShader = document.getElementById( 'fragmentShaderDepth' ).textContent; 
350
351                    // cloth mesh
352                    object = new THREE.Mesh( clothGeometry, materials[ 0 ] );
353                    object.position.set( 0, 150, 0 );
354                    object.castShadow = true;
355                    object.receiveShadow = true;
356                    scene.add( object );
357                    initial = false;
358                    object.customDepthMaterial = new THREE.ShaderMaterial( { uniforms: uniforms, vertexShader: vertexShader, fragmentShader: fragmentShader } );
359               
360                }else{
361                    setPinning(false);
362                    flagRelease = setInterval(function () {switchFlag()}, 2000);
363                }
364               
365            }
366           
367            //
368
369            function switchFlag() {
370
371                scene.remove( object );
372                setPinning(true);
373                object = new THREE.Mesh( clothGeometry, materials[ 0 ] );
374
375                object.position.set( 0, 0, 0 );
376                object.castShadow = true;
377                object.receiveShadow = true;
378                scene.add( object );
379                object.customDepthMaterial = new THREE.ShaderMaterial( { uniforms: uniforms, vertexShader: vertexShader, fragmentShader: fragmentShader } );
380               
381                // stop the timer for calling this method
382                clearInterval(flagRelease);
383            }
384
385            //
386
387            function onWindowResize() {
388
389                camera.aspect = window.innerWidth / window.innerHeight;
390                camera.updateProjectionMatrix();
391
392                renderer.setSize( window.innerWidth, window.innerHeight );
393
394            }
395
396            //
397
398            function animate() {
399
400                requestAnimationFrame( animate );
401
402                var time = Date.now();
403                windStrength = Math.cos( time / 7000 ) * 100 + 200;
404                windForce.set( 1000,500,Math.sin( time / 1000 ) ).normalize().multiplyScalar( windStrength );
405                arrow.setLength( windStrength );
406                arrow.setDirection( windForce );
407                controls.update();
408                simulate(time);
409                render();
410                stats.update();
411
412            }
413           
414            function render() {
415               
416               
417                var timer = Date.now() * 0.0002;
418   
419                keyboard.update();
420                if( keyboard.down("A")) {
421                    flagSelector--;
422                    if(flagSelector < 0) flagSelector = flags.length-1;
423                    createFlag();
424
425                }else if(keyboard.down("D")) {
426                    flagSelector++;
427                    if(flagSelector >= flags.length) flagSelector = 0; 
428                    createFlag();
429                }
430               
431                var p = cloth.particles;
432                for ( var i = 0, il = p.length; i < il; i ++ ) {
433
434                    clothGeometry.vertices[ i ].copy( p[ i ].position );
435
436                }
437               
438                clothGeometry.computeFaceNormals();
439                clothGeometry.computeVertexNormals();
440
441                clothGeometry.normalsNeedUpdate = true;
442                clothGeometry.verticesNeedUpdate = true;
443
444                sphere.position.copy( ballPosition );
445               
446               
447                document.addEventListener( "mousemove", onMouseMove, false);
448                document.addEventListener( "mousedown", onMouseClick, false);
449                document.addEventListener( "mouseup", onMouseUp, false);
450                   
451                /*if(mouseDown === true){
452                    cameraRot += (clickPos - mouseX)/500;
453                    cameraElevation += (clickPos - mouseY)/500;
454                    if(cameraElevation > 180)   cameraElevation = 0;
455                    if(cameraElevation < 0  )   cameraElevation = 180;
456                    if(cameraRot > 360) cameraRot = 0;
457                    if(cameraRot < 0  ) cameraRot = 360;
458                    camera.position.y = Math.sin(THREE.Math.degToRad(cameraElevation))*1500;
459                    camera.position.x = Math.cos(THREE.Math.degToRad(cameraRot))*1500;
460                    camera.position.z = Math.sin(THREE.Math.degToRad(cameraRot))*1500;
461                }*/
462               
463                if(raining && weatherSystem.type != rainSystem){
464                    snowing = false;
465                    weatherSystem.swap(rainSystem);
466                }else if(snowing && weatherSystem.type != snowSystem){
467                    raining = false;
468                    weatherSystem.swap(snowSystem);
469                }
470               
471                if(weatherSystem.isSet() === true){
472                    weatherSystem.update();
473                }
474               
475                camera.lookAt( new THREE.Vector3(scene.position.x+150, scene.position.y+150, scene.position.z) );
476
477                renderer.render( scene, camera );
478
479            }
480           
481            function onMouseMove(){
482               
483                mouseX = event.clientX;
484                mouseY = event.clientY;
485
486            }
487           
488            function onMouseClick(){
489                mouseDown = true;
490                clickPos = event.clientX;
491            }
492           
493            function onMouseUp(){
494                mouseDown = false;
495            }
496
497        </script><div><canvas width="1366" height="600"></canvas><!--<div style="cursor: pointer; width: 80px; opacity: 0.9; z-index: 10001; position: absolute; top: 0px;"><div style="padding: 2px 0px 3px; background: transparent;"><div style="font-family: Helvetica, Arial, sans-serif; text-align: left; font-size: 9px; color: rgb(170, 170, 170); margin: 0px 0px 1px 3px;"><span style="font-weight:bold">55 FPS</span> (0-60)</div><canvas width="74" height="30" style="display: none; margin-left: 3px;"></canvas></div><div style="padding: 2px 0px 3px; display: none; background-color: rgb(8, 24, 8);"><div style="font-family: Helvetica, Arial, sans-serif; text-align: left; font-size: 9px; color: rgb(0, 255, 0); margin: 0px 0px 1px 3px;"><span style="font-weight:bold">16 MS</span> (1-607201)</div><canvas width="74" height="30" style="display: block; margin-left: 3px;"></canvas></div><div style="padding: 2px 0px 3px; display: none; background-color: rgb(24, 8, 13);"><div style="font-family: Helvetica, Arial, sans-serif; text-align: left; font-size: 9px; color: rgb(255, 0, 128); margin: 0px 0px 1px 3px;"><span style="font-weight:bold">10 MEM</span> (10-10)</div><canvas width="74" height="30" style="display: block; margin-left: 3px;"></canvas></div></div></div><div><canvas height="932" width="1920"></canvas><div style="cursor: pointer; width: 80px; opacity: 0.9; z-index: 10001; position: absolute; top: 0px;"><div style="background: none repeat scroll 0% 0% transparent; padding: 2px 0px 3px;"><div style="font-family: Helvetica,Arial,sans-serif; text-align: left; font-size: 9px; color: rgb(170, 170, 170); margin: 0px 0px 1px 3px;"><span style="font-weight:bold">60 FPS</span> (30-69)</div><canvas style="display: none; margin-left: 3px;" height="30" width="74"></canvas></div><div style="background-color: rgb(8, 24, 8); padding: 2px 0px 3px; display: none;"><div style="font-family: Helvetica,Arial,sans-serif; text-align: left; font-size: 9px; color: rgb(0, 255, 0); margin: 0px 0px 1px 3px;"><span style="font-weight:bold">10 MS</span> (5-504)</div><canvas style="display: block; margin-left: 3px;" height="30" width="74"></canvas></div><div style="background-color: rgb(24, 8, 13); padding: 2px 0px 3px; display: none;"><div style="font-family: Helvetica,Arial,sans-serif; text-align: left; font-size: 9px; color: rgb(255, 0, 128); margin: 0px 0px 1px 3px;"><span style="font-weight:bold">MEM</span></div><canvas style="display: block; margin-left: 3px;" height="30" width="74"></canvas></div></div>--></div>
498   
499</body></html>
Note: See TracBrowser for help on using the browser.