使用原生THREEJS无法动态高亮

发布于 2024-07-07 16:13:30
<template>
  <primitive :object="model" :rotation-z="Math.PI / 6" />
</template>

<script setup>
import { watchEffect, ref } from 'vue'
import * as THREE from 'three'
import { useFBX } from '@tresjs/cientos'
import { useTresContext, useRenderLoop } from '@tresjs/core'
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass'
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer'
import { OutlinePass } from "three/examples/jsm/postprocessing/OutlinePass.js"

// import { Outlines } from '@pmndrs/vanilla'
const path = './plugins/JD/model/Xin_Dian_C.fbx'
const model = await useFBX(path)

const { scene, renderer, camera, sizes } = useTresContext()
var selectedObjects = []
let effectComposer = null
let outlinePass = null
let renderScene = null

// 创建发光类
const outlinePassEffect = (scene, camera, renderer, width, height) => {

  // 渲染器通道,将场景全部加入渲染器
  renderScene = new RenderPass(scene, camera)
  outlinePass = new OutlinePass(new THREE.Vector2(width, height), scene, camera)
  outlinePass.selectedObjects = []
  outlinePass.edgeStrength = 10.0 // 边框的亮度
  outlinePass.edgeGlow = 1// 光晕[0,1]
  outlinePass.usePatternTexture = false // 是否使用父级的材质
  outlinePass.edgeThickness = 1.0 // 边框宽度
  outlinePass.downSampleRatio = 1 // 边框弯曲度
  outlinePass.pulsePeriod = 5 // 呼吸闪烁的速度
  outlinePass.visibleEdgeColor.set(parseInt(0x00ff00)) // 呼吸显示的颜色
  outlinePass.hiddenEdgeColor = new THREE.Color(0, 0, 0) // 呼吸消失的颜色
  // outlinePass.clear = true
  // 创建合成器
  effectComposer = new EffectComposer(renderer)
  // 将渲染器和场景结合到合成器中
  effectComposer.addPass(renderScene)
  effectComposer.addPass(outlinePass)
}


watchEffect(() => {
  // 等拿到上下文对象后初始化后处理 通道
  if (sizes.width.value) {
    outlinePassEffect(scene.value, camera.value, renderer.value, sizes.width.value, sizes.height.value)
  }
})


//监听点击事件
window.addEventListener('click', (event) => {
  const raycaster = new THREE.Raycaster()
  const mouse = new THREE.Vector2()
  mouse.x = (event.clientX / window.innerWidth) * 2 - 1
  mouse.y = - (event.clientY / window.innerHeight) * 2 + 1
  raycaster.setFromCamera(mouse, camera.value);
  var intersects = raycaster.intersectObjects(model.children, true);
  // //当intersects.length > 0说明碰点击到物体(可能为多个重合的物体),获取最近的物体名称进行判断
  if (intersects.length > 0) {
    const mesh = intersects[0].object
    outlinePass.selectedObjects = [mesh]
  }

});

const { onLoop } = useRenderLoop()

onLoop(() => {
  if (effectComposer && camera.value) {
    effectComposer.render()
    renderer.value.render(scene.value, camera.value)

  }
})

</script>

查看更多

关注者
0
被浏览
91
1 个回答
Jsonco
Jsonco 图形社区官方人员 2024-07-07
奔驰的蜗牛

这个问题我也顺便回答一下,我也在使用的时候遇到过类似的问题,我当时解决办法是求出mesh的包围盒,去高亮的包围盒。这个方法其实没有从技术解决,只是从业务上进行改变,但是我个人感觉效果比几何体的outline还好一些。image.png

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览