Raycaster
- threejs鼠标响应机制 Raycaster射线投射器: 用来检测鼠标点击物体(射线检测是一条线,从相机发出,穿过屏幕,检测物体,可能是多个物体)
- 也就是说摄像机当眼睛与鼠标产生的直线就是所谓的射线投射器
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
let renderer, scene, camera, light, meshes;
let axesHelper;
let controls;
let amount = 6;
let count = Math.pow(amount, 3);
let color = new THREE.Color();
let white = new THREE.Color().setHex(0xffffff);
let raycaster = new THREE.Raycaster();
let mouse = new THREE.Vector2(1, 1);
scene = new THREE.Scene();
initRenderer();
initCamera();
initLight();
initAxesHelper();
initMeshes();
controls = new OrbitControls(camera, renderer.domElement);
render();
window.addEventListener("resize", () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
document.addEventListener("mousemove", (event) => {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
});
function initRenderer() {
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
function initCamera() {
camera = new THREE.PerspectiveCamera(
60,
window.innerWidth / window.innerHeight,
1,
1000
);
camera.position.set(10, 10, 10);
}
function initLight() {
light = new THREE.HemisphereLight(0xffffff, 0x888888);
light.position.set(0, 1, 0);
scene.add(light);
}
function initAxesHelper() {
axesHelper = new THREE.AxesHelper(3);
scene.add(axesHelper);
}
function initMeshes() {
const geometry = new THREE.IcosahedronGeometry(0.5, 2);
const meterial = new THREE.MeshPhongMaterial({ color: 0xffffff });
meshes = new THREE.InstancedMesh(geometry, meterial, count);
let index = 0;
const offset = (amount - 1) / 2;
const matrix = new THREE.Matrix4();
for (let i = 0; i < amount; i++) {
for (let j = 0; j < amount; j++) {
for (let k = 0; k < amount; k++) {
matrix.setPosition(offset - i, offset - j, offset - k);
meshes.setMatrixAt(index, matrix);
meshes.setColorAt(index, white);
index += 1;
}
}
}
scene.add(meshes);
}
function render() {
requestAnimationFrame(render);
raycaster.setFromCamera(mouse, camera);
const intersection = raycaster.intersectObject(meshes);
if (intersection.length > 0) {
const instanceId = intersection[0].instanceId;
meshes.getColorAt(instanceId, color);
if (color.equals(white)) {
meshes.setColorAt(instanceId, color.setHex(Math.random() * 0xffffff));
meshes.instanceColor.needsUpdate = true;
}
}
renderer.render(scene, camera);
}


总结
- 创建矩阵小球每个小球设置id
- 找到射线,找与球群相交的第一个元素
- 白色才设置随机色