vue项目中,Threejs 点击模型,高亮发光模型外轮廓

效果如图,点击哪块,对应显示边框线,带呼吸灯
在这里插入图片描述
1、引入依赖

import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer"
import {RenderPass} from "three/examples/jsm/postprocessing/RenderPass"
import {OutlinePass} from "three/examples/jsm/postprocessing/OutlinePass"
import {ShaderPass} from "three/examples/jsm/postprocessing/ShaderPass"
import {FXAAShader} from "three/examples/jsm/shaders/FXAAShader"

2、定义数据

composer:null,
outlinePass:null,
renderPass:null,

3、vue文件中,
监听模型的点击事件this.renderer.domElement.addEventListener('click', this.modelMouseClick, false)
渲染 this.composer.render()
并根据点击的模块为模块添加光效this.outlineObj([intersects[0].object])

 // 最后的渲染
    render() {
      let animate = () => {
        //循环调用函数
        this.clearAnim = requestAnimationFrame(animate)
        //更新相机控件
        this.controls && this.controls.update()
        //渲染界面
        this.renderer.render(this.scene, this.camera)
        if(this.composer){
          this.composer.render()
        }
      }
      animate()
      //  为模型绑定点击事件
      this.renderer.domElement.addEventListener('click', this.modelMouseClick, false)
    },
// 模型的点击事件
modelMouseClick( event ) {
      let raycaster = new THREE.Raycaster();
      let mouse = new THREE.Vector2();
      // 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)
      mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
      mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
      raycaster.setFromCamera(mouse, this.camera);

      const intersects = raycaster.intersectObjects(this.scene.children);
      // 根据它来判断点击的什么,length为0即没有点击到模型
      console.log(intersects.length ? intersects[0].object.name : intersects, 'intersects----->>>')
      if(intersects.length){
        this.outlineObj([intersects[0].object])
      }
},

4、添加高亮发光模型外轮廓效果

//高亮显示模型(呼吸灯)
    outlineObj (selectedObjects) {
      // 创建一个EffectComposer(效果组合器)对象,然后在该对象上添加后期处理通道。
      this.composer = new EffectComposer(this.renderer)
      // 新建一个场景通道  为了覆盖到原理来的场景上
      this.renderPass = new RenderPass(this.scene, this.camera)
      this.composer.addPass(this.renderPass);
      // 物体边缘发光通道
      this.outlinePass = new OutlinePass(new THREE.Vector2(window.innerWidth, window.innerHeight), this.scene, this.camera, selectedObjects)
      this.outlinePass.selectedObjects = selectedObjects
      this.outlinePass.edgeStrength = 10.0 // 边框的亮度
      this.outlinePass.edgeGlow = 1// 光晕[0,1]
      this.outlinePass.usePatternTexture = false // 是否使用父级的材质
      this.outlinePass.edgeThickness = 1.0 // 边框宽度
      this.outlinePass.downSampleRatio = 1 // 边框弯曲度
      this.outlinePass.pulsePeriod = 5 // 呼吸闪烁的速度
      this.outlinePass.visibleEdgeColor.set(parseInt(0x00ff00)) // 呼吸显示的颜色
      this.outlinePass.hiddenEdgeColor = new THREE.Color(0, 0, 0) // 呼吸消失的颜色
      this.outlinePass.clear = true
      this.composer.addPass(this.outlinePass)
      // 自定义的着色器通道 作为参数
      let effectFXAA = new ShaderPass(FXAAShader)
      effectFXAA.uniforms.resolution.value.set(1 / window.innerWidth, 1 / window.innerHeight)
      effectFXAA.renderToScreen = true
      this.composer.addPass(effectFXAA)
    },

此文引用于文章gis开发,亲测可用

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
好的,以下是完整的代码: <template> <div> <div id="canvas-container"></div> </div> </template> <script> import * as THREE from 'three'; import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; export default { mounted() { this.init(); }, methods: { init() { // 创建场景 const scene = new THREE.Scene(); // 创建相机 const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, .1, 100); camera.position.z = 5; // 创建渲染器 const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.getElementById('canvas-container').appendChild(renderer.domElement); // 加载模型 const loader = new GLTFLoader(); loader.load('model.gltf', (gltf) => { scene.add(gltf.scene); }); // 创建光源 const light = new THREE.PointLight(xffffff, 1, 100); light.position.set(, , 10); scene.add(light); // 点击事件 const raycaster = new THREE.Raycaster(); const mouse = new THREE.Vector2(); const highlightColor = xff000; const defaultColor = xffffff; const onMouseMove = (event) => { mouse.x = (event.clientX / window.innerWidth) * 2 - 1; mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; }; const onClick = () => { raycaster.setFromCamera(mouse, camera); const intersects = raycaster.intersectObjects(scene.children, true); if (intersects.length > ) { intersects[].object.material.color.set(highlightColor); } }; window.addEventListener('mousemove', onMouseMove, false); window.addEventListener('click', onClick, false); // 渲染场景 const animate = () => { requestAnimationFrame(animate); renderer.render(scene, camera); }; animate(); }, }, }; </script>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值