How to change face color in Three.js

前端 未结 5 1559
庸人自扰
庸人自扰 2020-11-30 10:56

I am attempting to change the color on a single face of a mesh. This is in a WebGL context. I can change the entire mesh color, just not a single Face. Relevant code belo

相关标签:
5条回答
  • 2020-11-30 11:30

    Assuming that "myGeometry" is the geometry containing the face that you would like to change the color of, and "faceIndex" is the index of the particular face that you want to change the color of.

    // the face's indices are labeled with these characters 
    var faceIndices = ['a', 'b', 'c', 'd'];  
    
    var face = myGeometry.faces[ faceIndex ];   
    
    // determine if face is a tri or a quad
    var numberOfSides = ( face instanceof THREE.Face3 ) ? 3 : 4;
    
    // assign color to each vertex of current face
    for( var j = 0; j < numberOfSides; j++ )  
    {
        var vertexIndex = face[ faceIndices[ j ] ];
        // initialize color variable
        var color = new THREE.Color( 0xffffff );
        color.setRGB( Math.random(), 0, 0 );
        face.vertexColors[ j ] = color;
    }
    

    Then, the mesh needs to use the following material so that face colors are derived from the vertices:

    // this material causes a mesh to use colors assigned to vertices
    var cubeMaterial = new THREE.MeshBasicMaterial( 
        { color: 0xffffff, shading: THREE.FlatShading, 
        vertexColors: THREE.VertexColors } );
    
    0 讨论(0)
  • 2020-11-30 11:34

    I think the method listed above only works in the WebGLRenderer. If you're going for something that works in both the CanvasRenderer and WebGLRenderer it's a bit more complicated, but I suspect the end result is more efficient both in terms of memory use and performance.

    After going through the THREE.jS Projector.js source, this is how I did it:

    // create the face materials
    var material_1 = new THREE.MeshLambertMaterial(
        {color : 0xff0000, shading: THREE.FlatShading, overdraw : true}
    );
    var material_2 = new THREE.MeshLambertMaterial(
        {color : 0x00ff00, shading: THREE.FlatShading, overdraw : true}
    );
    
    // create a geometry (any should do)
    var geom = new THREE.CubeGeometry(1,1,1);
    
    // add the materials directly to the geometry
    geom.materials.push(material_1);
    geom.materials.push(material_2);
    
    // assign the material to individual faces (note you assign the index in 
    // the geometry, not the material)
    for( var i in geom.faces ) {
        var face = geom.faces[i];
        face.materialIndex = i%geom.materials.length;
    }
    
    // create a special material for your mesh that tells the renderer to use the 
    // face materials
    var material = new THREE.MeshFaceMaterial();
    var mesh = new THREE.Mesh(geom, material);
    

    This example is adapted from the working code I have, but I have to admit I haven't actually run this exact block of code and I don't have a great track record of getting everything right first go, but hopefully it will help anyone who's struggling

    0 讨论(0)
  • 2020-11-30 11:35
    • Update library to r53.
    • Add vertexColors: THREE.FaceColors in material.
    • And finally use face.color.setRGB( Math.random(), Math.random(), Math.random()).

      Now no need to traverse loop for 4 sides (a,b,c,d) for THREE.Face4 or 3 sides (a,b,c) for THREE.Face3.

      This works in both WebGL and Canvas rendering.

    Example

    three.js r53

    0 讨论(0)
  • 2020-11-30 11:47

    As per Three JS Geometry Document, To signal an update in this faces, Geometry.elementsNeedUpdate needs to be set to true.

    The following snippet changes the colors of all faces.

    mesh.material.vertexColors = THREE.FaceColors

    var faces = mesh.geometry.faces;
    
    for(var i = 0 ; i < faces.length; i++){
      var face = faces[i];
      var color = new THREE.Color("rgb(255, 0, 0)");
      face.color = color;
    }
    
    mesh.geometry.elementsNeedUpdate = true;
    
    render();
    
    0 讨论(0)
  • 2020-11-30 11:51

    I'm rather new to three.js, but most of these examples seem overly long and complicated. The following code seems to color all 12 triangular faces for a cube... (WebGLRenderer r73).

    One thing I noted when doing this is that the order of the faces is a little strange (to me as a novice at least).

    var geometry = new THREE.BoxGeometry( 1, 1, 1 );
    console.log(geometry.faces.length); // 12 triangles
    geometry.faces[0].color = new THREE.Color(0x000000); //Right 1
    geometry.faces[1].color = new THREE.Color(0xFF0000); //Right 2
    geometry.faces[2].color = new THREE.Color(0xFF8C08); //Left 1
    geometry.faces[3].color = new THREE.Color(0xFFF702); //Left 2
    geometry.faces[4].color = new THREE.Color(0x00FF00); //Top 1
    geometry.faces[5].color = new THREE.Color(0x0000FF); //Top 2
    geometry.faces[6].color = new THREE.Color(0x6F00FF); //Bottom 1
    geometry.faces[7].color = new THREE.Color(0x530070); //Bottom 2
    geometry.faces[8].color = new THREE.Color(0x3F3F3F); //Front 1
    geometry.faces[9].color = new THREE.Color(0x6C6C6C); //Front 2
    geometry.faces[10].color = new THREE.Color(0xA7A7A7);//Rear 1
    geometry.faces[11].color = new THREE.Color(0xFFFFFF);//Rear 2
    
    0 讨论(0)
提交回复
热议问题