Changing material type doesn't update on all meshes

When I change a material from MeshBasic to MeshPhong, the meshes in the scene don’t change.

here is an example where I create a material and assign it to variable material… then when I change it, the meshes don’t update with the new material.

I have many meshes in my scene (not the jsfiddle), as well as meshes that aren’t in the scene… How can I update all of them when the material is overwritten with the new one?

Need add list of meshes and then:

var camera, scene, renderer;
var geometry, material;
var mesh=[];
var material;

init();
animate();

function init() {

    camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10 );
    camera.position.z = 1;

    scene = new THREE.Scene();

    geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2 );
    material = new THREE.MeshNormalMaterial();
		
mesh.box_1 = new THREE.Mesh( geometry, material );
mesh.box_2 = new THREE.Mesh( geometry, material );
    scene.add( mesh.box_1 );
		 scene.add( mesh.box_2 );
		setTimeout( function() {
		
			var material_2 = new THREE.MeshBasicMaterial( { color: 0xffffff } );
var max=mesh.length;
for(var i in mesh){
if(mesh[i].material==material){ mesh[i].material=material_2; }
}
//scene.traverse(function(child){
//if(child.isMesh && child.material==material){ child.material=material_2; }
//});
material.dispose();
		}, 1000 );

    renderer = new THREE.WebGLRenderer( { antialias: true } );
    renderer.setSize( window.innerWidth, window.innerHeight );
    document.body.appendChild( renderer.domElement );

}

function animate() {

    requestAnimationFrame( animate );

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

    renderer.render( scene, camera );

}

Why can’t I just use one variable to hold the material, and change that one variable? Shouldn’t all meshes get updated when I change the material?

Maybe link (reference) to old material breaks then make new materail.

Because you are creating a new object. By doing so, any reference to original object becomes a deep copy of original object ( Not a reference anymore ).

But if you were to modify its properties, you get what you aimed for.

var camera, scene, renderer;
var geometry, material, mesh;

var material;

init();
animate();

function init() {

    camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10 );
    camera.position.z = 1;

    scene = new THREE.Scene();

    geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2 );
    material = new THREE.MeshNormalMaterial();
		
    mesh = new THREE.Mesh( geometry, material );
    scene.add( mesh );
		
		setTimeout( function() {
		
			material.wireframe = !0;
		
		}, 1000 );

    renderer = new THREE.WebGLRenderer( { antialias: true } );
    renderer.setSize( window.innerWidth, window.innerHeight );
    document.body.appendChild( renderer.domElement );

}

function animate() {

    requestAnimationFrame( animate );

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

    renderer.render( scene, camera );

}

@prominent Hello! Welcome to JavaScript. This is only due to a misunderstanding of how JavaScript works (no issue with Three.js).

After you make a new material, you need to give it to the mesh.

Here is your example, but one line added inside the setTimeout to give the material to the mesh:

1 Like