Note that there are some explanatory texts on larger screens.

plurals
  1. POIncreasing real-time performance on canvas' effects
    primarykey
    data
    text
    <p>I'm trying to use the following effect on a HTML5 game: <a href="http://somethinghitme.com/projects/metaballs/" rel="nofollow">http://somethinghitme.com/projects/metaballs/</a></p> <p>But since its a game (as opposed to graphical demo) I have tighter FPS requirements, I need time to calculate the physics and the some other things and my biggest bottleneck is the code for the metaballs.</p> <p>The following code is what I got after stripping the original code for performance, its not as pretty but it's enough for my purposes:</p> <pre><code>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 &lt;n; i += 4) { if(pix[i+3]&lt;210){ pix[i+3] = 0; } } //ctx.clearRect(0,0,900,675); //ctx.drawImage(this._tempCanvas,0,0); ctx.putImageData(imageData, 0, 0); } </code></pre> <p>I had another loop on my code and I managed to increase its performance by using the technique described on the following link <a href="http://www.fatagnus.com/unrolling-your-loop-for-better-performance-in-javascript/" rel="nofollow">http://www.fatagnus.com/unrolling-your-loop-for-better-performance-in-javascript/</a> but using the same on this actually decreases the performance (maybe I did it wrong?)</p> <p>I also researched web workers to see if I could split the load (since the code runs for each pixel individually) but the example I found on this link <a href="http://blogs.msdn.com/b/eternalcoding/archive/2012/09/20/using-web-workers-to-improve-performance-of-image-manipulation.aspx" rel="nofollow">http://blogs.msdn.com/b/eternalcoding/archive/2012/09/20/using-web-workers-to-improve-performance-of-image-manipulation.aspx</a> actually runs slower when using web workers.</p> <p>What else can I do? Is there a way to remove the branching from the loop? Another way to unroll it? Or is this the best I can do?</p> <p>Edit:</p> <p>This is some of the surrounding code:</p> <pre><code>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 &gt; 0) { do { this.process(i++); } while(--leftover &gt; 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 &gt; 0); this.metabilize(ctx); } </code></pre> <p>and the process method:</p> <pre><code>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 &gt; 910 || bx &lt; -10 || by &gt; 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(); }; </code></pre> <p>As can be seen, I tried using images instead of gradient shapes, but the performance was worse, I also tried to use ctx.drawImage instead of putImageData, but it loses the alpha and is not faster. I can't think of an alternative to achieve the desired effect. The current code runs perfectly on Google Chrome, but Safari and Firefox are really slow. Is there anything else I can try? Should I just give up on those browsers?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload