14

I actually found this question, but it says material.color doesn't exist. I need to know how to change the colors of the various faces of a cube I'm drawing:

var newCube = new THREE.Mesh(new three.CubeGeometry(size, size, size), new three.MeshNormalMaterial({ vertexColors: three.FaceColors }));
Community
  • 1
  • 1
David Gomes
  • 5,644
  • 16
  • 60
  • 103

3 Answers3

38

This answer only applies to versions of three.js prior to r.125.

Here is how you set and change the colors of a cube's faces:

var geometry = new THREE.BoxGeometry( size, size, size );
for ( var i = 0; i < geometry.faces.length; i ++ ) {
    geometry.faces[ i ].color.setHex( Math.random() * 0xffffff );
}

var material = new THREE.MeshBasicMaterial( { color: 0xffffff, vertexColors: true } );

If geometry.faces[i].color is changed after the geometry has been rendered, you must set geometry.colorsNeedUpdate = true.

three.js r.124

WestLangley
  • 102,557
  • 10
  • 276
  • 276
8

Here is a fiddle for people who end up here and want to see this code working.

I made a box and tied 3 colors to the faces:

// colors
red = new THREE.Color(1, 0, 0);
green = new THREE.Color(0, 1, 0);
blue = new THREE.Color(0, 0, 1);
var colors = [red, green, blue];

for (var i = 0; i < 3; i++) {
    geometry.faces[4 * i].color = colors[i];
    geometry.faces[4 * i + 1].color = colors[i];
    geometry.faces[4 * i + 2].color = colors[i];
    geometry.faces[4 * i + 3].color = colors[i];
}

The face colors are changed in the animate loop.


Also check a related question here with a great answer demonstrating the use of material indices and groups on THREE.BufferGeometry instances.

Wilt
  • 41,477
  • 12
  • 152
  • 203
1

For versions greater r.125

Each side of your cube consists of two triangles. So the idea is to process six vertices per iteration in order to create a single (random) color per side.

https://discourse.threejs.org/t/how-to-color-individual-faces-of-a-boxgeometry-tononindexed-object-using-vertices/30099

  const piece = new THREE.BoxGeometry(1, 1, 1).toNonIndexed();
  const material = new THREE.MeshBasicMaterial({
    vertexColors: true
  });
  const positionAttribute = piece.getAttribute('position');
  const colors = [];

  const color = new THREE.Color();

  for (let i = 0; i < positionAttribute.count; i += 6) {

    color.setHex(0xffffff * Math.random());

    colors.push(color.r, color.g, color.b);
    colors.push(color.r, color.g, color.b);
    colors.push(color.r, color.g, color.b);

    colors.push(color.r, color.g, color.b);
    colors.push(color.r, color.g, color.b);
    colors.push(color.r, color.g, color.b);
  } // for

  // define the new attribute
  piece.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));
  cube = new THREE.Mesh(piece, material);

JSFiddle

tjw
  • 11
  • 2