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

Last change on this file since 29475 was 29475, checked in by davidb, 9 years ago

Initial set of files

File size: 15.2 KB
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 repository browser.