I wrote a sample code to display an animated texture, a live example:
http://stemkoski.github.com/Three.js/Texture-Animation.html
with source code available at:
http://github.com/stemkoski/stemkoski.github.com/blob/master/Three.js/Texture-Animation.html
The useful part is a function that I wrote to automatically handle offsets. The function (extracted from the link above) is as follows:
function TextureAnimator(texture, tilesHoriz, tilesVert, numTiles, tileDispDuration) { // note: texture passed by reference, will be updated by the update function. this.tilesHorizontal = tilesHoriz; this.tilesVertical = tilesVert; // how many images does this spritesheet contain? // usually equals tilesHoriz * tilesVert, but not necessarily, // if there at blank tiles at the bottom of the spritesheet. this.numberOfTiles = numTiles; texture.wrapS = texture.wrapT = THREE.RepeatWrapping; texture.repeat.set( 1 / this.tilesHorizontal, 1 / this.tilesVertical ); // how long should each image be displayed? this.tileDisplayDuration = tileDispDuration; // how long has the current image been displayed? this.currentDisplayTime = 0; // which image is currently being displayed? this.currentTile = 0; this.update = function( milliSec ) { this.currentDisplayTime += milliSec; while (this.currentDisplayTime > this.tileDisplayDuration) { this.currentDisplayTime -= this.tileDisplayDuration; this.currentTile++; if (this.currentTile == this.numberOfTiles) this.currentTile = 0; var currentColumn = this.currentTile % this.tilesHorizontal; texture.offset.x = currentColumn / this.tilesHorizontal; var currentRow = Math.floor( this.currentTile / this.tilesHorizontal ); texture.offset.y = currentRow / this.tilesVertical; } }; }
You can initialize the material using (for example):
var runnerTexture = new THREE.ImageUtils.loadTexture( 'images/run.png' ); // a texture with 10 frames arranged horizontally, display each for 75 millisec annie = new TextureAnimator( runnerTexture, 10, 1, 10, 75 ); var runnerMaterial = new THREE.MeshBasicMaterial( { map: runnerTexture } );
and update it before each rendering using:
var delta = clock.getDelta(); annie.update(1000 * delta);
Hope this helps!
source share