Everyone,
I'm trying to animate a Canvas-based texture that is mapped onto a plane, like a billboard. I've made a point of including material.needsUpdate & texture.needsUpdate, but I'm still unable to get the texture to come to life. I've also included a rotating cube just so I know the animation routine is functioning on 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 runs, but I can't seem to get the Canvas texture material to update. What have I overlooked? Thanks very much for any pointers!
Place this right before your
render()
call:Fiddle: http://jsfiddle.net/pPKVa/
The
needsUpdate
flag is reset (to false) every time the texture is used (every render loop), so it needs to be set to true in the render loop (before the render call, or it'll be a frame off). So in your example, putsign.material.map.needsUpdate = true
beforerenderer.render( scene, camera )
.texture.needsUpdate = true
andmaterial.needsUpdate = true
are not needed.Also, you only need to set the
needsUpdate
flag on the texture, as the material properties are not changing.