wmicn 2023-04-10 23:13 采纳率: 0%
浏览 34

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)


  • 写回答

1条回答 默认 最新

  • 阿里嘎多学长 2023-04-10 23:38
    关注

    以下内容部分参考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着色器材质,所以需要设置光源。而且,如果场景中有多个模型,需要将模型添加到场景中,并设置模型的名称,以便在交点计算时能够区分不同的模型。同时,可能需要在模型高亮时将其他模型的材质还原为原来的颜色。


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

    评论

报告相同问题?

问题事件

  • 创建了问题 4月10日

悬赏问题

  • ¥15 视频编码 十六进制问题
  • ¥15 Xsheii7我安装这个文件的时候跳出来另一个文件已锁定文件的无一部分进程无法访问。这个该怎么解决
  • ¥15 unity terrain打包后地形错位,跟建筑不在同一个位置,怎么办
  • ¥15 FileNotFoundError 解决方案
  • ¥15 uniapp实现如下图的图表功能
  • ¥15 u-subsection如何修改相邻两个节点样式
  • ¥30 vs2010开发 WFP(windows filtering platform)
  • ¥15 服务端控制goose报文控制块的发布问题
  • ¥15 学习指导与未来导向啊
  • ¥15 求多普勒频移瞬时表达式