【3D】EffectComposer、OutlinePass特效引发的问题和卡顿

·  阅读 53

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情

给场景中的设备描边关键代码

import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer'

let composer = null
let outlinePassRing = null // 光圈

composer = new EffectComposer(renderer)
outlinePassRing = new OutlinePass(new THREE.Vector2(div3D.clientWidth, div3D.clientHeight), scene, camera)
let paramsRing = {
    edgeStrength: 3.0, // 强度
    edgeGlow: 1, // 边缘明暗度
    edgeThickness: 2.0, // 边缘雾化度
    pulsePeriod: 3, // 闪烁 值越大频率越低
    rotate: false,
    usePatternTexture: false // 是否使用皮肤
}
outlinePassRing.visibleEdgeColor.set('#ff0000')
outlinePassRing.edgeStrength = paramsRing.edgeStrength
outlinePassRing.edgeGlow = paramsRing.edgeGlow
outlinePassRing.pulsePeriod = paramsRing.pulsePeriod
outlinePassRing.edgeThickness = paramsRing.edgeThickness
outlinePassRing.renderToScreen = true
composer.addPass(outlinePassRing)

let dev = scene.getObjectByName(`设备名称`)
outlinePassRing.selectedObjects.push(dev) // 将当前设备描红色边框
复制代码

问题一:

重复放了同一个设备到outlinePassRing.selectedObjects,其内部组件会变得不可见。

console.log(dev.name, dev.children[0].name, dev.children[0].visible, i)
复制代码

打印内容如下:

  • 1#DLB Geometry.001_0 true 0
  • 2#DLB Geometry.002_0 true 1
  • 1#DLB Geometry.001_0 true 2
  • 1#QYB Geometry.002_0 true 3
  • 1#QYB Geometry.002_0 true 4

第一三个设备是相同的,第四五个设备是相同的。

继续将这些设备放入outlinePassRing.selectedObjects有:

for (let i = 0; i < outlinePassRing.selectedObjects.length; i++) {
    let newobj = outlinePassRing.selectedObjects[i]
    setTimeout(() => {
        console.log(newobj.name, newobj.children[0].name, newobj.children[0].visible, i)
    }, 3000)
}
复制代码

打印内容如下:

  • 1#DLB Geometry.001_0 undefined 0
  • 2#DLB Geometry.002_0 true 1
  • 1#DLB Geometry.001_0 undefined 2
  • 1#QYB Geometry.002_0 undefined 3
  • 1#QYB Geometry.002_0 undefined 4

原本都可见的子组件,现在都不可见了。所以去重很重要!!!

去重方法如下:

方法1:

let val = ['1#DLB', '2#DLB', '1#DLB', '1#QYB', '1#QYB']
let devArr = [...new Set(val)]
复制代码

方法2:

let val = ['1#DLB', '2#DLB', '1#DLB', '1#QYB', '1#QYB']
let devArr = []
for (let i = 0; i < val.length; i++) {
    let devStr = val[i]
    if (devArr.indexOf(devStr) === -1) {
        devArr.push(devStr)
    }
}
复制代码

问题二:

当CSS2DRenderer的文字渲染器和EffectComposer的特效渲染同时出现时,时不时卡到爆。

怀疑是场景中动态加载删除的对象清理不够彻底,参考他人所说的删除对象时要清除缓存,调用如下方法。

// 清除当前mesh对象的缓存
function clearCache (mesh) {
  if (mesh.type === 'Mesh') {
    mesh.geometry.dispose()
    mesh.material.dispose()
  } else if (mesh.children && mesh.children.length > 0) {
    for (let i = 0; i < mesh.children.length; i++) {
      clearCache(mesh.children[i])
    }
  }
}
复制代码

毛线用都没有,依旧时不时卡到爆!!!

发现只有改回renderer渲染不用composer就好了。

// 每一帧都重新渲染界面 去掉才能添加边框发光效果
renderer.render(scene, camera)
// 效果组合器渲染
// composer.render()
复制代码

这……

分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改