🤔 需求
点击3d场景,获取点击中的对象。
😎 方案
光线投射Raycaster
Raycaster 光线投射用于进行鼠标拾取(在三维空间中计算出鼠标移过了什么物体)。
🌰 举个栗子
预期效果:点击3d场景中的绿色正方体,并将绿色正方体改成红色正方体
// 3d场景渲染一个正方体
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.getElementById("testContainer").appendChild(renderer.domElement);
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
camera.position.z = 5;
function animate() {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();
// 鼠标点击监听
const raycaster = new THREE.Raycaster(); // 初始化raycaster
const pointer = new THREE.Vector2(); // 鼠标的默认位置是一个二维向量
window.addEventListener("click", e => {
pointer.x = (e.clientX / window.innerWidth) * 2 - 1;
pointer.y = -(e.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(pointer, camera) // 计算出**相机照射到鼠标的光线**
const intersects = raycaster.intersectObjects(scene.children); //找到和射线相交的对象,返回数组(相交的物体不只有一个)
for (let i = 0; i < intersects.length; i++) {
intersects[i].object.material.color.set(0xff0000); //将正方体改成红色
}
});