You are right, a GPU can do upwards of millions of points at interactive framerates, but no, unfortunately there isn't a way to do this directly in WebGL (which is what three.js is based on). In full OpenGL/DirectX, there is something called transform feedback which does exactly what you want, but it isn't available in WebGL.
However, all hope is not lost. Before transform feedback, people made particle systems on the graphics card using render-to-texture. The idea is that you do the normal render step, but instead of given the positions of the particles in vertex arrays, you store it in textures. For example, you could store the X position in the red channel, the Y position in green, the hue in blue, and the size in alpha.
Each frame, you render to another texture with a fragment (pixel) shader which computes the new position, size/etc. Then you switch back to drawing to the screen and use the positions from this texture to draw the particles themselves. Finally, you make the "new positions texture" the positions texture, and the old positions texture becomes the new positions texture for the next frame. Basically, there is a way to output something from a shader -- a pixel shader, that is.
This is a complicated system though. I would recommend learning about shaders in general (and particularly about the ways to do texture access and render to texture) before attempting this.