The Networker
The Networker

Reputation: 23

How to update colors after vertex colors are changed?

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

Answers (2)

WestLangley
WestLangley

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

Evan D&#39;Elia
Evan D&#39;Elia

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

Related Questions