Improving the performance of animated sprites in the three.js file

I am currently working on an online game and decided to use webgl rather than an HTML5 canvas for performance reasons. I use the three.js framework and my intention is to move animated sprites. The sprites themselves are placed on the sprites, and I use UVOffset and UVScale to use the correct art and switch the art of Sprite while passing by. I was wondering if there is a way to improve the performance of this code, because now it starts to slow down by about 300 “players” on the field at the same time.

Hi

Below is the most important part of my code:

var image = THREE.ImageUtils.loadTexture( "img/idlew.png" ); function addPlayer(){ var mesh = new THREE.Sprite({map:image});//, affectedByDistance: false, useScreenCoordinates: false}); images.push(mesh); mesh.position.set(Math.floor(Math.random() * 500), Math.floor(Math.random() * 500), 10); scene.add(mesh); mesh.uvScale.x = 96/1152; mesh.scale.x = 0.1; mesh.scale.y = 0.1; } var imgBackground = new THREE.MeshLambertMaterial({ map:THREE.ImageUtils.loadTexture('img/grass.jpg') }); var background = new THREE.Mesh(new THREE.PlaneGeometry(1000, 1000),imgBackground); scene.add(background); scene.add(camera); camera.rotation.x = -(Math.PI/2); scene.add(new THREE.AmbientLight(0xFFFFFF)); addPlayer(); renderer.render(scene, camera); var moveUp = false; tick(); var ticker = 0; var usedOne = 0; function tick(){ ticker++; if(ticker%10==0){ for (var i = 0; i < images.length; i++) { images[i].uvOffset.x = usedOne * 0.0835; }; usedOne++; if(usedOne == 12) usedOne = 0; addPlayer(); addPlayer(); addPlayer(); console.log(images.length); } requestAnimationFrame( tick ); renderer.render(scene, camera); } 
+6
source share
2 answers

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!

+9
source

I answered my question, realizing that the code can be significantly improved by posting

 renderer.render(scene, camera); 

The code is in the right place, so it had to be called .

+2
source

Source: https://habr.com/ru/post/919439/


All Articles