Erhöhen der Echtzeitleistung auf Leinwandeffekten

Ich versuche, den folgenden Effekt auf ein HTML5-Spiel anzuwenden:http://somethinghitme.com/projects/metaballs/

Aber da es ein Spiel ist (im Gegensatz zu einer grafischen Demo), habe ich strengere FPS-Anforderungen. Ich brauche Zeit, um die Physik und einige andere Dinge zu berechnen, und mein größter Engpass ist der Code für die Metabälle.

Der folgende Code ist der, den ich nach dem Entfernen des Originalcodes zur Leistungssteigerung erhalten habe. Er ist nicht so hübsch, aber für meine Zwecke ausreichend:

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

Ich hatte eine weitere Schleife in meinem Code und konnte die Leistung mithilfe der im folgenden Link beschriebenen Technik steigernhttp://www.fatagnus.com/de/aufnehmen-Ihres-Schleifens-für-bessere-Leistung-in-Javascript/ Aber wenn Sie dasselbe verwenden, verringert sich die Leistung tatsächlich (habe ich es vielleicht falsch gemacht?)

Ich habe auch bei Webworkern nachgeforscht, um festzustellen, ob ich die Last aufteilen kann (da der Code für jedes Pixel einzeln ausgeführt wird), aber anhand des Beispiels, das ich auf diesem Link gefunden habehttp://blogs.msdn.com/b/eternalcoding/archive/2012/09/20/using-web-workers-to-prove-performance-of-image-manipulation.aspx Läuft tatsächlich langsamer, wenn Webworker verwendet werden.

Was kann ich sonst noch tun? Gibt es eine Möglichkeit, die Verzweigung aus der Schleife zu entfernen? Ein anderer Weg, um es abzuwickeln? Oder ist das das Beste, was ich tun kann?

Bearbeiten:

Dies ist ein Teil des umgebenden Codes:

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

}

und die Prozessmethode:

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

};

Wie zu sehen ist, habe ich versucht, Bilder anstelle von Verlaufsformen zu verwenden, aber die Leistung war schlechter. Ich habe auch versucht, ctx.drawImage anstelle von putImageData zu verwenden, aber es verliert das Alpha und ist nicht schneller. Ich kann mir keine Alternative vorstellen, um den gewünschten Effekt zu erzielen. Der aktuelle Code läuft perfekt auf Google Chrome, aber Safari und Firefox sind sehr langsam. Kann ich noch etwas ausprobieren? Sollte ich diese Browser einfach aufgeben?

Antworten auf die Frage(4)

Ihre Antwort auf die Frage