Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change face color in Three.js

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 below:

// Updated Per Lee!

var camera = _this.camera;      
var projector = new THREE.Projector();
var vector = new THREE.Vector3( ( event.clientX / window.innerWidth ) * 2 - 1,                                  - ( event.clientY / window.innerHeight ) * 2 + 1, 0.5 );
projector.unprojectVector( vector, camera );

var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );
var intersects = ray.intersectObjects( kage.scene.children );

if ( intersects.length > 0 ) {
    face = intersects[0].face;
    var faceIndices = ['a', 'b', 'c', 'd'];         
    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;
    }
}

I also initialize the object, in this case a Cube as follows:

// this material causes a mesh to use colors assigned to vertices
var material = new THREE.MeshBasicMaterial( { 
    color: 0xf0f0f0, 
    shading: THREE.FlatShading,
    vertexColors: THREE.VertexColors 
});

var directionalLight = new THREE.DirectionalLight(0xEEEEEE);
directionalLight.position.set(10, 1, 1).normalize();
kage.scene.add(directionalLight);

var cube = new THREE.Mesh(new THREE.CubeGeometry(300, 300, 300,1,1,1), material);
cube.dynamic = true;
kage.scene.add(cube);

Changing the material makes the cube white regardless of the light color. The intersection logic still works, meaning i select the correct face, but alas the color does not change.

I'm new to Stackoverflow [well asking a question that is, so hopefully my edits are not confusing]

like image 891
adamsch1 Avatar asked Jun 28 '12 20:06

adamsch1


3 Answers

  • 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

like image 114
Valay Avatar answered Nov 02 '22 15:11

Valay


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 } );
like image 7
Stemkoski Avatar answered Nov 02 '22 15:11

Stemkoski


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
like image 5
Gus Avatar answered Nov 02 '22 14:11

Gus