详解光线投射与物体交互  
 
import  *  as  THREE  from  "three" ; 
import  {  OrbitControls }  from  "three/examples/jsm/controls/OrbitControls" ; 
import  gsap from  "gsap" ; 
import  *  as  dat from  "dat.gui" ; 
const  gui =  new  dat. GUI ( ) ; 
const  scene =  new  THREE. Scene ( ) ; 
const  camera =  new  THREE. PerspectiveCamera ( 
  75 , 
  window. innerWidth /  window. innerHeight, 
  0.1 , 
  300 
) ; 
const  textureLoader =  new  THREE. TextureLoader ( ) ; 
const  particlesTexture =  textureLoader. load ( "./textures/particles/1.png" ) ; 
camera. position. set ( 0 ,  0 ,  20 ) ; 
scene. add ( camera) ; 
const  cubeGeometry =  new  THREE. BoxBufferGeometry ( 1 ,  1 ,  1 ) ; 
const  material =  new  THREE. MeshBasicMaterial ( { 
  wireframe :  true , 
} ) ; 
const  redMaterial =  new  THREE. MeshBasicMaterial ( { 
  color :  "#ff0000" , 
} ) ; 
let  cubeArr =  [ ] ; 
for  ( let  i =  - 5 ;  i <  5 ;  i++ )  { 
  for  ( let  j =  - 5 ;  j <  5 ;  j++ )  { 
    for  ( let  z =  - 5 ;  z <  5 ;  z++ )  { 
      const  cube =  new  THREE. Mesh ( cubeGeometry,  material) ; 
      cube. position. set ( i,  j,  z) ; 
      scene. add ( cube) ; 
      cubeArr. push ( cube) ; 
    } 
  } 
} 
const  raycaster =  new  THREE. Raycaster ( ) ; 
const  mouse =  new  THREE. Vector2 ( ) ; 
window. addEventListener ( "click" ,  ( event )  =>  { 
  
  mouse. x =  ( event. clientX /  window. innerWidth)  *  2  -  1 ;  
  mouse. y =  - ( ( event. clientY /  window. innerHeight)  *  2  -  1 ) ; 
  raycaster. setFromCamera ( mouse,  camera) ; 
  let  result =  raycaster. intersectObjects ( cubeArr) ; 
  
  
  result. forEach ( ( item )  =>  { 
    item. object. material =  redMaterial; 
  } ) ; 
} ) ; 
const  renderer =  new  THREE. WebGLRenderer ( ) ; 
renderer. setSize ( window. innerWidth,  window. innerHeight) ; 
renderer. shadowMap. enabled =  true ; 
renderer. physicallyCorrectLights =  true ; 
document. body. appendChild ( renderer. domElement) ; 
const  controls =  new  OrbitControls ( camera,  renderer. domElement) ; 
controls. enableDamping =  true ; 
const  axesHelper =  new  THREE. AxesHelper ( 5 ) ; 
scene. add ( axesHelper) ; 
const  clock =  new  THREE. Clock ( ) ; 
function  render ( )  { 
  let  time =  clock. getElapsedTime ( ) ; 
  controls. update ( ) ; 
  renderer. render ( scene,  camera) ; 
  
  requestAnimationFrame ( render) ; 
} 
render ( ) ; 
window. addEventListener ( "resize" ,  ( )  =>  { 
  
  
  camera. aspect =  window. innerWidth /  window. innerHeight; 
  
  camera. updateProjectionMatrix ( ) ; 
  
  renderer. setSize ( window. innerWidth,  window. innerHeight) ; 
  
  renderer. setPixelRatio ( window. devicePixelRatio) ; 
} ) ;