Three.js 性能优化总结 持续更新中

Three.js 性能优化总结

  • 数据优化篇

BIM模型, 3D大模型,先导出为GLTF格式, 然后GLTF格式,调用draco压缩算法,产生后缀为.drc文件。然后参考官网去解压.drc 文件就可以提高加载速度了

Draco 加载例子:

https://storage.googleapis.com/demos.webmproject.org/draco/draco_loader_throw.html

Github 例子

https://github.com/google/draco

 

Key point

1、try to use clone method in three.js
2、dispose is necessary, when objects are removed
3、Using BufferGeometry instead of others
4、pay attention to zip image files
5、Optiomize related functions within the method "requestAnimationFrame" (Senario 1:);
6、For external big models (big size),combine gltf-pipeline Draco tools to lightweigh size of models(Senario 2)。


Senario 1: related animate behavior:

let renderEnabled = false;
const animate = () => {
    requestAnimationFrame(animate);
    // 设置一个变量 减少没用的执行
    if (renderEnabled) {
      // 这里是你自己业务上需要的code
      controls.update(clock.getDelta());
      renderer.render(scene, camera);
    }
    stats.update();
  };
// 需要渲染的时候调用一下即可
const timeRender = (time: number = 3000) => {
  renderEnabled = true;
  raf.clearTimeout(timeOut);
  timeOut = raf.setTimeout(() => {
    renderEnabled = false;
  }, time);
};

Senario 2: Here are for Vue project.

At first, please suggest using gltf file to load models because Glft is very good to zip the images files

  • import dracoLoader class
    import {DRACOLoader} from "three/examples/jsm/loaders/DRACOLoader";

    Copy all related gltf folder ( three/examples/js/libs/draco in node_module) into public folder 

  • install gltf-pipeline in your node project 
npm i gltf-pipeline -g
  • execute command line to zip gltf file as below:
    gltf-pipeline -i xx.gltf -o xxDraco.gltf -d
 const manager = new LoadingManager()
      const loader = new GLTFLoader()

      const dracoLoader = new DRACOLoader(manager)
      dracoLoader.setDecoderPath('/draco/gltf/')
      dracoLoader.setDecoderConfig({type: 'js'})
      dracoLoader.preload()
      loader.setDRACOLoader(dracoLoader);

      loader.load(
        this.url,
        (gltf) => {

          var ambientLight = new AmbientLight(0xffffff);
          gltf.scene.add(ambientLight)
          console.log(gltf.scene)
          this.projectName = gltf.scene.name
          this.scene.add(gltf.scene)
          this.objects = []

          gltf.scene.children.forEach(e => {
            if (e instanceof Group) {
              var mats = []
              var geos = []
              var startIndex = 0
              var groups = []
              var i = 0
              for (const mesh of e.children) {
                if (mesh instanceof Mesh) {
                  geos.push(mesh.geometry);
                  groups.push({
                    start: startIndex,
                    count: mesh.geometry.index.count,
                    materialIndex: i
                  });
                  i++;
                  startIndex += mesh.geometry.index.count;
                  mats.push(mesh.material);
                }
              }
              var geometry = BufferGeometryUtils.mergeBufferGeometries([...geos])
              groups.forEach(item => {
                geometry.addGroup(item.start, item.count, item.materialIndex)
              })
              var newMesh = new Mesh(geometry, mats)
              newMesh.name = e.name
              this.objects.push(newMesh)
            } else if (e instanceof Mesh) {
              this.objects.push(e)
            }
          });
          this.scene.add(...this.objects)
          this._initViewPoint(gltf.scene)

          this._initBimInfo()
        }
      );

      this._initLoadingManager(manager)

Loader manager method

  _initLoadingManager(manager) {
    manager.onError = () => {
      this.loading = false
      this.flag = false
    }

    manager.onProgress = (url, loaded, total) => {
      this.loadPercent = loaded * 1.0 * 100 / total
    }

    manager.onLoad = () => {
      this.loading = false
      this.flag = false
      console.log("loading completed!")
    }

    manager.onStart = (url, loaded, total) => {
      this.loading = true
      this.flag = true
      this.loadPercent = loaded * 1.0 * 100 / total
    }
  }

ThreeJS WebGLRenderer参数优化:

    this.renderer = new WebGLRenderer({
      antialias: true,
      logarithmicDepthBuffer: true,
      precision: 'lowp',
      preserveDrawingBuffer: true,
      autoClear: true
    })

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值