threejs点击模型实现模型边缘高亮的选中效果--更改后提高帧率

先来个效果图

之前写的那个稍微有点问题,帧率只有30,参照官方代码修改后,帧率可以达到50了,在不全屏的状态下,帧率60


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;

2.添加EffectComposer效果组合器

js 复制代码
add_composer() {
  // 创建一个EffectComposer(效果组合器)对象,然后在该对象上添加后期处理通道。
  composer = new EffectComposer(renderer)
  // 新建一个场景通道  为了覆盖到原来的场景上
  renderPass = new RenderPass(scene, camera)
  composer.addPass(renderPass);
  // 物体边缘发光通道
  outlinePass = new OutlinePass(mouse, scene, camera)
  outlinePass.visibleEdgeColor.set(parseInt(0x00ff00)) // 呼吸显示的颜色
  outlinePass.hiddenEdgeColor = new THREE.Color(0, 0, 0) // 呼吸消失的颜色
  composer.addPass(outlinePass)

  // 解决高亮后环境变暗的问题
  const outputPass = new OutputPass();
  composer.addPass( outputPass );

  // 自定义的着色器通道 作为参数
  effectFXAA = new ShaderPass(FXAAShader)
  effectFXAA.uniforms[ 'resolution' ].value.set( 1 / window.innerWidth, 1 / window.innerHeight );
  composer.addPass(effectFXAA)

},
  • outlinePass = new OutlinePass(mouse, scene, camera)中的mouse就是 new THREE.Vector2( window.innerWidth, window.innerHeight ),可以直接用这个

把上面这个函数,在mounted的时候调用一下,初始化一次,后面想让哪个模型高亮,就传哪个模型进去

3.点击模型边缘高亮

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

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

我的self就是this。

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

如果你不想让这个模型边缘高亮了,那么outlinePass.selectedObjects = []; 这个数组里放哪个模型哪个模型边缘高亮,通过修改 outlinePass.selectedObjects 实现。

4.移除模型边缘高亮

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

js 复制代码
doubel_pick(event) {
  outlinePass.selectedObjects = [];
},

5.监听窗口变化

当窗口大小改变时,需要对应着改变渲染的大小

js 复制代码
// 随着窗体的变化修改场景
function onResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
  composer.setSize(window.innerWidth, window.innerHeight);
  effectFXAA.uniforms[ 'resolution' ].value.set( 1 / window.innerWidth, 1 / window.innerHeight );
}
// 监听窗体调整大小事件
window.addEventListener('resize', onResize, false);

6.循环渲染

js 复制代码
const animate = () => {
  stats.update();
  controls.update();
  //renderer.render(scene, camera);  不在需要renderer.render了
  composer.render(scene, camera)
  self.render_animation = requestAnimationFrame(animate);
};
animate()

这里需要注意的就是不要再添加renderer.render了,因为前面new EffectComposer的时候已经把renderer添加进去了,后面就是组合效果,只需要循环render后面这个composer就可以了,这是我的理解。

当然这也是造成之前帧率低的主要原因,循环渲染了,所以,删掉他,直接composer.render(scene, camera),帧率50,在不全屏的情况下,帧率60,基本满足需求。


附官方案例

案例:threejs.org/examples/?q...

源码:github.com/mrdoob/thre...

前面被其他博客误导了。

相关推荐
三天不学习6 小时前
一文讲透 Vue3 + Three.js 材质属性之皮革篇【扫盲篇】
javascript·webgl·three.js·材质
优雅永不过时·6 天前
实现一个漂亮的Three.js 扫光地面 圆形贴图扫光
前端·javascript·智慧城市·three.js·贴图·shader
3D虚拟工厂12 天前
1️⃣7️⃣three.js_OrbitControls相机控制器
javascript·3d·vue·blender·three.js·uv
3D虚拟工厂13 天前
OrbitControls
three.js
VcB之殇15 天前
three.js中使用canvas生成动态纹理贴图
javascript·three.js
Mintopia16 天前
Three.js 在数字孪生中的应用场景教学
前端·javascript·three.js
FanetheDivine16 天前
three.js学习笔记 2.光照和材质
react.js·three.js
雨夜带刀_17 天前
vue+three.js贴图-自定义贴图.仿写VANS定制功能(three.js+vue)
three.js
小桥风满袖17 天前
Three.js-硬要自学系列19 (曲线颜色渐变、渐变插值、查看设置gltf顶点、山脉高度可视化)
前端·css·three.js
Mintopia17 天前
# 使用 Three.js 实现带随机障碍物的小车行驶模拟
前端·javascript·three.js