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...

前面被其他博客误导了。

相关推荐
彼此不想说话1062473 天前
Vue + Three.js 实战:从零搭一座可交互 3D 世界(一)——世界由哪些零件构成
three.js
lerhxx14 天前
为什么你的Three.js物体总是乱转?一文彻底搞懂“万向锁”与四元数
前端·three.js
lerhxx15 天前
R3F 第一人称漫游与碰撞检测:Pointer Lock + 不穿墙的滑墙秘诀(中)
前端·javascript·three.js
xiaominlaopodaren15 天前
three.js地图视口瓦片(二):如何形成完整视口多边形
javascript·gis·three.js
lerhxx16 天前
我用 R3F 手搓了一个能走进去的 3D 迷宫简历(上):从选型架构到迷宫生成算法
前端·javascript·three.js
张人玉17 天前
基于 Python 机器学习 与 PyQt5 桌面框架开发的可视化分析系统——基于大数据的网上购物消费行为分析可视化大屏
python·qt·机器学习·echarts·three.js
xiaominlaopodaren17 天前
three.js地图视口瓦片(一):屏幕角点射线
javascript·gis·three.js
xiaominlaopodaren19 天前
three.js最小地图运行时(十):接入离线逻辑瓦片剖面
javascript·gis·three.js
xiaominlaopodaren20 天前
three.js最小地图运行时(九):TileKey 线框与 cursor 坐标探针
javascript·gis·three.js
像我这样帅的人丶你还20 天前
🚀苹果的液态玻璃咋做?🚀
前端·webgl·three.js