Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assigning colors to vertices in a geometry in Three.js

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.

like image 532
user1618840 Avatar asked Oct 02 '22 06:10

user1618840


2 Answers

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/

like image 72
Rob Baillie Avatar answered Oct 07 '22 17:10

Rob Baillie


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/

like image 27
morris4 Avatar answered Oct 07 '22 17:10

morris4