Squiggs.
Squiggs.

Reputation: 4474

Three.js: Changing material of one mesh changes all materials in scene

I'm trying to randomly select a mesh in my scene within THREE JS from an array, selecting what appears to be a Mesh within my scene and editing its properties, seems to affect the entire scene, i.e. it changes the colour of all the meshes, however, I haven't in this example merged any polygons. Any ideas on what I'm doing wrong to select a random one>?

var buildingObjs = [];

for ( var i = 0; i < 20; i ++ ) {
                var geometry = new THREE.BoxGeometry( 1, 1, 1 );
                geometry.applyMatrix( new THREE.Matrix4().makeTranslation( 0, 0.5, 0 ) );

                var building = new THREE.Mesh( geometry, material );
                var geo = new THREE.EdgesGeometry( building.geometry ); // or WireframeGeometry
                var mat = new THREE.LineBasicMaterial( { color: 0xcfcfcf } );
                var wireframe = new THREE.LineSegments( geo, mat );
                building.add( wireframe );

                var value = 1 - Math.random() * Math.random();
                var color = new THREE.Color().setRGB( value + Math.random() * 0.1, value, value + Math.random() * 0.1 );

                var top = color.clone().multiply( light );
                var bottom = color.clone().multiply( shadow );

                building.position.x = Math.floor( Math.random() * 200 - 100 ) * 10;
                building.position.z = Math.floor( Math.random() * 200 - 100 ) * 10;
                building.rotation.y = Math.random();
                building.scale.x = building.scale.z = Math.random() * Math.random() * Math.random() * Math.random() * 50 + 10;
                building.scale.y = ( Math.random() * Math.random() * Math.random() * building.scale.x ) * 8 + 8;

                buildingObjs.push(building);
                scene.add(building);
                
            }

function randomBuildingSelector()
        {
              
            var randomBuilding = buildingObjs[Math.floor(Math.random()*buildingObjs.length)];
            return randomBuilding;
        }

        function startAniLabels() {
            var selectedMesh = undefined;
            var tt = setInterval(function(){ 
                selectedMesh = randomBuildingSelector();
                console.log(selectedMesh);
                selectedMesh.material.color.setHex( 0x333333 );
             }, 5000);

            
        }

Below fiddle illustrates:

https://jsfiddle.net/60j5z9w3/

You'll see all buildings change colour, whereas I'm expecting only one to change.

Upvotes: 0

Views: 2077

Answers (1)

M -
M -

Reputation: 28497

The problem stems from your material variable. You're only using a single material for all buildings, so when you change the color of one, you change the color of all. This is a simplified version of your code for clarity:

// Create 1 material
var material = new THREE.MeshPhongMaterial();

for (var i = 0; i < 2000; i++) {
    var geometry = new THREE.BoxGeometry( 1, 1, 1 );
    // Use that same material on 2000 meshes
    var building = new THREE.Mesh( geometry, material );
}

// This is changing the color of the only material, 
// effectively changing the color of all meshes
buildingObjs[500].material.color.setHex( 0x333333 );

You would need to create a new material for each mesh if you're planning on changing them individually.

Upvotes: 1

Related Questions