Reputation: 23
I copy and paste the whole(short) html file here to illustrate the problem. Basically, I create a simple triangle geometry as a global variable. When you click the "Red" button, function red() is called to render the triangle as red. The problem is that clicking "Green" does not render it as green if the triangle has already been rendered as red.
<html>
<body>
<div id="container"></div>
<button onclick="red()">Red</button>
<button onclick="green()">Green</button>
<script src="http://threejs.org/build/three.js"></script>
<script>
//Boilerplate stuff
var w=300;
var h=300;
var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(w, h);
document.getElementById('container').appendChild( renderer.domElement );
var scene = new THREE.Scene();
var light = new THREE.DirectionalLight(0xffffff);
light.position.z = 10;
scene.add(light);
var camera = new THREE.PerspectiveCamera( 20, w / h, 1, 1000 );
camera.position.z = 10;
var materials = [new THREE.MeshPhongMaterial( { color: 0xffffff, shading: THREE.FlatShading, vertexColors: THREE.VertexColors, shininess: 0 } )];
//Make a geometry
var shape = new THREE.Shape();
shape.moveTo( 0,0 );
shape.lineTo( 0, 1 );
shape.lineTo( 1, 0);
var geometry = new THREE.ShapeGeometry([shape]);
var obj = THREE.SceneUtils.createMultiMaterialObject(geometry, materials);
scene.add(obj);
//
function red()
{
change_color(new THREE.Color(0xff0000));
renderer.render(scene, camera);
}
//
function green()
{
change_color(new THREE.Color(0x00ff00));
renderer.render(scene, camera);
}
//
function change_color(color)
{
geometry.colorsNeedUpdate = true;
for(var i=0;i<geometry.faces.length;i++)
{
if(geometry.faces[i].vertexColors[0]==undefined)
{
geometry.faces[i].vertexColors[0]=color;
}
else
{
geometry.faces[i].vertexColors[0].copy(color);
}
if(geometry.faces[i].vertexColors[1]==undefined)
{
geometry.faces[i].vertexColors[1]=color ;
}
else
{
geometry.faces[i].vertexColors[1].copy(color);
}
if(geometry.faces[i].vertexColors[2]==undefined)
{
geometry.faces[i].vertexColors[2]=color;
}
else
{
geometry.faces[i].vertexColors[2].copy(color);
}
}
}
</script>
</body>
</html>
Upvotes: 1
Views: 1404
Reputation: 104833
You are changing vertex colors after the first render of a mesh.
Currently, you can't use the following pattern in three.js once the object has been rendered at least once.
geometry.faces[ i ].vertexColors[ 0 ] = color; // assigning a Color object
You have to use this pattern instead:
geometry.faces[ i ].vertexColors[ 0 ].copy( color ); // or use set()
You must also set the needsUpdate
flag when the vertex colors are changed.
geometry.colorsNeedUpdate = true;
Consequently, in your program, you need to add vertex colors to your geometry when you create it. Then just change the color values.
three.js r.77
Upvotes: 4
Reputation: 56
Try making your var obj a global variable, so instantiate it at the beginning of your program. Also where are you changing the colors, in your render function or another function?
Upvotes: 0