
WebGL: 80.000 particles - _ZeD_
http://minimal.be/lab/fluGL/index80000.html
======
ykl
Here's a much cooler version by Nop Jiarathanakul. Nop's version has shape
targeting, which is especially cool. Check out the running horse.

[http://www.iamnop.com/particles/](http://www.iamnop.com/particles/)

~~~
conkrete
On my currently laptop I only pull about 5fps when viewing this. Indeed cool,
but the OPs (albeit more simple) runs at a solid 60fps

~~~
msl09
yeah iamnop crashes my firefox

~~~
cookiecaper
Runs at near-60 FPS in Firefox for me. Using Linux and Firefox 37.

~~~
msl09
Firefox 31 from the debian wheezy package

------
maccard
80k particles isn't an awful lot, unfortunately. I can hit well into the
millions on desktop GPU's, so I would assume 2-300k would be well achieveable

EDIT: Seems that
[http://threejs.org/examples/#webgl_buffergeometry_particles](http://threejs.org/examples/#webgl_buffergeometry_particles)
has 500k.

~~~
acadien
Particles can be misleading too because if they're simply propagated by some
PDE on a regular mesh (or even no mesh) it is an embarrassingly parallel
problem. But if they're interacting particles then you need neighbor lists and
predictor corrector methods to propagate them which is considerably more
difficult to implement and parallelize.

~~~
maccard
But the original post isn't interacting either, it's just an integration with
gravity, that happens to be rendered by WebGL.

~~~
acadien
Yeah that's what I'm saying, if this demo has been 80,000 interacting
particles it would be extremely impressive.

~~~
jblow
Not really. Back in 2002 we did the first game jam where the engine concept
was "100,000 guys". That was 13 years ago:

[http://www.indiegamejam.com/igj0/](http://www.indiegamejam.com/igj0/)

Those guys all interacted with each other and the environment (though the
engine was designed to do the interactions in slices, where 1/N of the guys
would be checked each frame, but N was not high, like 4 or 5 maybe?)

~~~
acadien
In particle simulations interactions can happen at a distance, so at every
time step all particles need to be checked with all other nearby particles to
get their distances and compute the force of their interaction. It looks like
your simulation is a hard-sphere type interaction where you're only checking
to see if two particles bump into each other and is considerably faster to
compute.

~~~
jblow
No, it's not really different from a hard-sphere type interaction. It's the
same thing. But that doesn't matter in this context, because in the system we
built, our problem was harder/more-general because we were simulating 'guys',
meaning you can program an arbitrary interaction into your guys (is guy type X
near guy type Y, if so what happens?), and those 'guys' also interacted with a
2D height field terrain.

Keep in mind this was all on computers from the year 2002, which were pretty
damn slow compared to computers today. Today you could do _a lot_ of guys.

------
flohofwoe
I did some emscripten/WebGL performance tests a while ago which went into the
hundred-thousands particles for 3D-shape-particles at 60fps, but this depends
very much on the target hardware, less on the browser or operating system.

Both tests use simple 3D shape particles (5-vertex diamonds) and hardware-
instanced rendering (instanced_arrays extension), the first updates particle
positions on the CPU, the second on the GPU (fragment shader writes particle
position to offscreen render target, which is then sampled in vertex shader to
displace particle positions).

The first (CPU updates) goes up to around 450k particles on my Windows7
desktop machine before consistently dropping below 16ms per frame, the second
(GPU updates) goes to about 800k particles before dropping below 60fps:

[http://floooh.github.io/oryol/Instancing.html](http://floooh.github.io/oryol/Instancing.html)

[http://floooh.github.io/oryol/GPUParticles.html](http://floooh.github.io/oryol/GPUParticles.html)

These numbers are not much different then using desktop GL (2.1 with
extensions). The real advantages for this type of scenario would come from
updating persistently mapped buffers which are not available in WebGL.

What's impressive is the raw math performance of asm.js, the particle update
loop is simple glm code
([https://github.com/g-truc/glm](https://github.com/g-truc/glm)) without any
fancy optimizations.

~~~
marcosscriven
>What's impressive is the raw math performance of asm.js

I continue to be staggered at how well asm.js performs, and really glad Chrome
has taken on optimising for it as well as Firefox.

~~~
corysama
Running the instancing demo on an iPhone6+ I can get to 150k particles before
dropping below 60fps. There's an obvious speed up about three seconds in where
I guess the JITter decides to get serious.

So, even though there's no official support for asm.js on mobile safari. It
still works surprisingly well!

------
Udo
I was expecting the particles to be done as a pure shader implementation, but
when I looked at the source that's not the case. While a vertex shader is used
to display the particles, the "physics" is done in a JavaScript loop.

~~~
pierrec
This also surprised me. You can do the exact same thing, but with millions of
particles, if you store and process them on the GPU. The first example of that
technique being used in WebGL is probably by Mr.doob [1]. Since then, there
have been many iterations, some of which are basically a cooler version of the
linked demo [2]. (And simpler, judging from the source!)

[1]: [https://www.chromeexperiments.com/experiment/magic-
dust](https://www.chromeexperiments.com/experiment/magic-dust)

[2]: [https://www.chromeexperiments.com/experiment/one-million-
par...](https://www.chromeexperiments.com/experiment/one-million-particles)

------
ManyParticles
Ive made something similar to this a while ago.

[https://www.chromeexperiments.com/experiment/one-million-
par...](https://www.chromeexperiments.com/experiment/one-million-particles)

It does its calculations on the GPU so it can handle a million particles
easily. You can also pause it to explore it in 3D.

------
sebgeelen
This same page appear on HN almost 3 year ago :
[https://news.ycombinator.com/item?id=4008040](https://news.ycombinator.com/item?id=4008040).

Interesting how this all WebGL stuff is still so "hacky" and not yet commonly
used all around .

~~~
bhouston
I don't think WebGL is hacky if you approach it right.

We have 100,000 users who have created +180,000 scenes using advanced WebGL
and it is really stable: [http://clara.io](http://clara.io).

Here is a new demo scene I've been working on. PBR materials (w/ clear coat),
area lights, HDR, bloom, DOF and FXAA:

[https://clara.io/view/d3b82831-d56b-462f-b30c-500ea1c7f870/w...](https://clara.io/view/d3b82831-d56b-462f-b30c-500ea1c7f870/webgl)

And you can edit any part of the mesh or materials or animation or lighting in
our editor.

~~~
tripzilch
It's really cool but please to not link to the "real time" tab? It almost hung
my browser :) (FF37, shitty old netbook)

~~~
irascible
So sorry... We'll all make an effort to keep the internet slow while you're
browsing on your shitty netbook.

------
grimmdude
I find playing with this very relaxing. +1!

------
thekemkid
That is so cool. There's a great demo of orbitals and the like that can be
picked up from this. I would have loved if a physics teacher showed me
something like this when I was in school.

------
sakri
I made a test a while back to see how Canvas performs with particles :
[http://codepen.io/sakri/full/ntLAv](http://codepen.io/sakri/full/ntLAv) . If
I select the "per pixel" method, on my old laptop I get 60fps with 80,000
particles. I wasn't very impressed :D (although I'm sure the code could be
improved)

------
im2w1l
By drawing circles rapidly around the particles, you can herd them into a tiny
blob. Move your mouse into the blob for a colourful explosion.

~~~
hamburglar
This is always the first thing I do with one of these. It's so satisfying. On
this one, if you make big, fast circles so the blob is moving as little as
possible, then you let go, you can get the whole blob to just drift off to the
side and stop (it disappears), so when you mousedown again somewhere else, you
get a big stream of them all coming from the same general area.

I could play with this for hours. :)

------
merpnderp
I've looked over the code and I can't figure out what makes the particles
brighter. Some of it is when the particles overlap, they appear brighter, but
if you don't touch the screen, all the particles fade out to black. Anyone
know how that is done?

~~~
flohofwoe
The particles are rendered with additive blending:

gl.enable(gl.BLEND); ... gl.blendFunc(gl.SRC_ALPHA, gl.ONE);

It basically means that the particle color is added on top of the already
rendered particles (with the alpha value used to modulate the particle color,
which is a bit strange, it would be more usual to use gl.ONE for both
parameters). The more particles overlap, the brighter that pixels becomes.

Details are explained here:
[https://www.opengl.org/wiki/Blending#Blend_Equations](https://www.opengl.org/wiki/Blending#Blend_Equations)

~~~
flohofwoe
Plus what teraflop writes about particle velocity being proportional to their
line length. The 'overbrightening effect' should be caused by the blending
however.

------
fulafel
The standard particles example in three.js has 500.000 particles.

A description like "80k dynamic interactive physics based particles" would do
this one more justice.

(There's a dynamic particles demo in the threejs examples too, though it
doesn't say how many there are...)

~~~
davexunit
Since these particles aren't dynamic, they are much easier to render at high
volume. You create the vertex buffers once and you're done. Dynamic particles
are a lot more complicated, since the buffer needs to be updated constantly.

If anyone has some good articles about how to render a large number of dynamic
particles, where the simulation happens on the CPU (i.e. it's not all shader
trickery), using modernish OpenGL (no fixed function stuff), please share. I'm
eager to learn more about it, but haven't found good resources. It's a
blocking issue towards my goal of creating a bullet hell shoot-em-up game.

~~~
flohofwoe
Unfortunately dynamic buffer updates is one of the tricky parts to do right in
OpenGL since you need to assume what the driver does under the hood, and the
best technique depends on what GL version you're targeting, and what GL
extensions are available.

I found this blog post very useful:
[http://hacksoflife.blogspot.de/2012/04/beyond-
glmapbuffer.ht...](http://hacksoflife.blogspot.de/2012/04/beyond-
glmapbuffer.html)

If you can afford to target bleeding edge OpenGL, the AZDO slides contain the
current state of the art (there's a whole section about dynamic buffer updates
somewhere in there): [http://www.slideshare.net/CassEveritt/approaching-zero-
drive...](http://www.slideshare.net/CassEveritt/approaching-zero-driver-
overhead?related=1)

On WebGL, the established tricks like buffer orphaning don't work, and direct
mapping isn't available. It seems best to simply do a bufferSubData and not
care about double buffering etc
([https://groups.google.com/forum/#!searchin/webgl-dev-
list/fl...](https://groups.google.com/forum/#!searchin/webgl-dev-
list/floooh/webgl-dev-list/vMNXSNRAg8M/lu1NkJ22J_YJ))

------
adam12
The developer could improve this page by adding a demo mode that shows the
particles moving randomly around the screen. The demo mode could be shown
after a couple seconds of user inactivity.

------
amelius
Cool. I wonder what the governing equation for the particles is...

Also, If I open developer console in Chrome (docked at the bottom), it seems
the mouse position is off like 100 pixels or so.

~~~
boblemarin
The particles are attracted by the position of the mouse, each having a
slightly different (randomized) attraction factor.

If a particle ever reaches the exact mouse coordinates, its position is
randomly generated anywhere on the screen.

When rendering the particles, it simply draws a line between the previous and
the new position. So when a particle is transported to a random place, it
create the rays that appear around the cursor.

There's no real complexity in the maths involved, but I remember spending
quite some time tweaking the random ranges to get something nice.

~~~
corysama
Have you seen this VR demo:
[http://youtu.be/fAhzW4blqvM](http://youtu.be/fAhzW4blqvM) ? It looks similar
enough that I bet it's inspired by yours.

Yours is a very fun demo. I tried modifying it to move more work to the GPU. I
had the CPU only update a subset of the particles each frame and the GPU would
interpolate a curve to fill in the missing frame updates. It sorta worked. It
was N-times faster and could do more particles. But, the interpolated curves
were progressively less responsive and fun.

------
LoSboccacc
we need a remake of this now
[https://www.youtube.com/watch?v=E_87pSWYhKo](https://www.youtube.com/watch?v=E_87pSWYhKo)

'attack of the killer swarm' one of the first round of games out of
experimental gameplay project

------
thomasfoster96
Smoothest WebGL I've ever used on my iPhone. Well done whoever created this!

~~~
sebgeelen
It's this guy
([https://twitter.com/boblemarin](https://twitter.com/boblemarin)). I know
him, and he is pretty damn good.

~~~
boblemarin
:)

------
tripzilch
Loving the fact that this runs so smoothly on my old netbook.

------
hmottestad
Works perfectly on my macbook pro 15" retina from 2012.

------
LaSombra
Works fine on my Lenovo T530 with Fedora 21

~~~
crossroads091
Why the hate?

------
vixen99
Definitely minimal on my Firefox

~~~
imron
I had the same problem - then I realised you need to click/drag the mouse.

------
niche
would be cool if you could somehow output this to audio

