Texture.dispose(); called but scene still rendered

I am using the most recent Three.JS, windows 8.1, firefox. I am creating a photo album.

When I add about 5000 photos to the scene I get a windows popup saying ‘PC low on Memory’ and fire fox closes. That happens at a little over 10Gig of texture loading. I was not surprised and intended to add texture.dispose() to the code at this point.

Before providing more details I want to mention an experiment I tried which had puzzling results. I loaded texture1 and in the next line of code I disposed of it. Then I loaded texture2 and immediately disposed of it. Then I created the geometry, the material, the mesh and added it to the scene. The result is that both textures rendered. I was expecting no textures to render. Did I not dispose correctly? Is there another needed step like an update? Here is the texture experiment code: ( it was originally posted by Mugen87 and I added the dispose lines )
camera = new THREE.PerspectiveCamera( 70, window.innerWidth/window.innerHeight, 0.01, 10 );
camera.position.z = 1;
scene = new THREE.Scene();

const loader = new THREE.TextureLoader();
const texture1 = loader.load( "../../../../../ImageDataBase/256/" + String(2+1)+".jpg");
texture1.dispose();
const texture2 = loader.load( "../../../../../ImageDataBase/256/" + String(3+1)+".jpg");
texture2.dispose();

const geometry = new THREE.BoxBufferGeometry( 0.4, 0.4, 0.4 );
material = new THREE.MeshBasicMaterial({ map: texture1});
mesh = new THREE.Mesh( geometry, material );
scene.add(mesh);
	
renderer = new THREE.WebGLRenderer({antialias:false});
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

setTimeout( () => {
	material.map = texture2;
	texture1.dispose();
}, 3000 ); // change the texture after three seconds
	
animate();		
	
function animate() {

	requestAnimationFrame( animate );

	mesh.rotation.x += 0.01;
	mesh.rotation.y += 0.02;

	renderer.render( scene, camera );

}

Now back to my code which crashes before loading 5000 photos. I did a test by modifying it to remove each photo immediately after it was added to the scene in an effort to avoid consuming all system memory resulting in a crash. Result: It still crashes. What is the proper way to free up the memory used by textures? Here is my texture loading / disposing loop which is crashing:

for ( let i=1;i<= 5000;i++)
{
	photofile= "../../../../../ImageDataBase/1024/" + String(i+1)+".jpg";
	const texture = loader.load(photofile);
	material = new THREE.MeshBasicMaterial({ map: texture});
	square = new THREE.Mesh( geometry, material );
	square.position.z=i/5000;
	scene.add(square);
	
	let index =scene.children.length -1
	let removeTarget = scene.children[index];
	scene.remove(removeTarget);            
	removeTarget.geometry.dispose();
	removeTarget.material.dispose();
	texture.dispose();
}

One more texture.dispose question which I could not find discussed on this forum nor stackoverflow. How can I dispose of one particular texture when I am loading multiple textures all with the same variable name ‘texture’? I had tried texture.children.length and a texture[index] with no luck. I see that texture has an .ID property so I am assuming that needs to be used to dispose of a particular texture.???
Thank you.

Yes. If you immediately call dispose() right after creating a material, geometry, texture etc. nothing will happen. The entities have to be used for rendering at least once so the respective WebGL entities have been created (buffers, shader programs, texture objects).

In other words, dispose() controls allocated memory on WebGL/GPU side. If you don’t allow the engine to allocate this memory first, freeing it will obviously have no effect.

1 Like