Changing material color on a merged mesh with three js

纵饮孤独 提交于 2019-12-11 02:37:18

问题


Is that possible to interact with the buffer used when merging multiple mesh for changing color on the selected individual mesh ?

It's easy to do such thing with a collection of mesh but what about a merged mesh with multiple different material ?


回答1:


Depends on what you mean with "changing colors". Note that after merging, the mesh is like any other non-merged mesh.

If you mean vertex colors, it would be possibly to iterate over the faces and determine the vertices which color to change based on the material index.

If you mean setting a color to the material itself, sure it's possible. Merged meshes can still have multiple materials the same way ordinary meshes do - in MeshFaceMaterial, though if you are merging yourself, you need to pass in a material index offset parameter for each geometry.




回答2:


@hgates, your last comment was very helpful to me, I was looking for the same thing for days !

Ok i set on each face a color, and set to true vertexColor on the material, that solve the problem ! :)

I write here the whole concept that I used in order to add a proper answer for those who are in the same situation :

// Define a main Geometry used for the final mesh
var mainGeometry = new THREE.Geometry();

// Create a Geometry, a Material and a Mesh shared by all the shapes you want to merge together (here I did 1000 cubes)
var cubeGeometry = new THREE.CubeGeometry( 1, 1, 1 );
var cubeMaterial = new THREE.MeshBasicMaterial({vertexColors: true});
var cubeMesh = new THREE.Mesh( cubeGeometry );

var i = 0;

for ( i; i<1000; i++ ) {

    // I set the color to the material for each of my cubes individually, which is just random here
    cubeMaterial.color.setHex(Math.random() * 0xffffff);

    // For each face of the cube, I assign the color
    for ( var j = 0; j < cubeGeometry.faces.length; j ++ ) {
        cubeGeometry.faces[ j ].color = cubeMaterial.color;
}

    // Each cube is merged to the mainGeometry
    THREE.GeometryUtils.merge(mainGeometry, cubeMesh);
 }

 // Then I create my final mesh, composed of the mainGeometry and the cubeMaterial
 var finalMesh = new THREE.Mesh( mainGeometry, cubeMaterial );
 scene.add( finalMesh );

Hope it will help as it helped me ! :)




回答3:


this.meshMaterials.push(new THREE.MeshBasicMaterial(
    {color:0x00ff00 * Math.random(), side:THREE.DoubleSide}));

for ( var face in geometry.faces ) {
  geometry.faces[face].materialIndex = this.meshMaterials.length-1;
}

var mesh = new THREE.Mesh(geometry);

THREE.GeometryUtils.merge(this.globalMesh, mesh);
var mesh = new THREE.Mesh(this.globalMesh, new THREE.MeshFaceMaterial(this.meshMaterials));

Works like a charm, for those who need example but ! This creates mutliple additional buffers (indices and vertex data) , and multiple drawElements call too :(, i inspect the draw call with webgl inpector, before adding the MeshFaceMaterial : 75 call opengl api running at 60fps easily, after : 3490 call opengl api fps drop about 20 % 45-50 fps, this means that drawElements is called for every mesh, we loose the context of merging meshes, did i miss something here ? i want to share different materials on the same buffer



来源:https://stackoverflow.com/questions/16400555/changing-material-color-on-a-merged-mesh-with-three-js

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!