Canvas Billboard animation at THREE.js

Everything,

I am trying to animate a canvas-based texture that displays on a plane like a billboard. I added that material.needsUpdate and texture.needsUpdate , but I still can't make the texture come to life. I also turned on the spinning cube so that I know that the animation program works at some level.

Here is the code:

    
      
      
         if (window.innerWidth === 0) {window.innerWidth = parent.innerWidth;  window.innerHeight = parent.innerHeight;  }

             var camera, scene, renderer;
             var mesh, geometry, material;
             var light, sign, animTex;
             var canvas, context;

             init ();
             animate ();

             function init () {

                 camera = new THREE.PerspectiveCamera (50, window.innerWidth / window.innerHeight, 1, 1200);
                 camera.position.z = 700;

                 scene = new THREE.Scene ();

                 material = new THREE.MeshLambertMaterial (
                     {color: 0x885522
                     , wireframe: false
                      , overdraw: false
                     });
                 geometry = new THREE.CubeGeometry (80, 120, 100, 1,1,1);
                 mesh = new THREE.Mesh (geometry, material);

                 sign = createSign ();

                 light = new THREE.DirectionalLight (0xFFFFFF, 3.0);
                 light.position = new THREE.Vector3 (5,10,7);
                 light.target = new THREE.Vector3 (0,0,0);

                 scene.add (mesh);
                 scene.add (sign);
                 scene.add (light);

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

             }
             function createSign () {
                 canvas = document.createElement ("canvas");
                 context = canvas.getContext ("2d");
                 canvas.width = 200;
                 canvas.height = 200;
                 context = canvas.getContext ("2d");              
                 var texture = new THREE.Texture (canvas);
                 texture.needsUpdate = true;
                 var material = new THREE.MeshBasicMaterial ({map: texture, overdraw: true});
                 material.needsUpdate = true;
                 var mesh = new THREE.Mesh (new THREE.PlaneGeometry (200, 200), material);
                 mesh.doubleSided = true;
                 return mesh;
             }

             function animate () {

                 var time = Date.now () * 0.01;
                 var sinTime = Math.sin (time * 0.05) * 100;
                 var cosTime = Math.cos (time * 0.05) * 100;

                 mesh.rotation.y = sinTime * 0.01;

                 requestAnimationFrame (animate);
                 context.fillStyle = "black";
                 context.fillRect (0,0, canvas.width, canvas.height);
                 context.fillStyle = "white";
                 context.fillRect ((canvas.width / 2) + sinTime, (canvas.height / 2) + cosTime, 20, 20)
                 renderer.render (scene, camera);
             }

This is done, but I cannot get the canvas texture material to be updated. What did I forget? Thanks so much for any pointers!

+4
source share
2 answers

Put this right before the render() call:

 sign.material.map.needsUpdate = true; 

Fiddle: http://jsfiddle.net/pPKVa/

+6
source

needsUpdate flag reset (to false) every time a texture is used (every render cycle), so the render cycle should be set to true (before calling the render, or it will be a frame). So in your example, put sign.material.map.needsUpdate = true before renderer.render( scene, camera ) . texture.needsUpdate = true and material.needsUpdate = true not needed.

In addition, you only need to set the needsUpdate flag on the texture, as the material properties do not change.

+1
source

All Articles