webgl_gpgpu_birds.html 17.6 KB
Newer Older
M
r64  
Mr.doob 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
<!DOCTYPE html>
<html lang="en">
	<head>
		<title>three.js webgl - gpgpu - flocking</title>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
		<style>
			body {
				background-color: #ffffff;
				margin: 0px;
				overflow: hidden;
				font-family:Monospace;
				font-size:13px;
				text-align:center;
				text-align:center;
				cursor: pointer;
			}

			a {
				color:#0078ff;
			}

			#info {
				color: #000;
				position: absolute;
				top: 10px;
				width: 100%;
			}

		</style>
	</head>
	<body>

		<div id="info">
M
r86  
Mr.doob 已提交
35
			<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - <span id="birds"></span> webgl gpgpu birds<br/>
M
r64  
Mr.doob 已提交
36 37
			Select <span id="options"></span> birds<br/>
			Move mouse to disturb birds.
M
r68  
Mr.doob 已提交
38

M
r64  
Mr.doob 已提交
39 40
		</div>

M
r76  
Mr.doob 已提交
41
		<script src="../build/three.js"></script>
M
r97  
Mr.doob 已提交
42
		<script src="js/WebGL.js"></script>
M
r64  
Mr.doob 已提交
43 44 45
		<script src="js/libs/stats.min.js"></script>
		<script src="js/libs/dat.gui.min.js"></script>

M
r78  
Mr.doob 已提交
46
		<script src="js/GPUComputationRenderer.js"></script>
M
r64  
Mr.doob 已提交
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85

		<!--
		TODO: If you're reading this, you may wish to improve this example by
			- Create a better shading for the birds?

		-->


		<!-- shader for bird's position -->
		<script id="fragmentShaderPosition" type="x-shader/x-fragment">

			uniform float time;
			uniform float delta;

			void main()	{

				vec2 uv = gl_FragCoord.xy / resolution.xy;
				vec4 tmpPos = texture2D( texturePosition, uv );
				vec3 position = tmpPos.xyz;
				vec3 velocity = texture2D( textureVelocity, uv ).xyz;

				float phase = tmpPos.w;

				phase = mod( ( phase + delta +
					length( velocity.xz ) * delta * 3. +
					max( velocity.y, 0.0 ) * delta * 6. ), 62.83 );

				gl_FragColor = vec4( position + velocity * delta * 15. , phase );

			}

		</script>

		<!-- shader for bird's velocity -->
		<script id="fragmentShaderVelocity" type="x-shader/x-fragment">

			uniform float time;
			uniform float testing;
			uniform float delta; // about 0.016
M
r102  
Mr.doob 已提交
86
			uniform float separationDistance; // 20
M
r64  
Mr.doob 已提交
87
			uniform float alignmentDistance; // 40
M
r68  
Mr.doob 已提交
88
			uniform float cohesionDistance; //
M
r64  
Mr.doob 已提交
89 90 91
			uniform float freedomFactor;
			uniform vec3 predator;

M
r78  
Mr.doob 已提交
92 93
			const float width = resolution.x;
			const float height = resolution.y;
M
r64  
Mr.doob 已提交
94 95 96 97 98 99

			const float PI = 3.141592653589793;
			const float PI_2 = PI * 2.0;
			// const float VISION = PI * 0.55;

			float zoneRadius = 40.0;
M
r72  
Mr.doob 已提交
100
			float zoneRadiusSquared = 1600.0;
M
r64  
Mr.doob 已提交
101 102 103 104

			float separationThresh = 0.45;
			float alignmentThresh = 0.65;

M
r78  
Mr.doob 已提交
105
			const float UPPER_BOUNDS = BOUNDS;
M
r64  
Mr.doob 已提交
106 107 108 109
			const float LOWER_BOUNDS = -UPPER_BOUNDS;

			const float SPEED_LIMIT = 9.0;

