首页 > 其他分享 >InstancedMesh threejs 批量重复使用相同的物体和材质

InstancedMesh threejs 批量重复使用相同的物体和材质

时间:2023-03-01 16:23:26浏览次数:38  
标签:threejs const camera THREE 重复使用 InstancedMesh window mesh new

代码


<!DOCTYPE html>
<html lang="en">
	<head>
		<title>three.js webgl - instancing - raycast</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" />
		<!-- Import maps polyfill -->
		<!-- Remove this when import maps will be widely supported -->
		<script
			async
			src="https://unpkg.com/[email protected]/dist/es-module-shims.js"
		></script>

		<script type="importmap">
			{
				"imports": {
					"three": "../build/three.module.js",
					"three/addons/": "./jsm/"
				}
			}
		</script>
	</head>
	<body>
		<script type="module">
			import * as THREE from 'three';
			import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

			let camera, scene, renderer, controls, stats;

			let mesh;
			const amount = parseInt(window.location.search.slice(1)) || 10;

			//const count = Math.pow(amount, 3);

			const count = 5;

			const raycaster = new THREE.Raycaster();
			const mouse = new THREE.Vector2(1, 1);

			const color = new THREE.Color();
			const white = new THREE.Color().setHex(0xffffff);

			init();
			animate();

			function init() {
				// camera
				camera = new THREE.PerspectiveCamera(
					60,
					window.innerWidth / window.innerHeight,
					0.1,
					100
				);
				camera.position.set(amount, amount, amount);
				camera.lookAt(0, 0, 0);

				// scene
				scene = new THREE.Scene();
				scene.background = new THREE.Color(0xa0a0a0);

				// light
				const light = new THREE.HemisphereLight(0xffffff, 0x888888);
				light.position.set(0, 1, 0);
				scene.add(light);

				// grid helper
				const size = 10;
				const divisions = 10;

				const gridHelper = new THREE.GridHelper(size, divisions);
				scene.add(gridHelper);

				// 圆球
				const geometry = new THREE.IcosahedronGeometry(0.5, 3);
				const material = new THREE.MeshPhongMaterial({ color: 0xffffff });

				// Instanced mesh,翻译过来就是单例物体
				// 物体的形状,物体的材质,最大的数量
				mesh = new THREE.InstancedMesh(geometry, material, 2);

				// 通过矩阵设置同样物体的位置,然后物体使用该矩阵
				const matrix = new THREE.Matrix4();
				matrix.setPosition(1, 0, 0);
				mesh.setMatrixAt(0, matrix);
				mesh.setColorAt(0, color);

				matrix.setPosition(2, 0, 0);
				mesh.setMatrixAt(1, matrix);
				mesh.setColorAt(1, color.setHex(Math.random() * 0xffffff));

				scene.add(mesh);

				// renderer
				renderer = new THREE.WebGLRenderer({ antialias: true });
				renderer.setPixelRatio(window.devicePixelRatio);
				renderer.setSize(window.innerWidth, window.innerHeight);
				document.body.appendChild(renderer.domElement);

				// controls
				controls = new OrbitControls(camera, renderer.domElement);
				controls.enableDamping = true;
				controls.enableZoom = false;
				controls.enablePan = false;

				window.addEventListener('resize', onWindowResize);
				document.addEventListener('mousemove', onm ouseMove);
			}

			function onWindowResize() {
				camera.aspect = window.innerWidth / window.innerHeight;
				camera.updateProjectionMatrix();
				renderer.setSize(window.innerWidth, window.innerHeight);
			}

			function onm ouseMove(event) {
				event.preventDefault();
				mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
				mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
			}

			function animate() {
				requestAnimationFrame(animate);
				controls.update();
				raycaster.setFromCamera(mouse, camera);
				const intersection = raycaster.intersectObject(mesh);

				if (intersection.length > 0) {
					const instanceId = intersection[0].instanceId;
					mesh.getColorAt(instanceId, color);
					if (color.equals(white)) {
						mesh.setColorAt(instanceId, color.setHex(Math.random() * 0xffffff));
						mesh.instanceColor.needsUpdate = true;
					}
				}
				render();
			}

			function render() {
				renderer.render(scene, camera);
			}
		</script>
	</body>
</html>
	

image

标签:threejs,const,camera,THREE,重复使用,InstancedMesh,window,mesh,new
From: https://www.cnblogs.com/zhuoss/p/17168681.html

相关文章