vue环境下实现threejs选中高亮

模块化参照https://blog.csdn.net/weixin_42776111/article/details/127511552
想模块化实现鼠标选中模型高亮,但是失败了
下面高亮模块js

import * as THREE from 'three'
import {EffectComposer}  from "../../examples/jsm/postprocessing/EffectComposer.js";
import {RenderPass}  from "../../examples/jsm/postprocessing/RenderPass.js";
import  {OutlinePass} from "../../examples/jsm/postprocessing/OutlinePass.js";
import  {FXAAShader}  from "../../examples/jsm/shaders/FXAAShader.js";
import  {ShaderPass}  from "../../examples/jsm/postprocessing/ShaderPass.js";

export function  Tclick(renderer, scene, camera){
    var raycaster = new THREE.Raycaster();
    var mouse = new THREE.Vector2();
    
    renderer.domElement.style.touchAction = 'none';
    renderer.domElement.addEventListener( 'pointermove', onPointerMove );
  
    function onPointerMove(event) {
     
    var composer = new EffectComposer( renderer );

    var renderPass = new RenderPass( scene, camera );
    composer.addPass( renderPass );

    var v2 = new THREE.Vector2( window.innerWidth, window.innerHeight )
    var outlinePass = new OutlinePass( v2, scene, camera );
    outlinePass.edgeStrength = 5;//包围线浓度
    outlinePass.edgeGlow = 0.5;//边缘线范围
    outlinePass.edgeThickness = 2;//边缘线浓度
    outlinePass.pulsePeriod = 2;//包围线闪烁频率
    outlinePass.visibleEdgeColor.set( '#ffffff' );//包围线颜色
    outlinePass.hiddenEdgeColor.set( '#190a05' );//被遮挡的边界线颜色
    composer.addPass( outlinePass );
    
    var effectFXAA = new ShaderPass( FXAAShader );
    effectFXAA.uniforms[ 'resolution' ].value.set( 1 / window.innerWidth, 1 / window.innerHeight );
    composer.addPass( effectFXAA );

    console.log(composer)

    mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
    mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;

    raycaster.setFromCamera( mouse, camera );
    const intersects = raycaster.intersectObject( scene, true );
        

        if ( intersects.length > 0 ) {
            var selectedObjects = []
            const selectedObject = intersects[0].object;
            selectedObjects.push(selectedObject);
            outlinePass.selectedObjects = selectedObjects;
           return composer
        } else {
             outlinePass.selectedObjects = [];
        }
    
    }
}

 

下面是TEngie.js

//初始化渲染器、场景、相机以及灯光
import { WebGLRenderer, Scene,PerspectiveCamera,Vector2,AmbientLight, DirectionalLight,AxesHelper,Raycaster,MOUSE} from 'three'
import OrbitControls from 'three-orbitcontrols';
import {Tclick} from './Tclick'

export class TEngie{
    dom = null;
    scene = null; // 场景
   
    constructor(dom){
    // 创建渲染器
    var renderer = new WebGLRenderer({antialias: true}) //开启抗锯齿
    renderer.setClearColor('rgb(214, 234, 255)')//设置旋绕背景颜色,默认是黑色
    dom.appendChild(renderer.domElement)  // 将渲染器挂载到dom
    //渲染器大小和dom节点大小一致
    //设置渲染高度和宽度与窗口大小一致
    renderer.setSize(window.innerWidth, window.innerHeight)
    
    //场景
    var scene = new Scene() 

    //相机
    var camera = new PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000)  
    camera.position.set(400, 200, 400) // 设置相机位置
    // camera.lookAt(new Vector3(0, 0, 0))  // 设置相机看先中心点
    // camera.up = new Vector3(0, 0, 0)  // 设置相机自身的方向
    
    //鼠标
    let orbitControls = new OrbitControls(camera, renderer.domElement)
    //发光模块
   
    var composer =  Tclick(renderer, scene, camera)
    //console.log(composer)
    
    //自适应窗口
    window.addEventListener( 'resize', onWindowResize);
    function onWindowResize() {
      camera.aspect = window.innerWidth / window.innerHeight;
      camera.updateProjectionMatrix();
      renderer.setSize(window.innerWidth, window.innerHeight);
  }
  //渲染
  function animate (){
    renderer.render(scene, camera)  // 渲染器渲染场景和相机
    if(composer){
      composer.render();
    }
    requestAnimationFrame(animate);
}
animate() 
  this.dom = dom ;
  this.scene = scene;
  } 
  //添加不同内容函数:如模型、灯光 
   addObject(object) {
    object.forEach(elem => {
      this.scene.add(elem)
    })
  }
}


//设置灯光
export const allLights = []
// 添加环境光   自然光强度,0最低 1最强
export const ambientLight = new AmbientLight( 0x404040)
// 平行光
export const directionalLight = new DirectionalLight( 0xffffff);
allLights.push(ambientLight,directionalLight)


//设置辅助线
export const allHelper = []
// 坐标辅助
export const axesHelper = new AxesHelper(5000)  // 创建坐标辅助
allHelper.push(axesHelper)


以下内容部分参考ChatGPT模型:


首先,需要在vue组件中引入threejs库,然后在mounted钩子函数中初始化场景、相机、光源等对象。接着,需要监听鼠标移动事件,获取鼠标在场景中的坐标,然后计算与场景中所有模型的交点,找到最近的交点,并将对应的模型高亮。具体实现代码如下:

<template>
  <div ref="container"></div>
</template>

<script>
import * as THREE from 'three';

export default {
  mounted() {
    // 初始化场景、相机、光源等对象
    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
    const renderer = new THREE.WebGLRenderer({ antialias: true });
    const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
    const pointLight = new THREE.PointLight(0xffffff, 0.5);
    const geometry = new THREE.BoxGeometry();
    const material = new THREE.MeshPhongMaterial({ color: 0x00ff00 });
    const cube = new THREE.Mesh(geometry, material);
    scene.add(cube, ambientLight, pointLight);

    // 设置渲染器大小,并将渲染器添加到DOM中
    renderer.setSize(window.innerWidth, window.innerHeight);
    this.$refs.container.appendChild(renderer.domElement);

    // 监听鼠标移动事件
    renderer.domElement.addEventListener('mousemove', event => {
      const mouse = new THREE.Vector2(
        (event.clientX / window.innerWidth) * 2 - 1,
        -(event.clientY / window.innerHeight) * 2 + 1
      );
      const raycaster = new THREE.Raycaster();
      raycaster.setFromCamera(mouse, camera);
      const intersects = raycaster.intersectObjects(scene.children);
      if (intersects.length > 0) {
        const target = intersects[0].object;
        target.material.color.set(0xff0000);
      }
    });

    // 渲染场景
    function render() {
      requestAnimationFrame(render);
      cube.rotation.x += 0.01;
      cube.rotation.y += 0.01;
      renderer.render(scene, camera);
    }
    render();
  }
};
</script>

需要注意的是,这里使用了Phong着色器材质,所以需要设置光源。而且,如果场景中有多个模型,需要将模型添加到场景中,并设置模型的名称,以便在交点计算时能够区分不同的模型。同时,可能需要在模型高亮时将其他模型的材质还原为原来的颜色。


如果我的建议对您有帮助、请点击采纳、祝您生活愉快