Browse Source

Examples: Refactor instancing - dynamic

Mugen87 8 năm trước cách đây
mục cha
commit
5460d602b7
1 tập tin đã thay đổi với 66 bổ sung145 xóa
  1. 66 145
      examples/webgl_buffergeometry_instancing_dynamic.html

+ 66 - 145
examples/webgl_buffergeometry_instancing_dynamic.html

@@ -69,15 +69,14 @@
 		void main() {
 
 			vec3 vPosition = position;
-			vec3 vcV = cross(orientation.xyz, vPosition);
-			vPosition = vcV * (2.0 * orientation.w) + (cross(orientation.xyz, vcV) * 2.0 + vPosition);
+			vec3 vcV = cross( orientation.xyz, vPosition );
+			vPosition = vcV * ( 2.0 * orientation.w ) + ( cross( orientation.xyz, vcV ) * 2.0 + vPosition );
 
 			vUv = uv;
 
 			gl_Position = projectionMatrix * modelViewMatrix * vec4( offset + vPosition, 1.0 );
 
 		}
-
 	</script>
 
 	<script id="fragmentShader" type="x-shader/x-fragment">
@@ -89,187 +88,116 @@
 
 		void main() {
 
-			gl_FragColor = texture2D(map, vUv);
+			gl_FragColor = texture2D( map, vUv );
 
 		}
-
 	</script>
 
 	<script>
 
-		if ( !Detector.webgl ) Detector.addGetWebGLMessage();
+		if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
 
 		var container, stats;
+		var camera, scene, renderer, mesh;
+		var offsetAttribute, orientationAttribute;
 
-		var camera, scene, renderer;
-		var orientations;
+		var lastTime = 0;
 
+		var moveQ = new THREE.Quaternion( 0.5, 0.5, 0.5, 0.0 ).normalize();
+		var tmpQ = new THREE.Quaternion();
+		var currentQ = new THREE.Quaternion();
+
+		init();
+		animate();
 
 		function init() {
 
 			container = document.getElementById( 'container' );
 
 			camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1000 );
-			//camera.position.z = 20;
 
 			scene = new THREE.Scene();
 			scene.background = new THREE.Color( 0x101010 );
 
-			renderer = new THREE.WebGLRenderer();
-
 			// geometry
 
 			var instances = 5000;
 
-			var geometry = new THREE.InstancedBufferGeometry();
+			var bufferGeometry = new THREE.BoxBufferGeometry( 2, 2, 2 );
 
-			// per mesh data
-			var vertices = new THREE.BufferAttribute( new Float32Array( [
-				// Front
-				-1, 1, 1,
-				1, 1, 1,
-				-1, -1, 1,
-				1, -1, 1,
-				// Back
-				1, 1, -1,
-				-1, 1, -1,
-				1, -1, -1,
-				-1, -1, -1,
-				// Left
-				-1, 1, -1,
-				-1, 1, 1,
-				-1, -1, -1,
-				-1, -1, 1,
-				// Right
-				1, 1, 1,
-				1, 1, -1,
-				1, -1, 1,
-				1, -1, -1,
-				// Top
-				-1, 1, 1,
-				1, 1, 1,
-				-1, 1, -1,
-				1, 1, -1,
-				// Bottom
-				1, -1, 1,
-				-1, -1, 1,
-				1, -1, -1,
-				-1, -1, -1
-			] ), 3 );
-
-			geometry.addAttribute( 'position', vertices );
-
-			var uvs = new THREE.BufferAttribute( new Float32Array( [
-						//x	y	z
-						// Front
-						0, 0,
-						1, 0,
-						0, 1,
-						1, 1,
-						// Back
-						1, 0,
-						0, 0,
-						1, 1,
-						0, 1,
-						// Left
-						1, 1,
-						1, 0,
-						0, 1,
-						0, 0,
-						// Right
-						1, 0,
-						1, 1,
-						0, 0,
-						0, 1,
-						// Top
-						0, 0,
-						1, 0,
-						0, 1,
-						1, 1,
-						// Bottom
-						1, 0,
-						0, 0,
-						1, 1,
-						0, 1
-			] ), 2 );
-
-			geometry.addAttribute( 'uv', uvs );
-
-			var indices = new Uint16Array( [
-				0, 1, 2,
-				2, 1, 3,
-				4, 5, 6,
-				6, 5, 7,
-				8, 9, 10,
-				10, 9, 11,
-				12, 13, 14,
-				14, 13, 15,
-				16, 17, 18,
-				18, 17, 19,
-				20, 21, 22,
-				22, 21, 23
-			] );
-
-			geometry.setIndex( new THREE.BufferAttribute( indices, 1 ) );
+			// copy data from a simple box geometry
+
+			var geometry = new THREE.InstancedBufferGeometry();
+			geometry.index = bufferGeometry.index;
+			geometry.attributes = bufferGeometry.attributes;
+			geometry.groups = bufferGeometry.groups;
 
 			// per instance data
-			var offsets = new THREE.InstancedBufferAttribute( new Float32Array( instances * 3 ), 3, 1 );
+
+			var offsets = [];
+			var orientations = [];
 
 			var vector = new THREE.Vector4();
