You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							152 lines
						
					
					
						
							3.4 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							152 lines
						
					
					
						
							3.4 KiB
						
					
					
				| <!DOCTYPE html> | |
| <html lang="en"> | |
| 	<head> | |
| 		<title>three.js webgl - instancing - dynamic</title> | |
| 		<meta charset="utf-8"> | |
| 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> | |
| 		<link type="text/css" rel="stylesheet" href="main.css"> | |
| 	</head> | |
| 	<body> | |
| 
 | |
| 		<!-- Import maps polyfill --> | |
| 		<!-- Remove this when import maps will be widely supported --> | |
| 		<script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script> | |
| 
 | |
| 		<script type="importmap"> | |
| 			{ | |
| 				"imports": { | |
| 					"three": "../build/three.module.js", | |
| 					"three/addons/": "./jsm/" | |
| 				} | |
| 			} | |
| 		</script> | |
| 
 | |
| 		<script type="module"> | |
| 
 | |
| 			import * as THREE from 'three'; | |
| 
 | |
| 			import Stats from 'three/addons/libs/stats.module.js'; | |
| 			import { GUI } from 'three/addons/libs/lil-gui.module.min.js'; | |
| 
 | |
| 			let camera, scene, renderer, stats; | |
| 
 | |
| 			let mesh; | |
| 			const amount = parseInt( window.location.search.slice( 1 ) ) || 10; | |
| 			const count = Math.pow( amount, 3 ); | |
| 			const dummy = new THREE.Object3D(); | |
| 
 | |
| 			init(); | |
| 			animate(); | |
| 
 | |
| 			function init() { | |
| 
 | |
| 				camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.1, 100 ); | |
| 				camera.position.set( amount * 0.9, amount * 0.9, amount * 0.9 ); | |
| 				camera.lookAt( 0, 0, 0 ); | |
| 
 | |
| 				scene = new THREE.Scene(); | |
| 
 | |
| 				const loader = new THREE.BufferGeometryLoader(); | |
| 				loader.load( 'models/json/suzanne_buffergeometry.json', function ( geometry ) { | |
| 
 | |
| 					geometry.computeVertexNormals(); | |
| 					geometry.scale( 0.5, 0.5, 0.5 ); | |
| 
 | |
| 					const material = new THREE.MeshNormalMaterial(); | |
| 					// check overdraw | |
| 					// let material = new THREE.MeshBasicMaterial( { color: 0xff0000, opacity: 0.1, transparent: true } ); | |
|  | |
| 					mesh = new THREE.InstancedMesh( geometry, material, count ); | |
| 					mesh.instanceMatrix.setUsage( THREE.DynamicDrawUsage ); // will be updated every frame | |
| 					scene.add( mesh ); | |
| 
 | |
| 					// | |
|  | |
| 					const gui = new GUI(); | |
| 					gui.add( mesh, 'count', 0, count ); | |
| 
 | |
| 				} ); | |
| 
 | |
| 				// | |
|  | |
| 				renderer = new THREE.WebGLRenderer( { antialias: true } ); | |
| 				renderer.setPixelRatio( window.devicePixelRatio ); | |
| 				renderer.setSize( window.innerWidth, window.innerHeight ); | |
| 				document.body.appendChild( renderer.domElement ); | |
| 
 | |
| 				// | |
|  | |
| 				stats = new Stats(); | |
| 				document.body.appendChild( stats.dom ); | |
| 
 | |
| 				// | |
|  | |
| 				window.addEventListener( 'resize', onWindowResize ); | |
| 
 | |
| 			} | |
| 
 | |
| 			function onWindowResize() { | |
| 
 | |
| 				camera.aspect = window.innerWidth / window.innerHeight; | |
| 				camera.updateProjectionMatrix(); | |
| 
 | |
| 				renderer.setSize( window.innerWidth, window.innerHeight ); | |
| 
 | |
| 			} | |
| 
 | |
| 			// | |
|  | |
| 			function animate() { | |
| 
 | |
| 				requestAnimationFrame( animate ); | |
| 
 | |
| 				render(); | |
| 
 | |
| 				stats.update(); | |
| 
 | |
| 			} | |
| 
 | |
| 			function render() { | |
| 
 | |
| 				if ( mesh ) { | |
| 
 | |
| 					const time = Date.now() * 0.001; | |
| 
 | |
| 					mesh.rotation.x = Math.sin( time / 4 ); | |
| 					mesh.rotation.y = Math.sin( time / 2 ); | |
| 
 | |
| 					let i = 0; | |
| 					const offset = ( amount - 1 ) / 2; | |
| 
 | |
| 					for ( let x = 0; x < amount; x ++ ) { | |
| 
 | |
| 						for ( let y = 0; y < amount; y ++ ) { | |
| 
 | |
| 							for ( let z = 0; z < amount; z ++ ) { | |
| 
 | |
| 								dummy.position.set( offset - x, offset - y, offset - z ); | |
| 								dummy.rotation.y = ( Math.sin( x / 4 + time ) + Math.sin( y / 4 + time ) + Math.sin( z / 4 + time ) ); | |
| 								dummy.rotation.z = dummy.rotation.y * 2; | |
| 
 | |
| 								dummy.updateMatrix(); | |
| 
 | |
| 								mesh.setMatrixAt( i ++, dummy.matrix ); | |
| 
 | |
| 							} | |
| 
 | |
| 						} | |
| 
 | |
| 					} | |
| 
 | |
| 					mesh.instanceMatrix.needsUpdate = true; | |
| 
 | |
| 				} | |
| 
 | |
| 				renderer.render( scene, camera ); | |
| 
 | |
| 			} | |
| 
 | |
| 		</script> | |
| 
 | |
| 	</body> | |
| </html>
 | |
| 
 |