Memory leaks WebGL内存泄漏
我知道有很多关于内存泄漏的话题,但我尝试了解决方案,但仍然不起作用 我正在做这个 所以我有Memory leaks WebGL内存泄漏,memory-leaks,textures,webgl,three.js,Memory Leaks,Textures,Webgl,Three.js,我知道有很多关于内存泄漏的话题,但我尝试了解决方案,但仍然不起作用 我正在做这个 所以我有 materialPano=new THREE.MeshFaceMaterial( materials ); materialPano.needsUpdate=true; mesh = new THREE.Mesh( new THREE.CubeGeometry( 400, 400, 400, 7, 7, 7 ), materialPano ); 我正在添加一些功能,以便在单击按钮时更改纹理。 问题在于
materialPano=new THREE.MeshFaceMaterial( materials );
materialPano.needsUpdate=true;
mesh = new THREE.Mesh( new THREE.CubeGeometry( 400, 400, 400, 7, 7, 7 ), materialPano );
我正在添加一些功能,以便在单击按钮时更改纹理。
问题在于,以前的纹理不会被删除,并且在每个新纹理上使用的内存都会增加
因此,当我单击按钮时,它会执行一个函数,该函数执行以下操作:
materials = [loadTexture(myNewTexture1 ), loadTexture( myNewTexture2),loadTexture( myNewTexture3 ),loadTexture( myNewTexture4 ),loadTexture( myNewTexture5), loadTexture( myNewTexture6)];
myNewTexureK
是一个新的图像文件,它随按钮的变化而变化。我更新了网格材质
materialPano.materials=materials;
mesh.material=materialPano;
问题是我不知道如何删除上一个纹理。我尝试过很多类似的事情:
for(var k=0;k<materials.length;k++){
materials[k].deallocate();
scene.remove(materials[k]);
renderer.deallocateTexture(materials[k]);
renderer.deallocateMaterial(materials[k]);
renderer.deallocateObject(materials[k]);
delete materials[k];
materials[k]=null;
}
renderer.deallocateMaterial(materials);
renderer.deallocateObject(materials);
delete materials;
materials=null;
function loadTexture( path ) {
var texture = new THREE.Texture( texture_placeholder );
var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: true } );
var image = new Image();
image.onload = function () {
texture.needsUpdate = true;
material.map.image = this;
render();
};
image.src = path;
texture.deallocate();//new line
renderer.deallocateTexture( texture );//new line
return material;
}
但它不会删除任何内容!
在没有对进行任何修改的情况下,我注意到当我刷新页面时,内存也会增加,所以示例中存在内存泄漏
有没有办法真正删除纹理以避免内存泄漏
非常感谢
没有人有解决办法(
我编辑这封信是为了更准确。
我有:
当我点击按钮时,我会:
updateTexture(){
var materiales = [
loadTexture( 'new1.jpg' ),
loadTexture( 'new2.jpg'),
loadTexture( 'new3.jpg' ),
loadTexture( 'new4.jpg' ),
loadTexture( 'new5.jpg'),
loadTexture( 'new6.jpg' )
];
mesh.material=new THREE.MeshFaceMaterial( materiales );
}
问题是每次单击时内存都会增加。仅使用该代码,这是正常的,不会删除以前的mesh.material。但我尝试了很多方法,如:
mesh.deallocate(mesh.material);
mesh.geometry.deallocate(mesh.material);
scene.deallocate(mesh.material);
renderer.deallocateMaterial(mesh.material);
renderer.deallocateTexture(mesh.material);
renderer.deallocateObject(mesh.material);
scene.remove(mesh.material);
内存仍然在增加。我确定我使用的是Firefox v 17.0.1。Chrome上也出现了漏洞。尝试添加纹理。如果您使用的是r51-r53,请尝试添加纹理。如果您使用的是r51-r53,请尝试添加纹理 我从中添加了loadTexture函数,该按钮用于执行changeTexture()函数
<!DOCTYPE html>
<head>
<title>three.js webgl - equirectangular panorama demo</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
background-color: #000000;
margin: 0px;
overflow: hidden;
}
#info {
position: absolute;
top: 0px; width: 100%;
color: #ffffff;
padding: 5px;
font-family:Monospace;
font-size:13px;
font-weight: bold;
text-align:center;
}
a {
color: #ffffff;
}
</style>
</head>
<body>
<div id="container"></div>
<div id="info"><a href="http://threejs.org" target="_blank">three.js webgl</a> - equirectangular panorama demo. photo by <a href="http://www.flickr.com/photos/jonragnarsson/2294472375/" target="_blank">Jón Ragnarsson</a>.<input id="changeTexture" type="button" value="Memory leak test" onclick="changeTexture();"> </div>
<script src="./build/three.min.js"></script>
<script>
var idTexture='id1';
var camera, scene, renderer;
var fov = 70,
texture_placeholder,
isUserInteracting = false,
onMouseDownMouseX = 0, onMouseDownMouseY = 0,
lon = 0, onMouseDownLon = 0,
lat = 0, onMouseDownLat = 0,
phi = 0, theta = 0;
var materialsT, materialPano;
init();
animate();
function init() {
var container, mesh;
container = document.getElementById( 'container' );
camera = new THREE.PerspectiveCamera( fov, window.innerWidth / window.innerHeight, 1, 1100 );
camera.target = new THREE.Vector3( 0, 0, 0 );
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
//put here your 6 textures, one per face. Of course, you can use the same texture for all the faces
materialsT = [
loadTexture( idTexture+'.jpg' ),
loadTexture( idTexture+'.jpg' ),
loadTexture( idTexture+'.jpg' ),
loadTexture(idTexture+'.jpg' ),
loadTexture( idTexture+'.jpg' ),
loadTexture( idTexture+'.jpg' )
];
materialPano=new THREE.MeshFaceMaterial( materialsT );
mesh = new THREE.Mesh( new THREE.CubeGeometry( 256, 256, 256, 7, 7, 7 ),materialPano );
mesh.scale.x = -1;
scene.add( mesh );
container.appendChild( renderer.domElement );
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
document.addEventListener( 'mouseup', onDocumentMouseUp, false );
document.addEventListener( 'mousewheel', onDocumentMouseWheel, false );
document.addEventListener( 'DOMMouseScroll', onDocumentMouseWheel, false);
window.addEventListener( 'resize', onWindowResize, false );
}
function loadTexture( path ) {
var texture = new THREE.Texture( texture_placeholder );
var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: true } );
var image = new Image();
image.onload = function () {
texture.needsUpdate = true;
material.map.image = this;
render();
};
image.src = path;
texture.deallocate();
renderer.deallocateTexture( texture );
return material;
}
function changeTexture(){
idCourant=(idTexture=='id1')?'id2':'id1';
//you can use the same texture, there is still the memory leak
materialsT = [
loadTexture( idTexture+'.jpg' ),
loadTexture( idTexture+'.jpg'),
loadTexture( idTexture+'.jpg' ),
loadTexture( idTexture+'.jpg' ),
loadTexture( idTexture+'.jpg'),
loadTexture( idTexture+'.jpg' )
];
materialPano.materials=materialsT;//without this line, I don't have memory leak but I can't change the texture. So it means that loadTexture doesn't have memory leak since the memory doesn't increase when I click on the button with only materialsT=[loadTexture(...),...] in the changeTexture() function.
//I try with the following (put before materialPano.materials=materialsT; of course) to deallocate materialPano but it doesn't do anything
/*
renderer.deallocateTexture(materialPano.materials);
renderer.deallocateMaterial(materialPano.materials);
renderer.deallocateObject(materialPano.materials);
renderer.deallocateTexture(materialPano);
renderer.deallocateMaterial(materialPano);
renderer.deallocateObject(materialPano);
//*/
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentMouseDown( event ) {
event.preventDefault();
isUserInteracting = true;
onPointerDownPointerX = event.clientX;
onPointerDownPointerY = event.clientY;
onPointerDownLon = lon;
onPointerDownLat = lat;
}
function onDocumentMouseMove( event ) {
if ( isUserInteracting ) {
lon = ( onPointerDownPointerX - event.clientX ) * 0.1 + onPointerDownLon;
lat = ( event.clientY - onPointerDownPointerY ) * 0.1 + onPointerDownLat;
}
}
function onDocumentMouseUp( event ) {
isUserInteracting = false;
}
function onDocumentMouseWheel( event ) {
// WebKit
if ( event.wheelDeltaY ) {
fov -= event.wheelDeltaY * 0.05;
// Opera / Explorer 9
} else if ( event.wheelDelta ) {
fov -= event.wheelDelta * 0.05;
// Firefox
} else if ( event.detail ) {
fov += event.detail * 1.0;
}
camera.projectionMatrix.makePerspective( fov, window.innerWidth / window.innerHeight, 1, 1100 );
render();
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
lat = Math.max( - 85, Math.min( 85, lat ) );
phi = ( 90 - lat ) * Math.PI / 180;
theta = lon * Math.PI / 180;
camera.target.x = 500 * Math.sin( phi ) * Math.cos( theta );
camera.target.y = 500 * Math.cos( phi );
camera.target.z = 500 * Math.sin( phi ) * Math.sin( theta );
camera.lookAt( camera.target );
renderer.render( scene, camera );
}
</script>
</body>
three.js webgl-等矩形全景演示
身体{
背景色:#000000;
边际:0px;
溢出:隐藏;
}
#信息{
位置:绝对位置;
顶部:0px;宽度:100%;
颜色:#ffffff;
填充物:5px;
字体系列:Monospace;
字体大小:13px;
字体大小:粗体;
文本对齐:居中;
}
a{
颜色:#ffffff;
}
-等矩形全景演示。照片由。
var idTexture='id1';
摄像机、场景、渲染器;
var fov=70,
纹理占位符,
isUserInteracting=false,
onMouseDownMouseX=0,onMouseDownMouseY=0,
lon=0,onMouseDownLon=0,
lat=0,onMouseDownLat=0,
φ=0,θ=0;
var materialsT、materialPano;
init();
制作动画();
函数init(){
var容器,网状;
container=document.getElementById('container');
摄像机=新的三个透视摄像机(视野,视窗内宽/视窗内高,11100);
camera.target=新的三个矢量3(0,0,0);
场景=新的三个。场景();
renderer=new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth、window.innerHeight);
//把你的6个纹理放在这里,每个面一个。当然,你可以对所有的面使用相同的纹理
材料ST=[
loadTexture(idTexture+'.jpg'),
loadTexture(idTexture+'.jpg'),
loadTexture(idTexture+'.jpg'),
loadTexture(idTexture+'.jpg'),
loadTexture(idTexture+'.jpg'),
loadTexture(idTexture+'.jpg')
];
materialPano=新的三个网格面材料(materialsT);
网格=新三网格(新三网格体积法(256、256、256、7、7、7)、materialPano);
mesh.scale.x=-1;
场景。添加(网格);
container.appendChild(renderer.doElement);
文件。添加的文件列表('mousedown',onDocumentMouseDown,false);
document.addEventListener('mousemove',onDocumentMouseMove,false);
文件。添加的列表器('mouseup',onDocumentMouseUp,false);
文件。添加的文件列表器('mouseweel',OnDocumentMouseweel,false);
文档.添加的列表器('DOMMouseScroll',onDocumentMouseWheel,false);
addEventListener('resize',onWindowResize,false);
}
函数loadTexture(路径){
var纹理=新的三个纹理(纹理占位符);
var material=new THREE.MeshBasicMaterial({map:texture,overdraw:true});
var image=新图像();
image.onload=函数(){
texture.needsUpdate=true;
material.map.image=这个;
render();
};
image.src=路径;
texture.deallocate();
deallocateTexture(纹理);
退料;
}
函数changeTexture(){
idCourant=(idTexture='id1')?'id2':'id1';
//你可以使用相同的纹理,仍然存在内存泄漏
材料ST=[
loadTexture(idTexture+'.jpg'),
loadTexture(idTexture+'.jpg'),
loadTexture(idTexture+'.jpg'),
loadTexture(idTexture+'.jpg'),
loadTexture(idTexture+'.jpg'),
loadTexture(idTexture+'.jpg')
];
materialPano.materials=materialsT;//没有这一行,我没有内存泄漏,但我无法更改纹理。因此,这意味着loadTexture没有内存泄漏,因为当我在changeTexture()函数中仅使用materialsT=[loadTexture(…),…]单击按钮时,内存不会增加。
//我尝试使用以下方法(放在materialPano.materials=materialsT;当然)来释放materialPano,但它没有任何作用
/*
渲染器.deallocateTexture(materialPano.materials);
渲染器.deallocateMaterial(materialPano.materials);
renderer.deallocateObject(materialPano.materials);
渲染器.deallocateTexture(materialPano);
2.deallocateMaterial(materialPano);
deallocateObject(materialPano);
//*/
}
函数onWindowResize(){
camera.aspect=window.innerWidth/window.innerHeight;
camera.updateProjectMatrix();
renderer.setSize(window.innerWidth、window.innerHeight);
<!DOCTYPE html>
<head>
<title>three.js webgl - equirectangular panorama demo</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
background-color: #000000;
margin: 0px;
overflow: hidden;
}
#info {
position: absolute;
top: 0px; width: 100%;
color: #ffffff;
padding: 5px;
font-family:Monospace;
font-size:13px;
font-weight: bold;
text-align:center;
}
a {
color: #ffffff;
}
</style>
</head>
<body>
<div id="container"></div>
<div id="info"><a href="http://threejs.org" target="_blank">three.js webgl</a> - equirectangular panorama demo. photo by <a href="http://www.flickr.com/photos/jonragnarsson/2294472375/" target="_blank">Jón Ragnarsson</a>.<input id="changeTexture" type="button" value="Memory leak test" onclick="changeTexture();"> </div>
<script src="./build/three.min.js"></script>
<script>
var idTexture='id1';
var camera, scene, renderer;
var fov = 70,
texture_placeholder,
isUserInteracting = false,
onMouseDownMouseX = 0, onMouseDownMouseY = 0,
lon = 0, onMouseDownLon = 0,
lat = 0, onMouseDownLat = 0,
phi = 0, theta = 0;
var materialsT, materialPano;
init();
animate();
function init() {
var container, mesh;
container = document.getElementById( 'container' );
camera = new THREE.PerspectiveCamera( fov, window.innerWidth / window.innerHeight, 1, 1100 );
camera.target = new THREE.Vector3( 0, 0, 0 );
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
//put here your 6 textures, one per face. Of course, you can use the same texture for all the faces
materialsT = [
loadTexture( idTexture+'.jpg' ),
loadTexture( idTexture+'.jpg' ),
loadTexture( idTexture+'.jpg' ),
loadTexture(idTexture+'.jpg' ),
loadTexture( idTexture+'.jpg' ),
loadTexture( idTexture+'.jpg' )
];
materialPano=new THREE.MeshFaceMaterial( materialsT );
mesh = new THREE.Mesh( new THREE.CubeGeometry( 256, 256, 256, 7, 7, 7 ),materialPano );
mesh.scale.x = -1;
scene.add( mesh );
container.appendChild( renderer.domElement );
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
document.addEventListener( 'mouseup', onDocumentMouseUp, false );
document.addEventListener( 'mousewheel', onDocumentMouseWheel, false );
document.addEventListener( 'DOMMouseScroll', onDocumentMouseWheel, false);
window.addEventListener( 'resize', onWindowResize, false );
}
function loadTexture( path ) {
var texture = new THREE.Texture( texture_placeholder );
var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: true } );
var image = new Image();
image.onload = function () {
texture.needsUpdate = true;
material.map.image = this;
render();
};
image.src = path;
texture.deallocate();
renderer.deallocateTexture( texture );
return material;
}
function changeTexture(){
idCourant=(idTexture=='id1')?'id2':'id1';
//you can use the same texture, there is still the memory leak
materialsT = [
loadTexture( idTexture+'.jpg' ),
loadTexture( idTexture+'.jpg'),
loadTexture( idTexture+'.jpg' ),
loadTexture( idTexture+'.jpg' ),
loadTexture( idTexture+'.jpg'),
loadTexture( idTexture+'.jpg' )
];
materialPano.materials=materialsT;//without this line, I don't have memory leak but I can't change the texture. So it means that loadTexture doesn't have memory leak since the memory doesn't increase when I click on the button with only materialsT=[loadTexture(...),...] in the changeTexture() function.
//I try with the following (put before materialPano.materials=materialsT; of course) to deallocate materialPano but it doesn't do anything
/*
renderer.deallocateTexture(materialPano.materials);
renderer.deallocateMaterial(materialPano.materials);
renderer.deallocateObject(materialPano.materials);
renderer.deallocateTexture(materialPano);
renderer.deallocateMaterial(materialPano);
renderer.deallocateObject(materialPano);
//*/
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentMouseDown( event ) {
event.preventDefault();
isUserInteracting = true;
onPointerDownPointerX = event.clientX;
onPointerDownPointerY = event.clientY;
onPointerDownLon = lon;
onPointerDownLat = lat;
}
function onDocumentMouseMove( event ) {
if ( isUserInteracting ) {
lon = ( onPointerDownPointerX - event.clientX ) * 0.1 + onPointerDownLon;
lat = ( event.clientY - onPointerDownPointerY ) * 0.1 + onPointerDownLat;
}
}
function onDocumentMouseUp( event ) {
isUserInteracting = false;
}
function onDocumentMouseWheel( event ) {
// WebKit
if ( event.wheelDeltaY ) {
fov -= event.wheelDeltaY * 0.05;
// Opera / Explorer 9
} else if ( event.wheelDelta ) {
fov -= event.wheelDelta * 0.05;
// Firefox
} else if ( event.detail ) {
fov += event.detail * 1.0;
}
camera.projectionMatrix.makePerspective( fov, window.innerWidth / window.innerHeight, 1, 1100 );
render();
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
lat = Math.max( - 85, Math.min( 85, lat ) );
phi = ( 90 - lat ) * Math.PI / 180;
theta = lon * Math.PI / 180;
camera.target.x = 500 * Math.sin( phi ) * Math.cos( theta );
camera.target.y = 500 * Math.cos( phi );
camera.target.z = 500 * Math.sin( phi ) * Math.sin( theta );
camera.lookAt( camera.target );
renderer.render( scene, camera );
}
</script>
</body>
for(var k=0;k<materialsT.length;k++){
renderer.deallocateTexture(materialsT[k].map);
renderer.deallocateTexture(materialsT[k]);
materialsT[k].deallocate();
materialsT[k].map.deallocate();
}
texture.deallocate();
renderer.deallocateTexture( texture );