当前位置:网站首页>Three 之 three.js (webgl)模型的删除/场景的清空/内存的释放 的简单整理
Three 之 three.js (webgl)模型的删除/场景的清空/内存的释放 的简单整理
2022-04-23 05:17:00 【仙魁XAN】
Three 之 three.js (webgl)模型的删除/场景的清空/内存的释放 的简单整理
目录
Three 之 three.js (webgl)模型的删除/场景的清空/内存的释放 的简单整理
五、参考补充:Three.js 内存释放问题(如果不正确处理,可能并未释放,还会占用内存)
一、简单介绍
Three js 开发的一些知识整理,方便后期遇到类似的问题,能够及时查阅使用。
本节介绍, three.js (webgl)模型的删除/场景的清空/内存的释放 的简单整理,供大家一个优化思考的方向,如果有不足之处,欢迎指出,或者你有更好的方法,欢迎留言。
通过Threejs开发Web3D应用的时候,可能需要删除场景中的模型对象,如果想从一个场景
Scene或组对象Group删除一个三维模型对象,不仅仅只是.remove(),记得必要时还要·dispose()。在开发3D场景时,若遇到需要动态添加删改模型、场景,页面切换重渲染时,为避免内存叠加占用,需要手动清除场景所占用的内存,避免溢出与资源浪费。
二、实现原理
1、一般的模型记住,要对 geometry 和 material 进行 dispose(),在对 模型 mesh 进行 remove()
2、清空 scene 场景,释放内存,关键以下
- 使用 dispose() 清除所有网格模型几何体的顶点缓冲区占用内存
- 使用 object.clear() 销毁模型对象,清除页面内存
- 暂停 requestAnimationFrame() 方法,避免无意义运行
- 清空 canvas画布,置空dom与相关元素
三、场景中的模型 group (mesh)
1、删除场景对象中Scene一个子对象Group,并释放组对象Group中所有网格模型几何体的顶点缓冲区占用内存
deleteObject(group) {
// 递归遍历组对象group释放所有后代网格模型绑定几何体占用内存
group.traverse(function(obj) {
if (obj.type === 'Mesh') {
obj.geometry.dispose();
obj.material.dispose();
}
})
// 删除场景对象scene的子对象group
scene.remove(group);
}
2、另一种方法,清除Group
clearGroup(group) {
// 释放 几何体 和 材质
const clearCache = (item) => {
item.geometry.dispose();
item.material.dispose();
};
// 递归释放物体下的 几何体 和 材质
const removeObj = (obj) => {
let arr = obj.children.filter((x) => x);
arr.forEach((item) => {
if (item.children.length) {
removeObj(item);
} else {
clearCache(item);
item.clear();
}
});
obj.clear();
arr = null;
};
// 移除 group
removeObj(group);
}
记得:
1)如果是场景中
scene.remove(group); // 删除组
2)如果是 组中
groups.remove(group);// 删除模型
四、清空 scene 场景,释放内存
// 清空场景,包括 scene 场景下的动画,子物体,renderer,camera,control,以及自己使用过的变量置空处理 等
clearScene() {
cancelAnimationFrame(this.animationId);
this.scene.traverse((child) => {
if (child.material) {
child.material.dispose();
}
if (child.geometry) {
child.geometry.dispose();
}
child = null;
});
// 场景中的参数释放清理或者置空等
this.sceneDomElement.innerHTML = '';
this.renderer.forceContextLoss();
this.renderer.dispose();
this.scene.clear();
this.flows = [];
this.scene = null;
this.camera = null;
this.controls = null;
this.renderer.domElement = null;
this.renderer = null;
this.sceneDomElement = null;
console.log('clearScene');
}
五、参考补充:Three.js 内存释放问题(如果不正确处理,可能并未释放,还会占用内存)
参考博文:Three.js 内存释放问题
1、常规方法不能彻底清除掉scene场景内的一些geometry、texture等,而且就算页面离开也不会自动释放内存。打开任务管理器,可能看到CPU一直被占用,切换页面时越来越高。
//注意: 这里释放场景,并未处理必要的scene子物体的 geometry 、material 等
beforeDestroy() {
try {
scene.clear();
renderer.dispose();
renderer.forceContextLoss();
renderer.content = null;
cancelAnimationFrame(animationID) // 去除animationFrame
let gl = renderer.domElement.getContext("webgl");
gl && gl.getExtension("WEBGL_lose_context").loseContext();
}catch (e) {
console.log(e)
}
}
2、这边封装了一个track方法,来管理释放场景中的 mesh、geometry、texture、object3D、外部加载的obj模型、gltf模型等 的释放
1)TrackResource 方法:
import * as THREE from 'three/build/three.module'
export default class ResourceTracker {
constructor() {
this.resources = new Set();
}
track(resource) {
if (!resource) {
return resource;
}
// handle children and when material is an array of materials or
// uniform is array of textures
if (Array.isArray(resource)) {
resource.forEach(resource => this.track(resource));
return resource;
}
if (resource.dispose || resource instanceof THREE.Object3D) {
this.resources.add(resource);
}
if (resource instanceof THREE.Object3D) {
this.track(resource.geometry);
this.track(resource.material);
this.track(resource.children);
} else if (resource instanceof THREE.Material) {
// We have to check if there are any textures on the material
for (const value of Object.values(resource)) {
if (value instanceof THREE.Texture) {
this.track(value);
}
}
// We also have to check if any uniforms reference textures or arrays of textures
if (resource.uniforms) {
for (const value of Object.values(resource.uniforms)) {
if (value) {
const uniformValue = value.value;
if (uniformValue instanceof THREE.Texture ||
Array.isArray(uniformValue)) {
this.track(uniformValue);
}
}
}
}
}
return resource;
}
untrack(resource) {
this.resources.delete(resource);
}
dispose() {
for (const resource of this.resources) {
if (resource instanceof THREE.Object3D) {
if (resource.parent) {
resource.parent.remove(resource);
}
}
if (resource.dispose) {
resource.dispose();
}
}
this.resources.clear();
}
}
2)引入track,初始化
import ResourceTracker from "../../../common/3D/dispose";
// 在外层定义resMgr和track
let resMgr = new ResourceTracker();
const track = resMgr.track.bind(resMgr);
3)将所有的mesh、geometry、texture、object3D、外部加载的obj模型、gltf模型等等需要add to scene的物体,全部调用一下track方法
let xxx = track(new Three.Vector3());
obj.geometry.computeBoundingBox();
obj.geometry.boundingBox.getCenter(center);
let wrapper = track(new Three.Object3D());
wrapper.position.set(center.x,center.y,center.z);
obj.position.set(-center.x,-center.y,-center.z);
wrapper.add(obj);
scene.add(wrapper);
return warpper;
4)track到的3D物体内存释放
beforeDestroy() {
try {
scene.clear();
resMgr && resMgr.dispose()
renderer.dispose();
renderer.forceContextLoss();
renderer.content = null;
cancelAnimationFrame(animationID)
let gl = renderer.domElement.getContext("webgl");
gl && gl.getExtension("WEBGL_lose_context").loseContext();
console.log(renderer.info) //查看memery字段即可
}catch (e) {
console.log(e)
}
}
版权声明
本文为[仙魁XAN]所创,转载请带上原文链接,感谢
https://blog.csdn.net/u014361280/article/details/124309410
边栏推荐
- Deep learning notes - semantic segmentation and data sets
- Study notes: unity customsrp-11-post processing --- bloom
- 4 most common automated test challenges and Countermeasures
- 直播带货表格模板-自动显示图片-自动关联系列商品
- 数字化转型失败,有哪些原因?
- Top 25 Devops tools in 2021 (Part 2)
- Implementation of resnet-34 CNN with kears
- Unity C e-learning (IV)
- 机器学习---线性回归
- Grpc long connection keepalive
猜你喜欢