M
r102.1  
Mr.doob 已提交
110 111
			float rand( vec2 co ){
				return fract( sin( dot( co.xy, vec2(12.9898,78.233) ) ) * 43758.5453 );
M
r64  
Mr.doob 已提交
112 113
			}

M
r78  
Mr.doob 已提交
114
			void main() {
M
r64  
Mr.doob 已提交
115

M
r102  
Mr.doob 已提交
116 117 118
				zoneRadius = separationDistance + alignmentDistance + cohesionDistance;
				separationThresh = separationDistance / zoneRadius;
				alignmentThresh = ( separationDistance + alignmentDistance ) / zoneRadius;
M
r64  
Mr.doob 已提交
119 120 121 122 123 124 125 126 127 128 129 130 131
				zoneRadiusSquared = zoneRadius * zoneRadius;


				vec2 uv = gl_FragCoord.xy / resolution.xy;
				vec3 birdPosition, birdVelocity;

				vec3 selfPosition = texture2D( texturePosition, uv ).xyz;
				vec3 selfVelocity = texture2D( textureVelocity, uv ).xyz;

				float dist;
				vec3 dir; // direction
				float distSquared;

M
r102  
Mr.doob 已提交
132
				float separationSquared = separationDistance * separationDistance;
M
r64  
Mr.doob 已提交
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
				float cohesionSquared = cohesionDistance * cohesionDistance;

				float f;
				float percent;

				vec3 velocity = selfVelocity;

				float limit = SPEED_LIMIT;

				dir = predator * UPPER_BOUNDS - selfPosition;
				dir.z = 0.;
				// dir.z *= 0.6;
				dist = length( dir );
				distSquared = dist * dist;

				float preyRadius = 150.0;
				float preyRadiusSq = preyRadius * preyRadius;

M
r68  
Mr.doob 已提交
151

M
r64  
Mr.doob 已提交
152
				// move birds away from predator
M
r102.1  
Mr.doob 已提交
153
				if ( dist < preyRadius ) {
M
r64  
Mr.doob 已提交
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168

					f = ( distSquared / preyRadiusSq - 1.0 ) * delta * 100.;
					velocity += normalize( dir ) * f;
					limit += 5.0;
				}


				// if (testing == 0.0) {}
				// if ( rand( uv + time ) < freedomFactor ) {}


				// Attract flocks to the center
				vec3 central = vec3( 0., 0., 0. );
				dir = selfPosition - central;
				dist = length( dir );
M
r70  
Mr.doob 已提交
169

M
r64  
Mr.doob 已提交
170 171 172
				dir.y *= 2.5;
				velocity -= normalize( dir ) * delta * 5.;

M
r102.1  
Mr.doob 已提交
173 174
				for ( float y = 0.0; y < height; y++ ) {
					for ( float x = 0.0; x < width; x++ ) {
M
r64  
Mr.doob 已提交
175

M
r70  
Mr.doob 已提交
176 177
						vec2 ref = vec2( x + 0.5, y + 0.5 ) / resolution.xy;
						birdPosition = texture2D( texturePosition, ref ).xyz;
M
r64  
Mr.doob 已提交
178 179

						dir = birdPosition - selfPosition;
M
r102.1  
Mr.doob 已提交
180
						dist = length( dir );
M
r64  
Mr.doob 已提交
181

M
r102.1  
Mr.doob 已提交
182
						if ( dist < 0.0001 ) continue;
M
r70  
Mr.doob 已提交
183 184

						distSquared = dist * dist;
M
r64  
Mr.doob 已提交
185

M
r102.1  
Mr.doob 已提交
186
						if ( distSquared > zoneRadiusSquared ) continue;
M
r64  
Mr.doob 已提交
187

M
r70  
Mr.doob 已提交
188
						percent = distSquared / zoneRadiusSquared;
M
r64  
Mr.doob 已提交
189

M
r70  
Mr.doob 已提交
190
						if ( percent < separationThresh ) { // low
M
r64  
Mr.doob 已提交
191

M
r70  
Mr.doob 已提交
192
							// Separation - Move apart for comfort
M
r102.1  
Mr.doob 已提交
193 194
							f = ( separationThresh / percent - 1.0 ) * delta;
							velocity -= normalize( dir ) * f;
M
r64  
Mr.doob 已提交
195

M
r70  
Mr.doob 已提交
196
						} else if ( percent < alignmentThresh ) { // high
M
r64  
Mr.doob 已提交
197

M
r70  
Mr.doob 已提交
198 199 200
							// Alignment - fly the same direction
							float threshDelta = alignmentThresh - separationThresh;
							float adjustedPercent = ( percent - separationThresh ) / threshDelta;
M
r68  
Mr.doob 已提交
201

M
r70  
Mr.doob 已提交
202
							birdVelocity = texture2D( textureVelocity, ref ).xyz;
M
r64  
Mr.doob 已提交
203

M
r70  
Mr.doob 已提交
204
							f = ( 0.5 - cos( adjustedPercent * PI_2 ) * 0.5 + 0.5 ) * delta;
M
r102.1  
Mr.doob 已提交
205
							velocity += normalize( birdVelocity ) * f;
M
r64  
Mr.doob 已提交
206

M
r70  
Mr.doob 已提交
207
						} else {
M
r64  
Mr.doob 已提交
208

M
r70  
Mr.doob 已提交
209 210 211
							// Attraction / Cohesion - move closer
							float threshDelta = 1.0 - alignmentThresh;
							float adjustedPercent = ( percent - alignmentThresh ) / threshDelta;
M
r64  
Mr.doob 已提交
212

M
r70  
Mr.doob 已提交
213
							f = ( 0.5 - ( cos( adjustedPercent * PI_2 ) * -0.5 + 0.5 ) ) * delta;
M
r64  
Mr.doob 已提交
214

M
r102.1  
Mr.doob 已提交
215
							velocity += normalize( dir ) * f;
M
r64  
Mr.doob 已提交
216 217 218 219 220 221 222

						}

					}

				}

M
r68  
Mr.doob 已提交
223

M
r64  
Mr.doob 已提交
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244

				// this make tends to fly around than down or up
				// if (velocity.y > 0.) velocity.y *= (1. - 0.2 * delta);

				// Speed Limits
				if ( length( velocity ) > limit ) {
					velocity = normalize( velocity ) * limit;
				}

				gl_FragColor = vec4( velocity, 1.0 );

			}

		</script>

		<script type="x-shader/x-vertex" id="birdVS">

			attribute vec2 reference;
			attribute float birdVertex;

			attribute vec3 birdColor;
