webgl_gpgpu_birds.html 17.3 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
r64  
Mr.doob 已提交
42 43 44 45
		<script src="js/Detector.js"></script>
		<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 86 87

		<!--
		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
			uniform float seperationDistance; // 20
			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 110
			const float LOWER_BOUNDS = -UPPER_BOUNDS;

			const float SPEED_LIMIT = 9.0;

			float rand(vec2 co){
M
r78  
Mr.doob 已提交
111
				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 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150

				zoneRadius = seperationDistance + alignmentDistance + cohesionDistance;
				separationThresh = seperationDistance / zoneRadius;
				alignmentThresh = ( seperationDistance + alignmentDistance ) / zoneRadius;
				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;

				float seperationSquared = seperationDistance * seperationDistance;
				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 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
				// move birds away from predator
				if (dist < preyRadius) {

					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 173 174 175
				dir.y *= 2.5;
				velocity -= normalize( dir ) * delta * 5.;

				for (float y=0.0;y<height;y++) {
					for (float x=0.0;x<width;x++) {

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 180 181

						dir = birdPosition - selfPosition;
						dist = length(dir);

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

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

M
r70  
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 193 194
							// Separation - Move apart for comfort
							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 205
							f = ( 0.5 - cos( adjustedPercent * PI_2 ) * 0.5 + 0.5 ) * delta;
							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
r70  
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 325 326 327 328 329 330
				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>

			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();

			var hash = document.location.hash.substr( 1 );
			if (hash) hash = parseInt(hash, 0);

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

M
r67  
Mr.doob 已提交
333
			var BIRDS = WIDTH * WIDTH;
M
r64  
Mr.doob 已提交
334

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

M
r67  
Mr.doob 已提交
338 339 340 341 342
				var triangles = BIRDS * 3;
				var points = triangles * 3;

				THREE.BufferGeometry.call( this );

M
r68  
Mr.doob 已提交
343 344 345 346
				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 已提交
347

M
r67  
Mr.doob 已提交
348 349 350 351
				this.addAttribute( 'position', vertices );
				this.addAttribute( 'birdColor', birdColors );
				this.addAttribute( 'reference', references );
				this.addAttribute( 'birdVertex', birdVertex );
M
r64  
Mr.doob 已提交
352

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


				var v = 0;

				function verts_push() {
					for (var i=0; i < arguments.length; i++) {
						vertices.array[v++] = arguments[i];
					}
				}
M
r64  
Mr.doob 已提交
363

M
r67  
Mr.doob 已提交
364
				var wingsSpan = 20;
M
r64  
Mr.doob 已提交
365 366

				for (var f = 0; f<BIRDS; f++ ) {
M
r67  
Mr.doob 已提交
367 368 369 370 371 372

					// Body
					verts_push(
						0, -0, -20,
						0, 4, -20,
						0, 0, 30
M
r64  
Mr.doob 已提交
373 374
					);

M
r67  
Mr.doob 已提交
375 376 377 378 379 380
					// Left Wing
					verts_push(
						0, 0, -15,
						-wingsSpan, 0, 0,
						0, 0, 15
					);
M
r64  
Mr.doob 已提交
381

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

M
r67  
Mr.doob 已提交
389
				}
M
r64  
Mr.doob 已提交
390

M
r67  
Mr.doob 已提交
391
				for( var v = 0; v < triangles * 3; v++ ) {
M
r64  
Mr.doob 已提交
392

M
r67  
Mr.doob 已提交
393 394 395 396 397 398 399
					var i = ~~(v / 3);
					var x = (i % WIDTH) / WIDTH;
					var y = ~~(i / WIDTH) / WIDTH;

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

M
r67  
Mr.doob 已提交
402 403 404 405 406 407 408 409
					birdColors.array[ v * 3 + 0 ] = c.r;
					birdColors.array[ v * 3 + 1 ] = c.g;
					birdColors.array[ v * 3 + 2 ] = c.b;

					references.array[ v * 2     ] = x;
					references.array[ v * 2 + 1 ] = y;

					birdVertex.array[ v         ] = v % 9;
M
r64  
Mr.doob 已提交
410 411 412

				}

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

M
r72  
Mr.doob 已提交
415
			};
M
r64  
Mr.doob 已提交
416

M
r67  
Mr.doob 已提交
417
			THREE.BirdGeometry.prototype = Object.create( THREE.BufferGeometry.prototype );
M
r64  
Mr.doob 已提交
418 419 420 421 422 423 424 425


			var container, stats;
			var camera, scene, renderer, geometry, i, h, color;
			var mouseX = 0, mouseY = 0;

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

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

M
r78  
Mr.doob 已提交
429
			document.getElementById('birds').innerText = BIRDS;
M
r64  
Mr.doob 已提交
430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446

			function change(n) {
				location.hash = n;
				location.reload();
				return false;
			}


			var options = '';
			for (i=1; i<7; i++) {
				var j = Math.pow(2, i);
				options += '<a href="#" onclick="return change(' + j + ')">' + (j * j) + '</a> ';
			}
			document.getElementById('options').innerHTML = options;

			var last = performance.now();

M
r78  
Mr.doob 已提交
447 448 449 450 451 452
			var gpuCompute;
			var velocityVariable;
			var positionVariable;
			var positionUniforms;
			var velocityUniforms;
			var birdUniforms;
M
r64  
Mr.doob 已提交
453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469

			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();

				scene.fog = new THREE.Fog( 0xffffff, 100, 1000 );

				renderer = new THREE.WebGLRenderer();
M
r70  
Mr.doob 已提交
470 471
				renderer.setClearColor( scene.fog.color );
				renderer.setPixelRatio( window.devicePixelRatio );
M
r64  
Mr.doob 已提交
472
				renderer.setSize( window.innerWidth, window.innerHeight );
M
r67  
Mr.doob 已提交
473
				container.appendChild( renderer.domElement );
M
r64  
Mr.doob 已提交
474

M
r78  
Mr.doob 已提交
475
				initComputeRenderer();
M
r64  
Mr.doob 已提交
476 477

				stats = new Stats();
M
r76  
Mr.doob 已提交
478
				container.appendChild( stats.dom );
M
r64  
Mr.doob 已提交
479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501

				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 = {
					seperation: 20.0,
					alignment: 20.0,
					cohesion: 20.0,
					freedom: 0.75
				};

				var valuesChanger = function() {

M
r78  
Mr.doob 已提交
502 503 504 505
					velocityUniforms.seperationDistance.value = effectController.seperation;
					velocityUniforms.alignmentDistance.value = effectController.alignment;
					velocityUniforms.cohesionDistance.value = effectController.cohesion;
					velocityUniforms.freedomFactor.value = effectController.freedom;
M
r64  
Mr.doob 已提交
506 507 508 509 510 511 512 513 514 515 516 517

				};

				valuesChanger();


				gui.add( effectController, "seperation", 0.0, 100.0, 1.0 ).onChange( valuesChanger );
				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 已提交
518

M
r64  
Mr.doob 已提交
519 520
			}

M
r78  
Mr.doob 已提交
521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561
			function initComputeRenderer() {

    				gpuCompute = new GPUComputationRenderer( WIDTH, WIDTH, renderer );

				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;

				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 };
				velocityUniforms.seperationDistance = { value: 1.0 };
				velocityUniforms.alignmentDistance = { value: 1.0 };
				velocityUniforms.cohesionDistance = { value: 1.0 };
				velocityUniforms.freedomFactor = { value: 1.0 };
				velocityUniforms.predator = { value: new THREE.Vector3() };
				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 ) {
				    console.error( error );
				}

			}
