2011-10-06 22 views
9

¿Cómo resolver diferentes FPS en requestAnimationFrame en diferentes navegadores?
estoy haciendo un juego en 3D utilizando THREE.js que utiliza requestAnimationFrame y es rápido en Google Chrome 15.
Sin embargo, es realmente lento en Firefox 6 y realmente muy lento (más lento que Firefox) en IE9.
Esto es realmente un problema grande y me pregunto si hay una solución para eso.¿Cómo resolver diferentes FPS en requestAnimationFrame en diferentes navegadores?

Gracias.

+1

La forma de resolver esto es hacer que el código que ejecuta desde la devolución de llamada se ejecute rápidamente. Cómo hacer eso es imposible de decir sin ver el código ... –

Respuesta

5

Hasta donde yo sé, no hay forma de arreglar esto realmente, aparte de hacer que su código requiera menos recursos.

Chrome parece ser el navegador más rápido, pero generalmente FF no se queda atrás, pero IE sigue siendo lento. Dependiendo de los métodos de renderizado, lienzo, svg o webGL, también depende mucho de su hardware local, ya que utiliza el lado del cliente para la mayoría de las cosas, y las representaciones webGL complicadas necesitan una poderosa GPU para lograr buenos framerates.

Existen formas de medir la tasa de cuadros sobre la marcha, y cambiar sus animaciones en consecuencia.
Aquí hay un ejemplo muy simple que mide la tasa de fotogramas.

function step(timestamp) { 
 
    var time2 = new Date; 
 
    var fps = 1000/(time2 - time); 
 
    time = time2; 
 
\t 
 
    document.getElementById('test').innerHTML = fps; 
 
    window.requestAnimationFrame(step); 
 
} 
 

 
var time = new Date(), i = 0; 
 
window.requestAnimationFrame(step);
<div id="test"></div>

Esto es sólo una medida instantánea que no es tan precisa, que probablemente querrá algo que mide más de un cierto tiempo para obtener una velocidad de fotogramas más correcto para el navegador que se utilice.

También tenga en cuenta el argumento timestamp, que en requestAnimationFrame es marca de tiempo de alta resolución con una precisión mínima de 1 milisegundos, que también se puede utilizar para deterine la velocidad de la animación, y cualquier retraso navegador.

+2

IE9 + es bastante rápido. A veces más rápido que FF, en mi experiencia. – kangax

14

Lo más común es crear una variable deltaTime (dt) que luego se utilizará como un parámetro para cada ciclo de animación/actualización.

El código es solo para visualizar el problema/solución.

// ... 
timer: function(){ 
    var now = new Date().getTime(); // get current time 
    this.controls.dt = now - this.controls.time; // calculate time since last call 
    this.controls.time = now; // update the current application time 
    this.controls.frame++; // also we have a new frame 
    return this.controls.dt ; 
} 

para cualquier llamada a la función de hacer que se pasan luego dt

// we call the update function with every request frame 
update: function(){ 
    var dt = this.timer(); 
    _.each(this.activeViews, function(item){ item.update(dt); }); // this is underscore.js syntax 
} 

item.update (dt) parece que

//... 
var x = this.position.get(x); 
x = x + (10*dt); // meaning: x increases 10 units every ms. 
this.position.x = x; 
2

En algunos navegadores requestAnimationFrame funciona algo así como

setTimeout(callback, 1000/(16 + N)

donde N es el tiempo requerido para que se ejecute su código. Lo que significa que limita su FPS a 62Hz, pero si su código funciona lentamente, se limitará a algo más bajo. Básicamente trata de hacer una brecha de 16 ms entre cada espacio. Por supuesto, esto no es cierto para todos los navegadores y probablemente cambie en el futuro de todos modos, pero aún puede darle una idea de cómo funciona.

Incluso si se implementó igual en todos los navegadores, existen muchos factores que afectan el rendimiento de su código, etc. Nunca se puede estar seguro de que su código se esté ejecutando a una frecuencia constante.

3

El marco Crafty hace algo que es un poco diferente, pero podría funcionar en algunos casos: el número de tics de juego por sorteo no es constante. Por el contrario, se da cuenta cuando la velocidad de fotogramas se está quedando atrás de un objetivo ideal, y se desplazará a través de múltiples marcas de juego antes de realizar el paso de sorteo. Puede ver el step function en github.

Esto funciona bien siempre y cuando el juego funcione sin problemas. Pero si intentas algo más intensivo en el uso del procesador, puede tender a exacerbar la situación, ya que priorizará la lógica del juego sobre la animación.

En cualquier caso, solo funcionará si la lógica del juego y la lógica de representación están un tanto desacopladas. (Si fueron completamente desacoplados, es posible que pueda colocarlos en bucles completamente separados.)

Cuestiones relacionadas