M
r68  
Mr.doob 已提交
245

M
r64  
Mr.doob 已提交
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
			uniform sampler2D texturePosition;
			uniform sampler2D textureVelocity;

			varying vec4 vColor;
			varying float z;

			uniform float time;

			void main() {

				vec4 tmpPos = texture2D( texturePosition, reference );
				vec3 pos = tmpPos.xyz;
				vec3 velocity = normalize(texture2D( textureVelocity, reference ).xyz);

				vec3 newPosition = position;

				if ( birdVertex == 4.0 || birdVertex == 7.0 ) {
					// flap wings
					newPosition.y = sin( tmpPos.w ) * 5.;
				}

				newPosition = mat3( modelMatrix ) * newPosition;


				velocity.z *= -1.;
				float xz = length( velocity.xz );
				float xyz = 1.;
				float x = sqrt( 1. - velocity.y * velocity.y );
M
r68  
Mr.doob 已提交
274

M
r64  
Mr.doob 已提交
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297
				float cosry = velocity.x / xz;
				float sinry = velocity.z / xz;

				float cosrz = x / xyz;
				float sinrz = velocity.y / xyz;

				mat3 maty =  mat3(
					cosry, 0, -sinry,
					0    , 1, 0     ,
					sinry, 0, cosry

				);

				mat3 matz =  mat3(
					cosrz , sinrz, 0,
					-sinrz, cosrz, 0,
					0     , 0    , 1
				);

				newPosition =  maty * matz * newPosition;
				newPosition += pos;

				z = newPosition.z;
M
r68  
Mr.doob 已提交
298

M
r64  
Mr.doob 已提交
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324
				vColor = vec4( birdColor, 1.0 );
				gl_Position = projectionMatrix *  viewMatrix  * vec4( newPosition, 1.0 );
			}

		</script>

		<!-- bird geometry shader -->
		<script type="x-shader/x-fragment" id="birdFS">

			varying vec4 vColor;
			varying float z;

			uniform vec3 color;

			void main() {
				// Fake colors for now
				float z2 = 0.2 + ( 1000. - z ) / 1000. * vColor.x;
				gl_FragColor = vec4( z2, z2, z2, 1. );

			}

		</script>


		<script>

