webgl_buffergeometry_drawcalls.html 8.0 KB
Newer Older
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 35 36 37 38 39 40 41 42 43 44
<!DOCTYPE html>
<html lang="en">
	<head>
		<title>three.js webgl - buffergeometry - lines drawcalls</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 {
				color: #cccccc;
				font-family:Monospace;
				font-size:13px;
				text-align:center;

				background-color: #000000;
				margin: 0px;
				overflow: hidden;
			}

			#info {
				position: absolute;
				top: 0px; width: 100%;
				padding: 5px;
			}

			a {

				color: #0080ff;
			}

		</style>
	</head>
	<body>

		<div id="container"></div>
		<div id="info">
			<a href="http://threejs.org" target="_blank">three.js</a> webgl - buffergeometry drawcalls - by <a href="https://twitter.com/fernandojsg">fernandojsg</a>
		</div>

		<script src="js/libs/dat.gui.min.js"></script>
		<script src="../build/three.min.js"></script>
		<script src="js/controls/OrbitControls.js"></script>
		<script src="js/libs/stats.min.js"></script>

		<script>
45

46 47
			var group;
			var container, stats;
F
Fernando Serrano 已提交
48
			var particlesData = [];
49 50 51 52
			var camera, scene, renderer;
			var positions,colors;
			var pointCloud;
			var particlePositions;
53
			var linesMesh;
54 55

			var maxParticleCount = 1000;
F
Fernando Serrano 已提交
56
			var particleCount = 500;
57
			var r = 800;
58
			var rHalf = r / 2;
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75

			var effectController = {
				showDots: true,
				showLines: true,
				minDistance: 150,
				limitConnections: false,
				maxConnections: 20,
				particleCount: 500
			}

			init();
			animate();

			function initGUI() {
				
				var gui = new dat.GUI();
				
F
Fernando Serrano 已提交
76 77
				gui.add( effectController, "showDots" ).onChange( function( value ) { pointCloud.visible = value; } );
				gui.add( effectController, "showLines" ).onChange( function( value ) { linesMesh.visible = value; } );
78 79
				gui.add( effectController, "minDistance", 10, 300 );
				gui.add( effectController, "limitConnections" );
F
Fernando Serrano 已提交
80 81 82 83 84 85
				gui.add( effectController, "maxConnections", 0, 30, 1 );
				gui.add( effectController, "particleCount", 0, maxParticleCount, 1 ).onChange( function( value ) { 
					
					particleCount = parseInt( value );
					particles.drawcalls[ 0 ].count = particleCount;

86 87 88 89 90
				});
					
			}

			function init() {
91

92 93 94 95 96 97 98 99 100 101 102 103 104 105
				initGUI();

				container = document.getElementById( 'container' );

				//

				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 4000 );
				camera.position.z = 1750;

				controls = new THREE.OrbitControls( camera );
				controls.damping = 0.2;
				controls.addEventListener( 'change', render );

				scene = new THREE.Scene();
F
Fernando Serrano 已提交
106

107 108 109
				geometry = new THREE.BufferGeometry();
				var material = new THREE.LineBasicMaterial({ vertexColors: THREE.VertexColors });

F
Fernando Serrano 已提交
110
				var segments = maxParticleCount * maxParticleCount;
111 112 113 114

				positions = new Float32Array( segments * 3 );
				colors = new Float32Array( segments * 3 );

F
Fernando Serrano 已提交
115 116 117 118 119 120 121
				var pMaterial = new THREE.PointCloudMaterial({
					color: 0xFFFFFF,
					size: 3,
					blending: THREE.AdditiveBlending,
					transparent: true,
					sizeAttenuation: false
				});
122 123 124 125

				particles = new THREE.BufferGeometry();
				particlePositions = new Float32Array( maxParticleCount * 3 );

F
Fernando Serrano 已提交
126
				for ( var i = 0; i < maxParticleCount; i++ ) {
127 128 129 130 131

					var x = Math.random() * r - r / 2;
					var y = Math.random() * r - r / 2;
					var z = Math.random() * r - r / 2;
	
F
Fernando Serrano 已提交
132
					particlePositions[ i * 3     ] = x;
133 134
					particlePositions[ i * 3 + 1 ] = y;
					particlePositions[ i * 3 + 2 ] = z;
135

F
Fernando Serrano 已提交
136 137 138 139 140
					// add it to the geometry
					particlesData.push({
						velocity: new THREE.Vector3( -1 + Math.random() * 2, -1 + Math.random() * 2,  -1 + Math.random() * 2 ),
						numConnections: 0
					});
141

F
Fernando Serrano 已提交
142
				}
143

F
Fernando Serrano 已提交
144 145 146 147 148
				particles.drawcalls.push( {
					start: 0,
					count: particleCount,
					index: 0
				} );
149 150 151 152

				particles.addAttribute( 'position', new THREE.BufferAttribute( particlePositions, 3 ) );

				// create the particle system
F
Fernando Serrano 已提交
153
				pointCloud = new THREE.PointCloud( particles, pMaterial );
154

F
Fernando Serrano 已提交
155
				group = new THREE.Object3D();
156

F
Fernando Serrano 已提交
157 158
				// add it to the scene
				group.add( pointCloud );
159 160 161 162 163 164

				geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
				geometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ) );

				geometry.computeBoundingSphere();

F
Fernando Serrano 已提交
165 166 167 168 169
				geometry.drawcalls.push( {
					start: 0,
					count: 0,
					index: 0
				} );
