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

前面被其他博客误导了。

相关推荐
格瑞@_@7 天前
11.Three.js使用indexeddb前端缓存模型优化前端加载效率
前端·javascript·缓存·three.js·indexeddb缓存
谢小飞7 天前
我做了三把椅子原来纹理这样加载切换
前端·three.js
小白菜学前端7 天前
ThreeJS创建一个3D物体的基本流程
3d·three.js
茶老翁8 天前
1-初识Three.js
前端·three.js
莫石10 天前
搓绳子(直)
前端·数学·three.js
小白菜学前端10 天前
3d 添加辅助坐标器和轨道控制器
3d·three.js
孙_华鹏12 天前
threejs——实战中材质的应用
前端·three.js·数据可视化
天涯学馆15 天前
Three.js灯光阴影与动画交互
前端·unity3d·three.js
格瑞@_@19 天前
6.Three.js贴图与uv映射(uv坐标)理解和实践
javascript·three.js·贴图·uv
入秋丶1 个月前
threejs - 包围盒和包围球
three.js