M
r97  
Mr.doob 已提交
325 326 327 328 329
			if ( WEBGL.isWebGLAvailable() === false ) {

				document.body.appendChild( WEBGL.getWebGLErrorMessage() );

			}
M
r64  
Mr.doob 已提交
330 331

			var hash = document.location.hash.substr( 1 );
M
r98  
Mr.doob 已提交
332
			if ( hash ) hash = parseInt( hash, 0 );
M
r64  
Mr.doob 已提交
333 334

			/* TEXTURE WIDTH FOR SIMULATION */
M
r68  
Mr.doob 已提交
335
			var WIDTH = hash || 32;
M
r64  
Mr.doob 已提交
336

M
r67  
Mr.doob 已提交
337
			var BIRDS = WIDTH * WIDTH;
M
r64  
Mr.doob 已提交
338

M
r67  
Mr.doob 已提交
339
			// Custom Geometry - using 3 triangles each. No UVs, no normals currently.
M
r64  
Mr.doob 已提交
340 341
			THREE.BirdGeometry = function () {

M
r67  
Mr.doob 已提交
342 343 344 345 346
				var triangles = BIRDS * 3;
				var points = triangles * 3;

				THREE.BufferGeometry.call( this );

M
r68  
Mr.doob 已提交
347 348 349 350
				var vertices = new THREE.BufferAttribute( new Float32Array( points * 3 ), 3 );
				var birdColors = new THREE.BufferAttribute( new Float32Array( points * 3 ), 3 );
				var references = new THREE.BufferAttribute( new Float32Array( points * 2 ), 2 );
				var birdVertex = new THREE.BufferAttribute( new Float32Array( points ), 1 );
M
r64  
Mr.doob 已提交
351

M
r67  
Mr.doob 已提交
352 353 354 355
				this.addAttribute( 'position', vertices );
				this.addAttribute( 'birdColor', birdColors );
				this.addAttribute( 'reference', references );
				this.addAttribute( 'birdVertex', birdVertex );
M
r64  
Mr.doob 已提交
356

M
r67  
Mr.doob 已提交
357 358 359 360 361 362
				// this.addAttribute( 'normal', new Float32Array( points * 3 ), 3 );


				var v = 0;

				function verts_push() {
M
r98  
Mr.doob 已提交
363 364 365 366 367

					for ( var i = 0; i < arguments.length; i ++ ) {

						vertices.array[ v ++ ] = arguments[ i ];

M
r103  
Mr.doob 已提交
368
					}
M
r98  
Mr.doob 已提交
369

M
r103  
Mr.doob 已提交
370
				}
M
r64  
Mr.doob 已提交
371

M
r67  
Mr.doob 已提交
372
				var wingsSpan = 20;
M
r64  
Mr.doob 已提交
373

M
r98  
Mr.doob 已提交
374
				for ( var f = 0; f < BIRDS; f ++ ) {
M
r67  
Mr.doob 已提交
375 376 377

					// Body
					verts_push(
M
r98  
Mr.doob 已提交
378 379
						0, - 0, - 20,
						0, 4, - 20,
M
r67  
Mr.doob 已提交
380
						0, 0, 30
M
r64  
Mr.doob 已提交
381 382
					);

M
r67  
Mr.doob 已提交
383 384
					// Left Wing
					verts_push(
M
r98  
Mr.doob 已提交
385 386
						0, 0, - 15,
						- wingsSpan, 0, 0,
M
r67  
Mr.doob 已提交
387 388
						0, 0, 15
					);
M
r64  
Mr.doob 已提交
389

M
r67  
Mr.doob 已提交
390 391 392 393
					// Right Wing
					verts_push(
						0, 0, 15,
						wingsSpan, 0, 0,
M
r98  
Mr.doob 已提交
394
						0, 0, - 15
M
r67  
Mr.doob 已提交
395
					);
M
r64  
Mr.doob 已提交
396

M
r67  
Mr.doob 已提交
397
				}
M
r64  
Mr.doob 已提交
398

M
r98  
Mr.doob 已提交
399
				for ( var v = 0; v < triangles * 3; v ++ ) {
M
r64  
Mr.doob 已提交
400

M
r98  
Mr.doob 已提交
401 402 403
					var i = ~ ~ ( v / 3 );
					var x = ( i % WIDTH ) / WIDTH;
					var y = ~ ~ ( i / WIDTH ) / WIDTH;
M
r67  
Mr.doob 已提交
404 405 406

					var c = new THREE.Color(
						0x444444 +
M
r98  
Mr.doob 已提交
407
						~ ~ ( v / 9 ) / BIRDS * 0x666666
M
r64  
Mr.doob 已提交
408 409
					);

M
r67  
Mr.doob 已提交
410 411 412 413
					birdColors.array[ v * 3 + 0 ] = c.r;
					birdColors.array[ v * 3 + 1 ] = c.g;
					birdColors.array[ v * 3 + 2 ] = c.b;

M
r98  
Mr.doob 已提交
414
					references.array[ v * 2 ] = x;
M
r67  
Mr.doob 已提交
415 416
					references.array[ v * 2 + 1 ] = y;

M
r98  
Mr.doob 已提交
417
					birdVertex.array[ v ] = v % 9;
M
r64  
Mr.doob 已提交
418 419 420

				}

M
r72  
Mr.doob 已提交
421
				this.scale( 0.2, 0.2, 0.2 );
M
r64  
Mr.doob 已提交
422

M
r72  
Mr.doob 已提交
423
			};
