three.js gpu占用极致优化
一、前言
公司项目新增了一个3d户型展示的区域,这块代码gpu占用七八百十上以上。因项目架构问题,算法计算也是本机计算,计算过程中,cpu占用100%!!!。这块是业务不能受到影响,3d如果无法优化,将无法上线。
二、分析
需要处理两处问题:
- 页面关闭或者切换场景时,清除场景,释放资源(geometry|material|texture dispose()), 这块不展开;
- 按需加载,模型加载完成。如果不操作不占用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 );
}