5

This question was previously asked here: Threejs: assign different colors to each vertex in a geometry, but it is quite old, and so the provided solutions don't work with current versions of three.js (which no longer provides the attribute vertexColors for the Geometry class).

I know that it's possible to set the color of each face of a geometry, but I am setting the vertices of a sphere to different distances, and I wish to simultaneously modulate the color of each vertex dependent on its distance from the centre.

Community
  • 1
  • 1
user1618840
  • 453
  • 1
  • 5
  • 14
  • Can you provide a simple test-case - something about 10 lines long - possibly with a fiddle? – Rob Baillie Dec 02 '13 at 13:20
  • I'm not entirely sure what you mean. A solution would be something along the lines of: geometry = new THREE.SphereGeometry( averageObjectRadius, 256,128 ); for(var i in geometry.vertices) { //code to set the color of vertex[i] } – user1618840 Dec 02 '13 at 13:46
  • I was thining more along the lines of: http://jsfiddle.net/87mcD/ Maybe with a geometry that doesn't have a huge number of verticies! Just thinking that if you make it easy for someone to start to answer your question you're likely to get more people interested! – Rob Baillie Dec 02 '13 at 13:56
  • Ah right, cheers for that. – user1618840 Dec 02 '13 at 14:33

2 Answers2

3

This seems to do what you're asking (though I've never used Three before, so I'm not 100% it's what you're asking for:

The key is (as morris4) says, setting the colors on the face, rather than the geometry.

You also need to set the material 'vertexColors' property so that it feeds through.

var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );

geometry = new THREE.CubeGeometry( 10, 10, 10 );

for ( faceIndex in geometry.faces )
{
    var face = geometry.faces[ faceIndex ];
    face.vertexColors[ 0 ] = new THREE.Color(0xFF0000);
    face.vertexColors[ 1 ] = new THREE.Color(0x00FF00);
    face.vertexColors[ 2 ] = new THREE.Color(0x0000FF);
    face.vertexColors[ 3 ] = new THREE.Color(0xFFFFFF);
}

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

var object = new THREE.Mesh( geometry, material );

object.position.z = -25;

scene.add(object);

function render() {
    requestAnimationFrame(render);
    object.rotation.x += 0.01;
    object.rotation.y += 0.01;
    renderer.render(scene, camera);    
}
render();

I put this on a fiddle here: http://jsfiddle.net/87mcD/3/

You should note that it's r54, and the latest is r63. And it doesn't appear to work as is on the latest version.

Still, it may still be of use to you...

EDIT: This fiddle works on three.js r.63: http://jsfiddle.net/87mcD/4/

WestLangley
  • 102,557
  • 10
  • 276
  • 276
Rob Baillie
  • 3,436
  • 2
  • 20
  • 34
1

A quick grep (try grep "vertexColors" */*.js . in three.js' src directory) indicates that you cannot set the color per vertex, but only per face in recent versions of three.js. A triangle face may have a property vertexColors with 3 colors, aligned to the vertices of the face.

For each vertex, you will have to figure out which faces use that vertex, and then set the colors on the faces' vertexColors property.

Update: depending on your use case, you may iterate over the faces, get the 3 vertices via the face's indices (a, b, c) and then compute and set the color on them. this will recompute the same color a few times (in your case, something like 8 times per vertex) but should be a quick and easy way to do what you asked for.

function color(v) {
    var c = new THREE.Color();
    c.r = (10 + v.y)/20;
    c.g = (10 + v.y)/10 + Math.sin(v.x/10 * Math.PI) - 0.3;
    c.b = 1 - (10 + v.y)/20;
    return c;
}

for(var i = 0; i < geometry.faces.length; ++i) {
    var face = geometry.faces[i];
    face.vertexColors[0] = color(geometry.vertices[face.a]);
    face.vertexColors[1] = color(geometry.vertices[face.b]);
    face.vertexColors[2] = color(geometry.vertices[face.c]);
}

Fiddle: http://jsfiddle.net/87mcD/5/

morris4
  • 1,977
  • 17
  • 14
  • I admit that I've been trying this myself and I can't get three to respond to setting the colors on the face.vertexColors. It seems to be ignored in every test case I've put together. – Rob Baillie Dec 02 '13 at 17:10
  • @RobBaillie i've updated your fiddle: http://jsfiddle.net/87mcD/2/ - r54 wouldn't work for me either, so i used a more recent build as an external resource. – morris4 Dec 02 '13 at 19:54
  • Insane! I just got this to happen in r54 - http://jsfiddle.net/87mcD/3/, which doesn't work with the more recent build. Don't you love stable APIs! – Rob Baillie Dec 02 '13 at 19:56