M
r64  
Mr.doob 已提交
424

M
r67  
Mr.doob 已提交
425
			THREE.BirdGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
M
r64  
Mr.doob 已提交
426 427 428


			var container, stats;
M
r98  
Mr.doob 已提交
429
			var camera, scene, renderer, i;
M
r64  
Mr.doob 已提交
430 431 432 433
			var mouseX = 0, mouseY = 0;

			var windowHalfX = window.innerWidth / 2;
			var windowHalfY = window.innerHeight / 2;
M
r68  
Mr.doob 已提交
434

M
r64  
Mr.doob 已提交
435 436
			var BOUNDS = 800, BOUNDS_HALF = BOUNDS / 2;

M
r98  
Mr.doob 已提交
437 438 439
			document.getElementById( 'birds' ).innerText = BIRDS;

			function change( n ) {
M
r64  
Mr.doob 已提交
440 441 442 443

				location.hash = n;
				location.reload();
				return false;
M
r98  
Mr.doob 已提交
444

M
r103  
Mr.doob 已提交
445
			}
M
r64  
Mr.doob 已提交
446 447

			var options = '';
M
r98  
Mr.doob 已提交
448 449 450 451 452
			for ( i = 1; i < 7; i ++ ) {

				var j = Math.pow( 2, i );
				options += '<a href="#" onclick="return change(' + j + ')">' + ( j * j ) + '</a> ';

M
r103  
Mr.doob 已提交
453 454
			}

M
r98  
Mr.doob 已提交
455
			document.getElementById( 'options' ).innerHTML = options;
M
r64  
Mr.doob 已提交
456 457 458

			var last = performance.now();

