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
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 } );
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
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
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();
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