Incremento del rendimiento en tiempo real sobre los lienzos.

Estoy tratando de usar el siguiente efecto en un juego HTML5:http://somethinghitme.com/projects/metaballs/

Pero como es un juego (a diferencia de una demostración gráfica) tengo requisitos más estrictos de FPS, necesito tiempo para calcular la física y algunas otras cosas, y mi mayor cuello de botella es el código para los metaballs.

El siguiente código es lo que obtuve después de eliminar el código original para el rendimiento, no es tan bonito pero es suficiente para mis propósitos:

ParticleSpawner.prototype.metabilize = function(ctx) {
    var imageData = this._tempCtx.getImageData(0,0,900,675),
    pix = imageData.data;
    this._tempCtx.putImageData(imageData,0,0);

    for (var i = 0, n = pix.length; i <n; i += 4) {
        if(pix[i+3]<210){
            pix[i+3] = 0;
        }
    }

    //ctx.clearRect(0,0,900,675);
    //ctx.drawImage(this._tempCanvas,0,0);
    ctx.putImageData(imageData, 0, 0);
}

Tuve otro bucle en mi código y logré aumentar su rendimiento utilizando la técnica descrita en el siguiente enlacehttp://www.fatagnus.com/unrolling-your-loop-for-better-performance-in-javascript/ pero usar lo mismo en esto realmente disminuye el rendimiento (¿tal vez lo hice mal?)

También investigué a los trabajadores web para ver si podía dividir la carga (ya que el código se ejecuta para cada píxel individualmente) pero el ejemplo que encontré en este enlacehttp://blogs.msdn.com/b/eternalcoding/archive/2012/09/20/using-web-workers-to-improve-performance-of-image-manipulation.aspx en realidad funciona más lento cuando se utilizan trabajadores web.

¿Que más puedo hacer? ¿Hay alguna manera de eliminar la ramificación del bucle? ¿Otra forma de desenrollarlo? ¿O es esto lo mejor que puedo hacer?

Editar:

Este es parte del código que lo rodea:

ParticleSpawner.prototype.drawParticles = function(ctx) {
    this._tempCtx.clearRect(0,0,900,675);

    var iterations = Math.floor(this._particles.getNumChildren() / 8);
    var leftover = this._particles.getNumChildren() % 8;
    var i = 0;

    if(leftover > 0) {
        do {
            this.process(i++);
        } while(--leftover > 0);
    }

    do {
        this.process(i++);
        this.process(i++);
        this.process(i++);
        this.process(i++);
        this.process(i++);
        this.process(i++);
        this.process(i++);
        this.process(i++);
    } while(--iterations > 0);

    this.metabilize(ctx);

}

y el método de proceso:

ParticleSpawner.prototype.process = function(i) {
    if(!this._particles.getChildAt(i)) return;
    var bx = this._particles.getChildAt(i).x;
    var by = this._particles.getChildAt(i).y;

    if(bx > 910 || bx < -10 || by > 685) {
        this._particles.getChildAt(i).destroy();
        return;
    }

    //this._tempCtx.drawImage(this._level._queue.getResult("particleGradient"),bx-20,by-20);

    var grad = this._tempCtx.createRadialGradient(bx,by,1,bx,by,20);
    this._tempCtx.beginPath();

    var color = this._particles.getChildAt(i).color;
    var c = "rgba("+color.r+","+color.g+","+color.b+",";

    grad.addColorStop(0, c+'1.0)');
    grad.addColorStop(0.6, c+'0.5)');
    grad.addColorStop(1, c+'0)');

    this._tempCtx.fillStyle = grad;
    this._tempCtx.arc(bx, by, 20, 0, Math.PI*2);
    this._tempCtx.fill();

};

Como se puede ver, intenté usar imágenes en lugar de formas de degradado, pero el rendimiento fue peor, también intenté usar ctx.drawImage en lugar de putImageData, pero pierde el alfa y no es más rápido. No puedo pensar en una alternativa para lograr el efecto deseado. El código actual se ejecuta perfectamente en Google Chrome, pero Safari y Firefox son muy lentos. ¿Hay algo más que pueda probar? ¿Debo renunciar a esos navegadores?

Respuestas a la pregunta(4)

Su respuesta a la pregunta