M
r78  
Mr.doob 已提交
459 460 461 462 463 464
			var gpuCompute;
			var velocityVariable;
			var positionVariable;
			var positionUniforms;
			var velocityUniforms;
			var birdUniforms;
M
r64  
Mr.doob 已提交
465 466 467 468 469 470 471 472 473 474 475 476 477

			init();
			animate();

			function init() {

				container = document.createElement( 'div' );
				document.body.appendChild( container );

				camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 3000 );
				camera.position.z = 350;

				scene = new THREE.Scene();
M
r87  
Mr.doob 已提交
478
				scene.background = new THREE.Color( 0xffffff );
M
r64  
Mr.doob 已提交
479 480 481
				scene.fog = new THREE.Fog( 0xffffff, 100, 1000 );

				renderer = new THREE.WebGLRenderer();
M
r70  
Mr.doob 已提交
482
				renderer.setPixelRatio( window.devicePixelRatio );
M
r64  
Mr.doob 已提交
483
				renderer.setSize( window.innerWidth, window.innerHeight );
M
r67  
Mr.doob 已提交
484
				container.appendChild( renderer.domElement );
M
r64  
Mr.doob 已提交
485

M
r78  
Mr.doob 已提交
486
				initComputeRenderer();
M
r64  
Mr.doob 已提交
487 488

				stats = new Stats();
M
r76  
Mr.doob 已提交
489
				container.appendChild( stats.dom );
M
r64  
Mr.doob 已提交
490 491 492 493 494 495 496 497 498 499 500 501 502 503 504

				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
				document.addEventListener( 'touchstart', onDocumentTouchStart, false );
				document.addEventListener( 'touchmove', onDocumentTouchMove, false );

				//

				window.addEventListener( 'resize', onWindowResize, false );



				var gui = new dat.GUI();


				var effectController = {
M
r102  
Mr.doob 已提交
505
					separation: 20.0,
M
r64  
Mr.doob 已提交
506 507 508 509 510
					alignment: 20.0,
					cohesion: 20.0,
					freedom: 0.75
				};

M
r98  
Mr.doob 已提交
511
				var valuesChanger = function () {
M
r64  
Mr.doob 已提交
512

M
r102  
Mr.doob 已提交
513
					velocityUniforms[ "separationDistance" ].value = effectController.separation;
M
r101  
Mr.doob 已提交
514 515 516
					velocityUniforms[ "alignmentDistance" ].value = effectController.alignment;
					velocityUniforms[ "cohesionDistance" ].value = effectController.cohesion;
					velocityUniforms[ "freedomFactor" ].value = effectController.freedom;
M
r64  
Mr.doob 已提交
517 518 519 520 521 522

				};

				valuesChanger();


M
r102  
Mr.doob 已提交
523
				gui.add( effectController, "separation", 0.0, 100.0, 1.0 ).onChange( valuesChanger );
M
r64  
Mr.doob 已提交
524 525 526 527 528
				gui.add( effectController, "alignment", 0.0, 100, 0.001 ).onChange( valuesChanger );
				gui.add( effectController, "cohesion", 0.0, 100, 0.025 ).onChange( valuesChanger );
				gui.close();

				initBirds();
M
r68  
Mr.doob 已提交
529

M
r64  
Mr.doob 已提交
530 531
			}

