光线投射
光线投射用于进行鼠标拾取, 在三维空间中计算出鼠标移过了什么物体
文档: https://threejs.rocyuan.top/docs/?q=ray#api/zh/core/Raycaster
示例代码
完成一个示例, 三个立方体都为绿色, 点击哪个立方体, 就将其变为红色, 再次点击, 同样的逻辑, 将其他立方体变为绿色
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| <template> <div ref="threeContainer" class="three-container"></div> </template>
<script setup> import { onMounted, ref } from "vue"; import * as THREE from "three"; import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
const threeContainer = ref(null);
function init3D() { const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, threeContainer.value.clientWidth / threeContainer.value.clientHeight, 0.1, 1000); camera.position.z = 5; const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(threeContainer.value.clientWidth, threeContainer.value.clientHeight); threeContainer.value.appendChild(renderer.domElement);
new OrbitControls(camera, renderer.domElement);
function createCube(width = 1, height = 1, depth = 1) { const geometry = new THREE.BoxGeometry(width, height, depth); const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); return new THREE.Mesh(geometry, material); } const cube1 = createCube(); cube1.position.x = -2; const cube2 = createCube(); const cube3 = createCube(); cube3.position.x = 2; scene.add(cube1, cube2, cube3);
function cubeAllGreen() { cube1.material.color.set(0x00ff00); cube2.material.color.set(0x00ff00); cube3.material.color.set(0x00ff00); }
const raycaster = new THREE.Raycaster(); const mouse = new THREE.Vector2();
threeContainer.value.addEventListener("mousedown", (event) => { mouse.x = (event.clientX / threeContainer.value.clientWidth) * 2 - 1; mouse.y = -(event.clientY / threeContainer.value.clientHeight) * 2 + 1; raycaster.setFromCamera(mouse, camera); const intersects = raycaster.intersectObjects(scene.children); cubeAllGreen(); if (intersects.length > 0) { const currentClickMesh = intersects[0].object; currentClickMesh.material.color.set(0xff0000); } });
function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); } animate(); }
onMounted(() => { init3D(); }); </script>
<style scoped> .three-container { width: 100vw; height: calc(100vh - 20px); } </style>
|
效果
