Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maximixing the speed of particle rendering on HTML5 <canvas>

I am doing an experiment and attempting to improve the max particle count before frame-rates start to drop in HTML5 Canvas.

I'm using requestAnimationFrame, I'm using drawImage from a canvas as this seems to be the fastest method for rendering images (as tested on jsPerf).

There's a working jsFiddle here: http://fiddle.jshell.net/bewYC/5/

You might have to refresh or re-run a few times to get it to work (no idea why but it just doesn't want to run on the first page load.)

As is, my computer running Chrome 22 can maintain 60FPS with about 5,000 particles. With every step above that, FPS starts to drop. If I remove drawImage() and just calculate the particles' positions, my processor doesn't max out until well over 10X as many particles.

What I want to know: Is there is a faster way to render a large amount of particles (say 40,000 for example) than using a loop with drawImage in it? I especially want to know this about JavaScript/Canvas, but if you only have knowledge about another language such as Java or C#, then please share anyway.

like image 286
BumbleShrimp Avatar asked Nov 15 '12 19:11

BumbleShrimp


1 Answers

For this problem, using WebGL (or other “3D” API as appropriate for your platform) is nearly always the best way to do it. Compositing lots of images ("textures", rather) at moving positions is exactly what graphics hardware is designed to be good for. Modern browsers do use GPU acceleration for performing 2D-Canvas drawing operations, but there is still JavaScript requesting the drawing of each individual image, and that's the problem.

I recommend you check out WebGL — for simple things like a particle system it's not hard to program at all, and you can easily render thousands of particles. Your JavaScript simply provides an array containing the positions of all the particles.

An advanced technique is to put the simulation of the particles as well on the GPU, thus requiring no JavaScript to execute per-particle at all. I have myself written a GPU particle simulator in my GLToy. Here it's configured for 80,000 particles and that achieves 60 FPS on my laptop. In fact, the limitation in that particular configuration is the fill-rate of the smooth particles; if we just use points I can push it up to 300,000 particles. And I am no wizard of graphics programming; I'm sure someone who knows exactly what to do could push it further.

(P.S. links may be fragile as I revise GLToy; if you don't get the named effects please let me know so I can fix the links.)

like image 179
Kevin Reid Avatar answered Sep 22 '22 14:09

Kevin Reid