M
r78  
Mr.doob 已提交
532 533
			function initComputeRenderer() {

M
r101  
Mr.doob 已提交
534
				gpuCompute = new GPUComputationRenderer( WIDTH, WIDTH, renderer );
M
r78  
Mr.doob 已提交
535 536 537 538 539 540 541 542 543 544 545 546 547 548 549

				var dtPosition = gpuCompute.createTexture();
				var dtVelocity = gpuCompute.createTexture();
				fillPositionTexture( dtPosition );
				fillVelocityTexture( dtVelocity );

				velocityVariable = gpuCompute.addVariable( "textureVelocity", document.getElementById( 'fragmentShaderVelocity' ).textContent, dtVelocity );
				positionVariable = gpuCompute.addVariable( "texturePosition", document.getElementById( 'fragmentShaderPosition' ).textContent, dtPosition );

				gpuCompute.setVariableDependencies( velocityVariable, [ positionVariable, velocityVariable ] );
				gpuCompute.setVariableDependencies( positionVariable, [ positionVariable, velocityVariable ] );

				positionUniforms = positionVariable.material.uniforms;
				velocityUniforms = velocityVariable.material.uniforms;

M
r101  
Mr.doob 已提交
550 551 552 553 554
				positionUniforms[ "time" ] = { value: 0.0 };
				positionUniforms[ "delta" ] = { value: 0.0 };
				velocityUniforms[ "time" ] = { value: 1.0 };
				velocityUniforms[ "delta" ] = { value: 0.0 };
				velocityUniforms[ "testing" ] = { value: 1.0 };
M
r102  
Mr.doob 已提交
555
				velocityUniforms[ "separationDistance" ] = { value: 1.0 };
M
r101  
Mr.doob 已提交
556 557 558 559
				velocityUniforms[ "alignmentDistance" ] = { value: 1.0 };
				velocityUniforms[ "cohesionDistance" ] = { value: 1.0 };
				velocityUniforms[ "freedomFactor" ] = { value: 1.0 };
				velocityUniforms[ "predator" ] = { value: new THREE.Vector3() };
M
r78  
Mr.doob 已提交
560 561 562 563 564 565 566 567 568
				velocityVariable.material.defines.BOUNDS = BOUNDS.toFixed( 2 );

				velocityVariable.wrapS = THREE.RepeatWrapping;
				velocityVariable.wrapT = THREE.RepeatWrapping;
				positionVariable.wrapS = THREE.RepeatWrapping;
				positionVariable.wrapT = THREE.RepeatWrapping;

				var error = gpuCompute.init();
				if ( error !== null ) {
M
r98  
Mr.doob 已提交
569

M
r78  
Mr.doob 已提交
570
				    console.error( error );
M
r98  
Mr.doob 已提交
571

M
r103  
Mr.doob 已提交
572
				}
M
r78  
Mr.doob 已提交
573 574

			}
M
r64  
Mr.doob 已提交
575 576 577

			function initBirds() {

M
r67  
Mr.doob 已提交
578
				var geometry = new THREE.BirdGeometry();
M
r64  
Mr.doob 已提交
579 580 581

				// For Vertex and Fragment
				birdUniforms = {
M
r101  
Mr.doob 已提交
582 583 584 585 586
					"color": { value: new THREE.Color( 0xff2200 ) },
					"texturePosition": { value: null },
					"textureVelocity": { value: null },
					"time": { value: 1.0 },
					"delta": { value: 0.0 }
M
r64  
Mr.doob 已提交
587 588 589
				};

				// ShaderMaterial
M
r72  
Mr.doob 已提交
590
				var material = new THREE.ShaderMaterial( {
M
r98  
Mr.doob 已提交
591 592
					uniforms: birdUniforms,
					vertexShader: document.getElementById( 'birdVS' ).textContent,
M
r64  
Mr.doob 已提交
593
					fragmentShader: document.getElementById( 'birdFS' ).textContent,
M
r67  
Mr.doob 已提交
594
					side: THREE.DoubleSide
M
r64  
Mr.doob 已提交
595

M
r98  
Mr.doob 已提交
596
				} );
M
r64  
Mr.doob 已提交
597

M
r86  
Mr.doob 已提交
598
				var birdMesh = new THREE.Mesh( geometry, material );
M
r64  
Mr.doob 已提交
599 600 601 602
				birdMesh.rotation.y = Math.PI / 2;
				birdMesh.matrixAutoUpdate = false;
				birdMesh.updateMatrix();

M
r98  
Mr.doob 已提交
603
				scene.add( birdMesh );
M
r64  
Mr.doob 已提交
604 605 606

			}

