跳到主要内容

光线投射

光线投射可以理解为在 Canvas 上发射一条射线,这条射线会与场景中的 3D 物体相交,然后返回相交的物体信息。

先创建三个球体:

// 创建三个不同颜色的球体
const sphereGeometry = new THREE.SphereGeometry(1, 32, 32) // 复用几何体
const spheres = [
{ color: 0x00ff00, position: -3 }, // 左侧绿色
{ color: 0x0000ff, position: 0 }, // 中间蓝色
{ color: 0xff0000, position: 3 } // 右侧红色
].map(({ color, position }) => {
const material = new THREE.MeshBasicMaterial({ color })
const sphere = new THREE.Mesh(sphereGeometry, material)
sphere.position.x = position
scene.add(sphere)
return sphere
})

当鼠标点击时,改变球体的颜色

window.addEventListener('click', (event) => {
// 将鼠标位置归一化为设备坐标
mouse.x = (event.clientX / window.innerWidth) * 2 - 1
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1
raycaster.setFromCamera(mouse, camera)
const intersects = raycaster.intersectObjects(spheres)

if (intersects.length > 0) {
for (const intersect of intersects) {
const sphere = intersect.object as THREE.Mesh
const material = sphere.material as THREE.MeshBasicMaterial

if (material._isSelected) {
material.color.set(material._originalColor)
material._isSelected = false
} else {
// 保存原始颜色
const originalColor = material.color.clone()
material._originalColor = originalColor
material.color.set(0x000000)
// 保存选中状态
material._isSelected = true
}
}
}
})

注意这里对坐标进行了归一化处理,将鼠标位置归一化为设备坐标,这个坐标叫做 NDC(Normalized Device Coordinates),它是一个将 3D 坐标系转换到 2D 坐标系的坐标系,它的范围是 -1 到 1:

NDC

本节示例代码:https://github.com/wukaipeng-dev/threejs-demo/blob/main/02-basic/src/main-raycasting.ts