threejs点击模型实现模型边缘高亮的选中效果

先来个效果图


1.首先需要导入库

js 复制代码
// 用于模型边缘高亮
import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer.js"
import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass.js"
import { OutlinePass } from "three/examples/jsm/postprocessing/OutlinePass.js"
import { ShaderPass } from "three/examples/jsm/postprocessing/ShaderPass.js"
import { FXAAShader } from "three/examples/jsm/shaders/FXAAShader.js"
import { SMAAPass } from "three/examples/jsm/postprocessing/SMAAPass.js"
import { UnrealBloomPass } from "three/examples/jsm/postprocessing/UnrealBloomPass.js"

然后需要注意,我这里使用的是vue的框架,但是对于变量的定义我用的是全局的定义。

js 复制代码
// 模型边缘高光
let composer;
let outlinePass;
let renderPass;
let effectFXAA;
let smaaPass;
let unrealBloomPass;

2.定义一个模型边缘高亮的函数

js 复制代码
outlineObj (selectedObjects) {
  // 创建一个EffectComposer(效果组合器)对象,然后在该对象上添加后期处理通道。
  // 用于模型边缘高亮
  composer = new EffectComposer(renderer)
  composer.renderTarget1.texture.outputColorSpace = THREE.sRGBEncoding;
  composer.renderTarget2.texture.outputColorSpace = THREE.sRGBEncoding;
  composer.renderTarget1.texture.encoding = THREE.sRGBEncoding;
  composer.renderTarget2.texture.encoding = THREE.sRGBEncoding;

  // 新建一个场景通道  为了覆盖到原来的场景上
  renderPass = new RenderPass(scene, camera)
  composer.addPass(renderPass);
  // 物体边缘发光通道
  outlinePass = new OutlinePass(new THREE.Vector2(window.innerWidth, window.innerHeight), scene, camera, selectedObjects)
  outlinePass.selectedObjects = selectedObjects
  outlinePass.edgeStrength = 10.0 // 边框的亮度
  outlinePass.edgeGlow = 0.5// 光晕[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
  composer.addPass(outlinePass)
  // 自定义的着色器通道 作为参数
  effectFXAA = new ShaderPass(FXAAShader)
  effectFXAA.uniforms.resolution.value.set(1 / window.innerWidth, 1 / window.innerHeight)
  effectFXAA.renderToScreen = true
  composer.addPass(effectFXAA)
  // 抗锯齿
  smaaPass = new SMAAPass();
  composer.addPass(smaaPass);
  // 发光效果
  unrealBloomPass = new UnrealBloomPass();
  unrealBloomPass.strength = 0.1;
  // unrealBloomPass.radius = 0;
  unrealBloomPass.threshold = 1;
  composer.addPass(unrealBloomPass);
},

这段代码的运行,会导致变卡,帧率会从60降低到23在我的环境中,所以,可以根据实际需求对代码进行删减优化。

3.点击模型边缘高亮

现在就需要在点击模型的事件中去调用这个函数

js 复制代码
// 点击模型事件
pick(event) {
  const found = self.cast(event)[0];
  if (found) {
    // [transformer]是给变压器加,[transformer,car]是给变压器和房子加,子模型要.object
    if(composer){
      composer = null;
    }
    self.outlineObj([found.object])
  }
},

我的self就是this。

我想要实现的是子模型的高亮,所以我要取子模型的object,其次需要注意的就是传入的参数是个数组,你传入哪些模型,点击的时候,那些模型就会一起高亮,我这里传入的是一个,是选中的子模型。

还有就是要注意我在每次点击前都清空了下composer,也许不需要,但是以防万一。

4.移除模型边缘高亮

当不想要高亮的时候,把composer赋值为空就可以了。

js 复制代码
doubel_pick(event) {
  composer = null;
},

5.循环渲染

js 复制代码
const animate = () => {
  stats.update();
  controls.update();
  renderer.render(scene, camera);
  if(composer) {
    composer.render(scene, camera)
  }
  self.render_animation = requestAnimationFrame(animate);
};
animate()

在renderer.render(scene, camera);后面添加composer的render

相关推荐
郝学胜-神的一滴5 天前
中级OpenGL教程 005:为球体&平面注入法线灵魂
c++·unity·图形渲染·three.js·opengl·unreal
我胖虎不答应!!5 天前
Three.js开发思想笔记
javascript·笔记·three.js
白鳯8 天前
塔罗神谕:星月神域莱诺薇为您占卜
react·web·three.js·codex·deepseek·vibe coding·塔罗占卜
李剑一11 天前
耗时 2 小时!我复刻了全网超火的通透 3D 水晶球动效,Vue3+Three.js 做出高级视觉特效
前端·three.js
时光足迹12 天前
ThreeJS之GUI控制器
前端·javascript·three.js
李剑一13 天前
别再写死静态文字了!Vue3+Three.js 实现超酷3D流光旋转文字科技感拉满!【附完整源码】
three.js
爱看书的小沐13 天前
【小沐学WebGIS】基于Cesium.JS与jsbsim联动三维飞行仿真(OpenGL、Cesium.js、Three.js)
c++·qt·three.js·opengl·cesium·jsbsim
爱看书的小沐15 天前
【小沐杂货铺】基于Three.js绘制三维艺术画廊3DArtGallery (Three.js,WebGL)
javascript·3d·webgl·three.js·babylon.js·三维画廊
郝学胜-神的一滴15 天前
[简化版 GAMES 101] 计算机图形学 07:图形学投影完全推导
c++·unity·图形渲染·three.js·unreal engine
CAE虚拟与现实16 天前
五一假期闲来无事,来个前段、后端的说明吧
前端·后端·vtk·three.js·前后端