2012-07-01 11 views
6

Ahora mismo estoy trabajando en un juego en línea y he decidido usar el lienzo webgl en lugar del HTML5 por motivos de rendimiento. Estoy usando el framework three.js y mi intención es tener sprites animados en movimiento. Los sprites mismos se colocan en hojas de spritesheets y utilizo UVOffset y UVScale para usar el arte correcto y cambiar el arte de Sprite con el paso del tiempo. Me preguntaba si hay alguna manera de mejorar el rendimiento de este código, porque ahora mismo comienza a disminuir la velocidad en alrededor de 300 "jugadores" en el campo al mismo tiempo.Mejorando el rendimiento de los sprites animados en three.js

Saludos

La siguiente es la parte más importante de mi código:

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); 
    } 
+1

¡Bienvenido a Stack Overflow, y me alegro de haber resuelto el problema! Entonces, ya sabe, es perfectamente aceptable responder a su propia pregunta en la sección de respuestas a continuación y (después de un breve período de espera) marcarla como la respuesta aceptada. Esto ayuda a otras personas que podrían encontrarse con el mismo problema en el futuro a encontrar la solución más rápido. – Toji

Respuesta

2

respondí a mi propia pregunta por la realización del código podría ser mejorado en gran medida mediante la colocación de la

renderer.render(scene, camera); 

Codifique en el lugar correcto para que solo se llame cuando sea necesario.

9

me han escrito un ejemplo de código para mostrar una textura animada, ejemplo vivo en:

http://stemkoski.github.com/Three.js/Texture-Animation.html

con la fuente disponible en:

http://github.com/stemkoski/stemkoski.github.com/blob/master/Three.js/Texture-Animation.html

La parte útil es una función Escribí para manejar los desplazamientos automáticamente. La función (extraído desde el enlace anterior) es el siguiente:

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; 
     } 
    }; 
}  

Puede inicializar el material usando (por ejemplo):

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 }); 

y actualizarlo antes de cada render usando:

var delta = clock.getDelta(); 
annie.update(1000 * delta); 

Espero que esto ayude!

+0

Definitivamente una buena manera de manejar el desplazamiento cambiando automáticamente; sin embargo, realmente no veo cómo esto podría hacer que el renderizado sea más rápido. En este momento estoy en un punto donde tengo la aplicación con un límite superior de 20 fps (que es el punto dulce) y los sprites se mueven (x e y val) cada fotograma, la animación cambia (el desplazamiento cambia) cada 10 movimientos. La renderización vuelve a hacer cada cambio de fotograma. El problema que tengo ahora es que el renderizado va demasiado lento cuando tengo demasiados sprites en mi campo ... teniendo 100 sprites en movimiento y cambiando UV-offset mientras muevo la cámara se vuelve extremadamente lenta – Kristof

+0

+1 llené mi ventana con sprites (476 de ellos) todos con transparencia y 8 cuadros de animación. Usando este método todavía estaba obteniendo 30+ fps. ¡Gracias! – Chad

+0

hola. Escribí otra implementación de la misma idea y la empaqué como módulo. También utilizo desplazamiento uv, pero muevo todos los cálculos a sombreadores. ¿Qué piensas? https://github.com/elephanter/AnimatedSprites – Elephant

Cuestiones relacionadas