M
r78  
Mr.doob 已提交
607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645
			function fillPositionTexture( texture ) {

				var theArray = texture.image.data;

				for ( var k = 0, kl = theArray.length; k < kl; k += 4 ) {

					var x = Math.random() * BOUNDS - BOUNDS_HALF;
					var y = Math.random() * BOUNDS - BOUNDS_HALF;
					var z = Math.random() * BOUNDS - BOUNDS_HALF;

					theArray[ k + 0 ] = x;
					theArray[ k + 1 ] = y;
					theArray[ k + 2 ] = z;
					theArray[ k + 3 ] = 1;

				}

			}

			function fillVelocityTexture( texture ) {

				var theArray = texture.image.data;

				for ( var k = 0, kl = theArray.length; k < kl; k += 4 ) {

					var x = Math.random() - 0.5;
					var y = Math.random() - 0.5;
					var z = Math.random() - 0.5;

					theArray[ k + 0 ] = x * 10;
					theArray[ k + 1 ] = y * 10;
					theArray[ k + 2 ] = z * 10;
					theArray[ k + 3 ] = 1;

				}

			}


M
r64  
Mr.doob 已提交
646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702
			function onWindowResize() {

				windowHalfX = window.innerWidth / 2;
				windowHalfY = window.innerHeight / 2;

				camera.aspect = window.innerWidth / window.innerHeight;
				camera.updateProjectionMatrix();

				renderer.setSize( window.innerWidth, window.innerHeight );

			}

			function onDocumentMouseMove( event ) {

				mouseX = event.clientX - windowHalfX;
				mouseY = event.clientY - windowHalfY;

			}

			function onDocumentTouchStart( event ) {

				if ( event.touches.length === 1 ) {

					event.preventDefault();

					mouseX = event.touches[ 0 ].pageX - windowHalfX;
					mouseY = event.touches[ 0 ].pageY - windowHalfY;

				}

			}

			function onDocumentTouchMove( event ) {

				if ( event.touches.length === 1 ) {

					event.preventDefault();

					mouseX = event.touches[ 0 ].pageX - windowHalfX;
					mouseY = event.touches[ 0 ].pageY - windowHalfY;

				}

			}

			//

			function animate() {

				requestAnimationFrame( animate );

				render();
				stats.update();

			}

			function render() {
M
r67  
Mr.doob 已提交
703

M
r72  
Mr.doob 已提交
704
				var now = performance.now();
M
r98  
Mr.doob 已提交
705
				var delta = ( now - last ) / 1000;
M
r64  
Mr.doob 已提交
706

M
r98  
Mr.doob 已提交
707
				if ( delta > 1 ) delta = 1; // safety cap on large deltas
M
r64  
Mr.doob 已提交
708 709
				last = now;

M
r101  
Mr.doob 已提交
710 711 712 713 714 715
				positionUniforms[ "time" ].value = now;
				positionUniforms[ "delta" ].value = delta;
				velocityUniforms[ "time" ].value = now;
				velocityUniforms[ "delta" ].value = delta;
				birdUniforms[ "time" ].value = now;
				birdUniforms[ "delta" ].value = delta;
M
r64  
Mr.doob 已提交
716

M
r101  
Mr.doob 已提交
717
				velocityUniforms[ "predator" ].value.set( 0.5 * mouseX / windowHalfX, - 0.5 * mouseY / windowHalfY, 0 );
M
r64  
Mr.doob 已提交
718 719 720 721

				mouseX = 10000;
				mouseY = 10000;

M
r78  
Mr.doob 已提交
722 723
				gpuCompute.compute();

M
r101  
Mr.doob 已提交
724 725
				birdUniforms[ "texturePosition" ].value = gpuCompute.getCurrentRenderTarget( positionVariable ).texture;
				birdUniforms[ "textureVelocity" ].value = gpuCompute.getCurrentRenderTarget( velocityVariable ).texture;
M
r77  
Mr.doob 已提交
726

M
r64  
Mr.doob 已提交
727 728 729 730 731 732 733
				renderer.render( scene, camera );

			}

		</script>
	</body>
</html>