three.js gpu占用优化

2,579 阅读1分钟

three.js gpu占用极致优化

一、前言

公司项目新增了一个3d户型展示的区域,这块代码gpu占用七八百十上以上。因项目架构问题,算法计算也是本机计算,计算过程中,cpu占用100%!!!。这块是业务不能受到影响,3d如果无法优化,将无法上线。

二、分析

需要处理两处问题:

  1. 页面关闭或者切换场景时,清除场景,释放资源(geometry|material|texture dispose()), 这块不展开;
  2. 按需加载,模型加载完成。如果不操作不占用gpu内存。
// 这块代码,就是内存占用的问题
function render() {
    controls.update();
    renderer.render( scene, camera );
    requestAnimationFrame( render );
}

1、这个模块使用的是OrbitControls.js,可以通过监听change时间来判断。
2、还有就是每次材质和纹理更新,触发重新渲。

三、实现

原代码量比较大,单独文件处理这块逻辑

// 1. renderHelper.js
export default class renderHelper {
  constructor(controls, THREE, render) {
    this.controls = controls;
    this.render = render;
    this.requestId = null;

    // 增加某种惯性, 让整个画面显得不那么僵硬
    controls.enableDamping = true;
    // 每次材质和纹理更新,触发重新渲
    const callbackFun = this.requestRenderIfNotRequested.bind(this);
    THREE.DefaultLoadingManager.onLoad = callbackFun;
    // 各种事件监听
    controls.addEventListener('change', callbackFun);
    window.addEventListener('click', callbackFun);
    window.addEventListener('resize', callbackFun);
    
    this.renderRequested = false;
  }

  requestRenderIfNotRequested() {
    if (!this.renderRequested) {
      this.renderRequested = true;
      this.requestId = window.requestAnimationFrame(this.render);
    }
  }

  cancelAnimation() {
    this.requestId && window.cancelAnimationFrame(this.requestId);
  }

  throttle(fn, wait = 16.7) {
    let previous = 0;
    return function (...args) {
      let now = +new Date();
      if (now - previous > wait || !previous) {
        previous = now;
        fn.apply(this, args);
      }
    };
  };

}

// 2. index.js
import renderHelper from './renderHelper.js';
let renderHelperInstance = new renderHelper(controls, THREE, render);
// 改造render函数
function render() {
    if (!renderHelperInstance.renderRequested) return;
    renderHelperInstance.renderRequested = false;
    controls.update();
    renderer.render( scene, camera );
// 	requestAnimationFrame( render );
}

四、总结

多看文档rendering-on-demand按需渲染