Three.js:更改一个网格的 material 会更改场景中的所有 material
Three.js: Changing material of one mesh changes all materials in scene
我正在尝试从数组中的三个 JS 中随机 select 我的场景中的网格,selecting 我的场景中的网格并编辑其属性,似乎影响整个场景,即它改变了所有网格的颜色,但是,我没有在这个例子中合并任何多边形。关于我对 select 一个随机的做错了什么的想法>?
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);
}
下面fiddle说明:
https://jsfiddle.net/60j5z9w3/
您会看到所有建筑物都会改变颜色,而我预计只有一个会改变。
问题源于您的 material
变量。您只对所有建筑物使用一个 material,因此当您更改其中一个的颜色时,您会更改所有建筑物的颜色。为清楚起见,这是您的代码的简化版本:
// 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 );
如果您打算单独更改每个网格,则需要为每个网格创建一个新的 material。
我正在尝试从数组中的三个 JS 中随机 select 我的场景中的网格,selecting 我的场景中的网格并编辑其属性,似乎影响整个场景,即它改变了所有网格的颜色,但是,我没有在这个例子中合并任何多边形。关于我对 select 一个随机的做错了什么的想法>?
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);
}
下面fiddle说明:
https://jsfiddle.net/60j5z9w3/
您会看到所有建筑物都会改变颜色,而我预计只有一个会改变。
问题源于您的 material
变量。您只对所有建筑物使用一个 material,因此当您更改其中一个的颜色时,您会更改所有建筑物的颜色。为清楚起见,这是您的代码的简化版本:
// 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 );
如果您打算单独更改每个网格,则需要为每个网格创建一个新的 material。