射线投射器Raycaster通过.intersectObjects()判断模型是否选中 EffectComposer.js进行后期处理,添加描边高亮效果
< template> < div class = "app" > < div ref= "canvesRef" class = "canvas-wrap" > < / div> < / div>
< / template> < script setup>
import { ref, onMounted } from "vue" ;
import * as THREE from "three" ;
import { OrbitControls } from "three/addons/controls/OrbitControls.js" ;
import Stats from "three/addons/libs/stats.module.js" ;
import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js" ;
import { EffectComposer } from "three/addons/postprocessing/EffectComposer.js" ;
import { RenderPass } from "three/addons/postprocessing/RenderPass.js" ;
import { OutlinePass } from "three/addons/postprocessing/OutlinePass.js" ;
const canvesRef = ref ( null ) ;
const canvasWidth = window. innerWidth;
const canvasHeight = window. innerHeight;
let model = null ;
const scene = new THREE. Scene ( ) ;
const loader = new GLTFLoader ( ) ;
loader. load ( "../src/model/factory/工厂.gltf" , function ( gltf ) { console. log ( "控制台查看加载gltf文件返回的对象结构" , gltf) ; model = gltf; scene. add ( gltf. scene) ; } , function ( val ) { } , function ( err ) { console. log ( err) ; }
) ;
const camera = new THREE. PerspectiveCamera ( 75 , canvasWidth / canvasHeight, 0.1 , 3000
) ;
camera. position. set ( - 84 , 78 , 1.3 ) ;
camera. lookAt ( 0 , 0 , 0 ) ;
const pointLight = new THREE. PointLight ( 0xffffff , 1.0 ) ;
pointLight. decay = 0.0 ; pointLight. position. set ( - 100 , 190 , 110 ) ;
scene. add ( pointLight) ;
const axesHelper = new THREE. AxesHelper ( 200 ) ;
scene. add ( axesHelper) ;
const stats = new Stats ( ) ;
document. body. appendChild ( stats. domElement) ;
const renderer = new THREE. WebGLRenderer ( ) ;
renderer. setSize ( canvasWidth, canvasHeight) ;
const composer = new EffectComposer ( renderer) ;
const renderPass = new RenderPass ( scene, camera) ;
const outlinePass = new OutlinePass ( new THREE. Vector2 ( canvasWidth, canvasHeight) , scene, camera
) ;
composer. addPass ( renderPass) ;
composer. addPass ( outlinePass) ;
function animate ( ) { stats. update ( ) ; composer. render ( ) ; requestAnimationFrame ( animate) ;
}
animate ( ) ;
const cameraControls = new OrbitControls ( camera, renderer. domElement) ;
cameraControls. addEventListener ( "change" , function ( ) {
} ) ;
cameraControls. target. set ( 0 , 0 , 0 ) ;
cameraControls. maxPolarAngle = Math. PI / 2 ; onMounted ( ( ) => { canvesRef. value. appendChild ( renderer. domElement) ; renderer. domElement. addEventListener ( "click" , ( event ) => { console. log ( "模型点击" , model) ; const px = event. offsetX; const py = event. offsetY; const x = ( px / canvasWidth) * 2 - 1 ; const y = - ( py / canvasHeight) * 2 + 1 ; const raycaster = new THREE. Raycaster ( ) ; raycaster. setFromCamera ( new THREE. Vector2 ( x, y) , camera) ; const intersects = raycaster. intersectObjects ( model. scene. children) ; console. log ( "射线器返回的对象" , intersects) ; if ( intersects. length > 0 ) { outlinePass. selectedObjects = [ intersects[ 0 ] . object] ; } else { } } ) ;
} ) ;
< / script> < style lang= "scss" scoped>
. app { position : relative;
}
< / style>