M
r64  
Mr.doob 已提交
562 563 564

			function initBirds() {

M
r67  
Mr.doob 已提交
565
				var geometry = new THREE.BirdGeometry();
M
r64  
Mr.doob 已提交
566 567 568

				// For Vertex and Fragment
				birdUniforms = {
M
r78  
Mr.doob 已提交
569 570 571 572 573
					color: { value: new THREE.Color( 0xff2200 ) },
					texturePosition: { value: null },
					textureVelocity: { value: null },
					time: { value: 1.0 },
					delta: { value: 0.0 }
M
r64  
Mr.doob 已提交
574 575 576
				};

				// ShaderMaterial
M
r72  
Mr.doob 已提交
577 578
				var material = new THREE.ShaderMaterial( {
					uniforms:       birdUniforms,
M
r64  
Mr.doob 已提交
579 580
					vertexShader:   document.getElementById( 'birdVS' ).textContent,
					fragmentShader: document.getElementById( 'birdFS' ).textContent,
M
r67  
Mr.doob 已提交
581
					side: THREE.DoubleSide
M
r64  
Mr.doob 已提交
582 583 584

				});

M
r86  
Mr.doob 已提交
585
				var birdMesh = new THREE.Mesh( geometry, material );
M
r64  
Mr.doob 已提交
586 587 588 589 590 591 592 593
				birdMesh.rotation.y = Math.PI / 2;
				birdMesh.matrixAutoUpdate = false;
				birdMesh.updateMatrix();

				scene.add(birdMesh);

			}

M
r78  
Mr.doob 已提交
594 595 596 597 598 599 600 601 602 603 604 605 606 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
			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 已提交
633 634 635 636 637 638 639 640 641 642 643 644 645 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
			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 已提交
690

M
r72  
Mr.doob 已提交
691
				var now = performance.now();
M
r67  
Mr.doob 已提交
692
				var delta = (now - last) / 1000;
M
r64  
Mr.doob 已提交
693 694 695 696

				if (delta > 1) delta = 1; // safety cap on large deltas
				last = now;

M
r78  
Mr.doob 已提交
697 698 699 700
				positionUniforms.time.value = now;
				positionUniforms.delta.value = delta;
				velocityUniforms.time.value = now;
				velocityUniforms.delta.value = delta;
M
r64  
Mr.doob 已提交
701 702 703
				birdUniforms.time.value = now;
				birdUniforms.delta.value = delta;

M
r78  
Mr.doob 已提交
704
				velocityUniforms.predator.value.set( 0.5 * mouseX / windowHalfX, - 0.5 * mouseY / windowHalfY, 0 );
M
r64  
Mr.doob 已提交
705 706 707 708

				mouseX = 10000;
				mouseY = 10000;

M
r78  
Mr.doob 已提交
709 710 711 712
				gpuCompute.compute();

				birdUniforms.texturePosition.value = gpuCompute.getCurrentRenderTarget( positionVariable ).texture;
				birdUniforms.textureVelocity.value = gpuCompute.getCurrentRenderTarget( velocityVariable ).texture;
M
r77  
Mr.doob 已提交
713

M
r64  
Mr.doob 已提交
714 715 716 717 718 719 720
				renderer.render( scene, camera );

			}

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