170 171 172 173

				linesMesh = new THREE.Line( geometry, material, THREE.LinePieces );
				group.add( linesMesh );

F
Fernando Serrano 已提交
174
				scene.add( group );
175 176 177 178
				
				//
				
				renderer = new THREE.WebGLRenderer( { antialias: true } );
F
Fernando Serrano 已提交
179
				renderer.setPixelRatio( window.devicePixelRatio )
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
				renderer.setSize( window.innerWidth, window.innerHeight );

				renderer.gammaInput = true;
				renderer.gammaOutput = true;

				container.appendChild( renderer.domElement );

				//
				
				stats = new Stats();
				stats.domElement.style.position = 'absolute';
				stats.domElement.style.top = '0px';
				container.appendChild( stats.domElement );

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

			}

			function onWindowResize() {

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

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

			}

			function animate() {

F
Fernando Serrano 已提交
209 210 211
				var vertexpos = 0;
				var colorpos = 0;
				var numConnected = 0;
212

F
Fernando Serrano 已提交
213 214
				for ( var i = 0; i < particleCount; i++ )
					particlesData[ i ].numConnections = 0;
215

F
Fernando Serrano 已提交
216
				for ( var i = 0; i < particleCount; i++ ) {
217

F
Fernando Serrano 已提交
218 219
					// get the particle
					var particleData = particlesData[i];
220

221 222 223
					particlePositions[ i * 3     ] += particleData.velocity.x;
					particlePositions[ i * 3 + 1 ] += particleData.velocity.y;
					particlePositions[ i * 3 + 2 ] += particleData.velocity.z;
224

F
Fernando Serrano 已提交
225 226
					if ( particlePositions[ i * 3 + 1 ] < -rHalf || particlePositions[ i * 3 + 1 ] > rHalf )
						particleData.velocity.y = -particleData.velocity.y;
227

F
Fernando Serrano 已提交
228 229
					if ( particlePositions[ i * 3 ] < -rHalf || particlePositions[ i * 3 ] > rHalf )
						particleData.velocity.x = -particleData.velocity.x;
230

F
Fernando Serrano 已提交
231 232
					if ( particlePositions[ i * 3 + 2 ] < -rHalf || particlePositions[ i * 3 + 2 ] > rHalf )
						particleData.velocity.z = -particleData.velocity.z;
233

F
Fernando Serrano 已提交
234 235
					if ( effectController.limitConnections && particleData.numConnections >= effectController.maxConnections )
						continue;
236

F
Fernando Serrano 已提交
237 238
					// Check collision
					for ( var j = i + 1; j < particleCount; j++ ) {
239

F
Fernando Serrano 已提交
240 241 242
						var particleDataB = particlesData[ j ];
						if ( effectController.limitConnections && particleDataB.numConnections >= effectController.maxConnections )
							continue;
243
						
244 245 246 247
						var dx = particlePositions[ i * 3     ] - particlePositions[ j * 3     ];
						var dy = particlePositions[ i * 3 + 1 ] - particlePositions[ j * 3 + 1 ];
						var dz = particlePositions[ i * 3 + 2 ] - particlePositions[ j * 3 + 2 ];
						var dist = Math.sqrt( dx * dx + dy * dy + dz * dz );
248

F
Fernando Serrano 已提交
249 250
						if ( dist < effectController.minDistance ) {
							
251 252 253
							particleData.numConnections++;
							particleDataB.numConnections++;

F
Fernando Serrano 已提交
254
							var alpha = 1.0 - dist / effectController.minDistance + 0.2;
255

F
Fernando Serrano 已提交
256 257 258
							positions[ vertexpos++ ] = particlePositions[ i * 3     ];
							positions[ vertexpos++ ] = particlePositions[ i * 3 + 1 ];
							positions[ vertexpos++ ] = particlePositions[ i * 3 + 2 ];
259

F
Fernando Serrano 已提交
260 261 262
							positions[ vertexpos++ ] = particlePositions[ j * 3     ];
							positions[ vertexpos++ ] = particlePositions[ j * 3 + 1 ];
							positions[ vertexpos++ ] = particlePositions[ j * 3 + 2 ];
263

F
Fernando Serrano 已提交
264 265 266
							colors[ colorpos++ ] = alpha;
							colors[ colorpos++ ] = alpha;
							colors[ colorpos++ ] = alpha;
267

F
Fernando Serrano 已提交
268 269 270
							colors[ colorpos++ ] = alpha;
							colors[ colorpos++ ] = alpha;
							colors[ colorpos++ ] = alpha;
271

F
Fernando Serrano 已提交
272 273 274 275
							numConnected++;
						}
					}
				}
276 277


F
Fernando Serrano 已提交
278 279 280
				linesMesh.geometry.drawcalls[ 0 ].count = numConnected * 2;
				linesMesh.geometry.attributes.position.needsUpdate = true;
				linesMesh.geometry.attributes.color.needsUpdate = true;
281

F
Fernando Serrano 已提交
282
				pointCloud.geometry.attributes.position.needsUpdate = true;
283 284 285 286 287 288 289 290 291 292 293 294

				requestAnimationFrame( animate );

				stats.update();
				render();

			}

			function render() {

				var time = Date.now() * 0.001;

295
				group.rotation.y = time * 0.1;
296 297 298 299 300 301
				renderer.render( scene, camera );

			}

		</script>
	</body>
F
Fernando Serrano 已提交
302
</html>