Updating Material map?

Hi guys, I have been trying to load different images in a cube material, while is rendering (rotating cube) once in a while I want to update the textures with different images but these codes doesn’t make it change…
(I tried mesh.material.map.dispose() and tried to load new texture later but no difference)
–Is there a way to achieve this??

Codes inside render function:

mesh.material.map=THREE.ImageUtils.loadTexture( "Img/pic.jpg" );
mesh.material.needsUpdate = true;
1 Like

Hi!

Can you use THREE.TextureLoader() and the latest revision of the framework?
mesh.material.map = new THREE.TextureLoader().load( "Img/pic.jpg" );

1 Like

Full working example: Edit fiddle - JSFiddle - Code Playground

The texture is changed after three seconds. The old one is disposed.

1 Like

Thanks for your help, it works perfect, I have to go through my codes to see what I did wrong.

I modified a little your codes and my question is, which is the right way to free the memory?

let camera, scene, renderer, mesh;

init();
animate();

function init() {

    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();
		
    texture1 = loader.load( '//cdn.rawgit.com/mrdoob/three.js/master/examples/textures/brick_diffuse.jpg' );
    texture2 = loader.load( '//cdn.rawgit.com/mrdoob/three.js/master/examples/textures/floors/FloorsCheckerboard_S_Diffuse.jpg' );

    const geometry = new THREE.BoxBufferGeometry( 0.4, 0.4, 0.4 );
    const material = new THREE.MeshBasicMaterial( { map: texture2 } );

    mesh = new THREE.Mesh( geometry, material );
    scene.add( mesh );

    renderer = new THREE.WebGLRenderer( { antialias: true } );
    renderer.setPixelRatio( window.devicePixelRatio );
    renderer.setSize( window.innerWidth, window.innerHeight );
    document.body.appendChild( renderer.domElement );
    cm=true;
    setInterval( () => {
   
    // the idea is to use it to use a long photo collection (I will try with multi-texture for the cube)
    // which of these 2 ways is the right one to free memory??? I tried both and works.
   material.map.dispose(); // a
   // material.dispose();// b
		if(cm){
    
			material.map = loader.load( '//cdn.rawgit.com/mrdoob/three.js/master/examples/textures/floors/FloorsCheckerboard_S_Diffuse.jpg' );cm=false
		//	texture1.dispose();
    }else{
      material.map=loader.load( '//cdn.rawgit.com/mrdoob/three.js/master/examples/textures/brick_diffuse.jpg' );cm=true;
      }
      
		//material.map = texture1;
		}, 3000 ); // change the texture after three seconds

}

function animate() {

    requestAnimationFrame( animate );

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

    renderer.render( scene, camera );

}

You want to dispose the texture, not the material itself.

1 Like

Hello, sorry for poor english.

Something’s probably wrong with my code, trying to change object’s material’s map texture when the image is loaded
(earth is a permanent var)

Blockquote
eg=new THREE.Group();

    geometry = new THREE.SphereBufferGeometry( kl(R), 32, 32 );
 	var earthmaterial = new THREE.MeshPhongMaterial( {    
	wireframe: false, 
	} );

    earth=new THREE.Mesh( geometry, earthmaterial );

loader = new THREE.TextureLoader();

let img= 'https://2img.net/u/2517/29/39/28/album/center11.jpg';
loader.load(img,
	function(texture) {
	console.log(img + ' downloaded successfully');
	earth.material.map = texture;
	r.render( space, camera );
	}, undefined, function(err) {console.log('download unsuccessfull for '+img);}
);
	
eg.add(earth);
space.add(eg);

Well, while real time load and display is ok after some time for this texture, differed display does not show the uploaded texture. What’s wrong ?

Thanks a lot (did not find a place talking with callback texture load then update map)

Hello,

I found out that, when a texture is updated, we must notify it to three. As well, the materials having this texture must be notified too.
So i made my code work fine this way :

eg=new THREE.Group();

    geometry = new THREE.SphereBufferGeometry( kl(R), 32, 32 );
//let 'https://2img.net/u/2517/29/39/28/album/center11.jpg',
let earthTexture = loader.load('https://2img.net/u/2517/29/39/28/album/kgv6o310.jpg',
	function(texture) {
		console.log('load successful ' ) ;
		texture.needsUpdate=true;
		earthmaterial.needsUpdate=true;
		show(); // renderer.render
	},
	undefined,
	function(err) {
		console.log('error at loading');
	}
); 
earthTexture.offset.x = 0.25; 
earthTexture.wrapS=THREE.RepeatWrapping;earthmaterial = new THREE.MeshPhongMaterial( {   
	map: earthTexture });

earth=new THREE.Mesh( geometry, earthmaterial );
eg.add(earth);
space.add(eg);

;

Best regards,