MySQL foreign key constraint

The introduction of lean management needs to achieve these nine points in advance

改进DevSecOps框架的 5 大关键技术

JSP -- Introduction to JSP

Graphics.FromImage报错“Graphics object cannot be created from an image that has an indexed pixel ...”

数字化转型失败,有哪些原因?

Blender程序化地形制作

工具在数字化转型中扮演了什么样的角色?

The WebService interface writes and publishes calls to the WebService interface (2)

MySQL 慢查询
随机推荐
Define defines constants and macros, pointers and structures
SQLyog的基本使用
Restful toolkit of idea plug-in
C#测试调用PaddleSharp模块识别图片文字
Redis lost key and bigkey
MySQL external connection, internal connection, self connection, natural connection, cross connection
改进DevSecOps框架的 5 大关键技术
Detailed explanation of hregionserver
Traversal of tree
2022年最热门的招聘技术技能是什么,您绝对想不到
Basic theory of Flink
C. Tree Infection(模拟+贪心)
青岛敏捷之旅,来了!
[untitled] kimpei kdboxpro's cool running lantern coexists with beauty and strength
引入精益管理方式,需要提前做到这九点
JS Array常见方法
云计算与云原生 — OpenShift 的架构设计
What are the reasons for the failure of digital transformation?
Data management of basic operation of mairadb database
《2021年IT行业项目管理调查报告》重磅发布!