-			for ( var i = 0, ul = offsets.count; i < ul; i++ ) {
-				var x = Math.random() * 100 - 50;
-				var y = Math.random() * 100 - 50;
-				var z = Math.random() * 100 - 50;
-				vector.set( x, y, z, 0 ).normalize();
-				// move out at least 5 units from center in current direction
-				offsets.setXYZ( i, x + vector.x * 5, y + vector.y * 5, z + vector.z * 5 );
+			var x, y, z, w;
 
-			}
+			for ( var i = 0; i < instances; i ++ ) {
 
-			geometry.addAttribute( 'offset', offsets ); // per mesh translation
+				// offsets
 
+				x = Math.random() * 100 - 50;
+				y = Math.random() * 100 - 50;
+				z = Math.random() * 100 - 50;
 
-			orientations = new THREE.InstancedBufferAttribute( new Float32Array( instances * 4 ), 4, 1 ).setDynamic( true );
+				vector.set( x, y, z, 0 ).normalize();
+				vector.multiplyScalar( 5 ); // move out at least 5 units from center in current direction
 
-			for ( var i = 0, ul = orientations.count; i < ul; i++ ) {
+				offsets.push( x + vector.x, y + vector.y, z + vector.z );
 
-				vector.set( Math.random() * 2 - 1, Math.random() * 2 - 1, Math.random() * 2 - 1, Math.random() * 2 - 1 );
-				vector.normalize();
+				// orientations
 
-				orientations.setXYZW( i, vector.x, vector.y, vector.z, vector.w );
+				x = Math.random() * 2 - 1;
+				y = Math.random() * 2 - 1;
+				z = Math.random() * 2 - 1;
+				w = Math.random() * 2 - 1;
+
+				vector.set( x, y, z, w ).normalize();
+
+				orientations.push( vector.x, vector.y, vector.z, vector.w );
 
 			}
 
-			geometry.addAttribute( 'orientation', orientations ); // per mesh orientation
+			offsetAttribute = new THREE.InstancedBufferAttribute( new Float32Array( offsets ), 3 );
+			orientationAttribute = new THREE.InstancedBufferAttribute( new Float32Array( orientations ), 4 ).setDynamic( true );
+
+			geometry.addAttribute( 'offset', offsetAttribute );
+			geometry.addAttribute( 'orientation', orientationAttribute );
 
 			// material
-			var texture = new THREE.TextureLoader().load( 'textures/crate.gif' );
-			texture.anisotropy = renderer.getMaxAnisotropy();
 
 			var material = new THREE.RawShaderMaterial( {
 
 				uniforms: {
-					map: { value: texture }
+					map: { value: new THREE.TextureLoader().load( 'textures/crate.gif' ) }
 				},
 				vertexShader: document.getElementById( 'vertexShader' ).textContent,
-				fragmentShader: document.getElementById( 'fragmentShader' ).textContent,
-				side: THREE.DoubleSide,
-				transparent: false
+				fragmentShader: document.getElementById( 'fragmentShader' ).textContent
 
 			} );
 
-			var mesh = new THREE.Mesh( geometry, material );
+			mesh = new THREE.Mesh( geometry, material );
 			scene.add( mesh );
 
+			renderer = new THREE.WebGLRenderer();
+			renderer.setPixelRatio( window.devicePixelRatio );
+			renderer.setSize( window.innerWidth, window.innerHeight );
+			container.appendChild( renderer.domElement );
 
 			if ( renderer.extensions.get( 'ANGLE_instanced_arrays' ) === false ) {
-				document.getElementById( "notSupported" ).style.display = "";
+
+				document.getElementById( 'notSupported' ).style.display = '';
 				return;
-			}
 
-			renderer.setPixelRatio( window.devicePixelRatio );
-			renderer.setSize( window.innerWidth, window.innerHeight );
-			container.appendChild( renderer.domElement );
+			}
 
 			stats = new Stats();
 			container.appendChild( stats.dom );
@@ -298,38 +226,31 @@
 
 		}
 
-		var lastTime = 0;
-
-		var moveQ = ( new THREE.Quaternion( .5, .5, .5, 0.0 ) ).normalize();
-		var tmpQ = new THREE.Quaternion();
-		var currentQ = new THREE.Quaternion();
 		function render() {
 
 			var time = performance.now();
 
-			var object = scene.children[0];
-
-			object.rotation.y = time * 0.00005;
-
-			renderer.render( scene, camera );
+			mesh.rotation.y = time * 0.00005;
 
 			var delta = ( time - lastTime ) / 5000;
 			tmpQ.set( moveQ.x * delta, moveQ.y * delta, moveQ.z * delta, 1 ).normalize();
 
-			for ( var i = 0, ul = orientations.count; i < ul; i++ ) {
-				var index = i * 4;
-				currentQ.set( orientations.array[index], orientations.array[index + 1], orientations.array[index + 2], orientations.array[index + 3] );
+			for ( var i = 0, il = orientationAttribute.count; i < il; i ++ ) {
+
+				currentQ.fromArray( orientationAttribute.array, ( i * 4 ) );
 				currentQ.multiply( tmpQ );
 
-				orientations.setXYZW( i, currentQ.x, currentQ.y, currentQ.z, currentQ.w );
+				orientationAttribute.setXYZW( i, currentQ.x, currentQ.y, currentQ.z, currentQ.w );
 
 			}
-			orientations.needsUpdate = true;
+
+			orientationAttribute.needsUpdate = true;
 			lastTime = time;
+
+			renderer.render( scene, camera );
+
 		}
 
-		init();
-		animate();
 	</script>
 
 </body>