Hacker News new | past | comments | ask | show | jobs | submit login
Fibre:A WebGL application for visualizing 3D vector fields and dynamical systems (github.com/portsmouth)
146 points by corysama on Jan 4, 2019 | hide | past | favorite | 34 comments



Lovely code! Thanks for sharing.

Oh cool, TIL you can dispatch a fake click event on an invisible anchor element pointing to a png object url to download a file, without even putting the anchor in the document! I presume it all just gets garbage collected with it's done. I would have never have thought to attempt that, but it works like a charm, in just a few lines.

https://github.com/portsmouth/fibre/blob/master/js/fibre.js#...

        case 80: // P key: save current image to disk
        {
            if (fibre.editing) break;
            var link = document.createElement('a');
            link.download = "fibre.png";
            this.render_canvas.toBlob(function(blob){
                    link.href = URL.createObjectURL(blob);
                    var event = new MouseEvent('click');
                    link.dispatchEvent(event);
                },'image/png', 1);
            break;
        }


The link.download is the important point: in DOM terms that’s <a download="fibre.png"> which specifies that the resource should be downloaded with a filename of fibre.png.


If I'm not mistaken, this is a library to solve and visualize dynamical systems defined by a 3D vector field. It does not allow for the visualization of the vector field, as the title suggests.

Still a cool app, but with a slightly misleading title.


Yes, that's what I thought. So are these pretty pictures visualisations of scalar fields?

EDIT: or maybe like iso-lines (is that what you call them?) lines connecting points with the same value?


They are basically visualizations of the "integral curves" defined by the vector field.

https://en.wikipedia.org/wiki/Integral_curve

You can think of the vector field as the definition of a differential equation, i.e. it gives the rate of change of each coordinate at each point. The solution of the differential equation, given a start point, is then some curve, which is locally tangent to the vector field at every point.

I think one is usually more interested in the solution curves than in the vector field itself, particularly in 3d. As the vector field itself would render as a cloud of little isolated lines which don't reveal much structure, whereas the solution curves show a lot of structure (for sufficiently dense lines, forming 3d structures like ribbons, sheets, helices, etc.).

In 2d, one can get away with rendering little arrows and still produce a decent looking visualization, e.g. https://github.com/anvaka/fieldplay (which I would agree, is a genuine "vector field renderer").


More like field-lines or flow lines that trace out the trajectory of a "particle" obeying the given dynamical laws.


Looks cool but could use some speed optimisations, it really slows down browser responsiveness. For instance, all points in the attractor seem to be recalculated when rotating.

It could use better controls for changing the attractor constants. Changing those constants can really give you a good feeling of what chaos and strange attractors really are.

Some of the controls also feel a bit hard to handle, you might want to look into doing custom controls or looking at UX a bit more.

What could also be nice is an option to eliminate the first few thousand iterations (yellow box and red start) to only show the stable orbits.

Are you using web workers for this? I did a similar web thing years back which could output millions of iterations into animations like this https://assets0.ello.co/uploads/asset/attachment/3485091/ell... so I'll be sure to sift through your code to look how you tackled it.


Hi Sjeiti, I wrote this, thanks for the comments.

Agreed it needs some optimization. The reason the attractor gets recalculated when rotating, is that there is actually no geometry at all..

This is different from the approach used in e.g. https://syntopia.github.io/StrangeAttractors/, where the Runge-Kutta integration is done is JS and converted to geo. The advantage of that approach is that the rotation is smooth (and there is no shader recompilation), but the number of lines/tubes is limited by the time for JS to do the RK integration.

In my approach, the image is generated fresh from each viewpoint as follows: - initialize a floating point texture A with the start points - in a shader, update all points in parallel to their next position, via R-K, writing to texture B - draw all of the GL line segments via a vertex shader which reads the line endpoints from the textures A and B (with lighting done in the line fragment shader) - composite the result into the framebuffer - repeat for the number of integration timesteps, ping-ponging A/B - iterate over frames, with the start points jittered, blending each frame equally

This renders the thick tubes over time.

This way the integration happens entirely in shaders, with JS never seeing any geometry. So a really huge effective amount of geometry can be rendered (billions of lines?). The disadvantage is that the integration is re-done for every viewpoint, and also the GLSL shader is recompiled whenever the vector field changes. I was optimizing here for detail of the visualization more than for smoothness of the interaction -- but I would like to improve the interactivity for sure.

(There's no web workers involved -- except during GIF rendering, with uses the very nice lib https://jnordberg.github.io/gif.js/).

>It could use better controls for changing the attractor constants. Changing those constants can really give you a good feeling of what chaos and strange attractors really are.

>Some of the controls also feel a bit hard to handle, you might want to look into doing custom controls or looking at UX a bit more.

I'm keen to know where I can improve the controls. For the number/color scrubbing in the code editor I just use http://enjalot.github.io/Inlet/ pretty much out-of-the-box. It does seems a little clunky, though generally I really like the notion of the UI being integrated with the code like this.


I'm not certain - are you using orthographic or perspective rendering of the generated fields? I only ask because it seemed like the "source box" (I don't know what to call it - just something I saw as a wireframe in the Lorenz demo) seemed orthographic.

If so - it'd be nice to be able to switch between the two using the parameter controls or something; I understand why on a tool like this you'd want the orthographic view, but from an aesthetic perspective, having the perspective view would be nice to look at.

I'm not the audience, though, for this kind of tool - I barely understand what's being done (the math is way above my pay grade, but the simulation and visualization code is neat to see in action, and I could imagine potential artistic rendering uses for the tool).

EDIT: Looking at the code, it seems like you set up the camera to be in perspective mode - so I don't know why that "source box" thing I saw appears to be orthographic? Regardless, having both modes available might be useful (and maybe - on thinking about it - some kind of "bounding box" labeled grid on three sides?)...


It's doing a perspective rendering. You can change the camera FOV in the controls (which approaches orthographic as the FOV goes to zero). I could add a specific orthographic mode though perhaps.


>What could also be nice is an option to eliminate the first few thousand iterations (yellow box and red start) to only show the stable orbits.

That’s a good idea, will try it.


Looks like it's spinning on checking the framebuffer status, which is probably not something that needs to be done as frequently as it is. Putting that in a better spot would likely make it much more interactive.


I will investigate, thanks!


It appears to work much better in Firefox for me


I have a question.

My personal curiosity only. I love magnets and a have a couple of them.

Do you know any cheap or free tools, that work in the browser/osx/linux and can simulate how magnets interact?

How 2 or 3 magnets interact with each other, how magnetic forces interact etc.

It must not be 100% accurate, just ballpark estimation for fun playtime :)


The following is a visualization of electric field lines (for a "quadrupole" of charges):

https://twitter.com/jamportz/status/1079777103892135936 https://tinyurl.com/y859v78t

For magnetic fields, the problem is there are no simple (non-trivial) solutions for the magnetic fields of interesting things like a bar magnet. Even the magnetic field of a circular loop of current involves elliptic integrals. (see e.g. https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/200100...).

What you could do is numerically solve the https://en.wikipedia.org/wiki/Biot%E2%80%93Savart_law (given your currents) inside the GLSL shader.. Though this will probably be very slow..


Quickfield has a free "student edition":

https://quickfield.com/index.htm

I also recall there being at one time a DOS-based magnetic field simulation software, but I can't recall the name of it. Probably could find it (or at least the shareware version) in a simtel archive somewhere.

If you really want a better answer for this, look into browsing and asking around one of the various "magnetic overunity" perpetual motion/energy sites out there. Tons of people out there using such software trying to crack the laws of thermodynamics and extract "free energy" from magnets - here's a start down that wormhole:

http://jnaudin.free.fr/


Yes! I would love to help out if someone starts with the basic structure of such a project.

I've been searching for something like this for years.


This app is pretty decent: https://www.falstad.com/vector3dm/

Looking at the source code, indeed many of the magnetic fields are computed via the Biot-Savart law, though some interesting ones are not. I might try rendering them.


Why not use a physics engine? Model the magnetism as attractive/repulsive forces.


Pretty cool! @jamportz you should look into rendering the static separatrices along with the advected points/streamlines. It’s both fun to do and really increases the usefulness of the imagery to have some visual analysis. (This discussion might help with implementation details, if you’re interested: https://mathematica.stackexchange.com/questions/80284/plotti...)


Thanks for the suggestion, that does look like a nice way to visualize the structure of the phase space.

I'm not sure it's easy to implement this though, as it requires first solving for the equilibrium points of the flow, which in general requires solving a set of non-linear equations. That could maybe be attempted numerically, but it's likely to be difficult to make it fast/robust (not to mention, to implement it at all in WebGL shaders).

Also, in three dimensions are the separatrices still lines, or they can also be 2d surfaces? I'm not sure how they would be rendered if they can live on surfaces


It's definitely harder to implement than advection, yes. But IIRC it wasn't too bad at least for the Lorenz attractor. It has been a long time since I did my own Lorenz visualizer. Some systems certainly might be tougher. Pretty sure I did the separatrices numerically.

Separatrices can be surfaces in 3d systems. I suspect surfaces are less common than curves, but I'm just guessing. And maybe if you want it to be general, then how common is irrelevant anyway.



On macOS I got it to work with Chrome but not Safari. It did not work on iOS.


It uses WebGL 2, which Apple has not implemented.


Looks awesome! When I see those nebulas, I want to take my space shuttle and explore them ;-)

The controls could use some love.


Any specific suggestions would be appreciated! Cheers, - jamie


Currently, it feels like there is some point in front of the camera around which the camera rotates (mouse1). The mode I am missing is more like a first-person mode. The rotation point should be at (or slightly behind) the camera position.

In addition, increasing the step size of 'W-A-S-D' plus a 'sprint/boost' modifier (shift) would make navigating around a bit more fun.

Another idea would be to allow some kind of fluid movement and give the camera some momentum, but that is probably not possible with the current renderer as it seems to refresh the whole scene as soon as the position changes. Nevertheless, in such a scenario the mouse-wheel could be used to set the movement speed.

Just suggestions, take what you like ;-)


OK, good suggestions, i'll look into improving it. Cheers!


It fails on Chrome Android with an invalid framebuffer message.


It should work if WebGL 2 is supported, though possibly there could be missing extension issues. I haven't tried it on Android, will try to do so.

I'm not sure it will be usable anyway on a mobile device (https://github.com/dataarts/dat.gui is not very mobile friendly, and it requires too much fine control for fingers I think).


It tried it on an LG X Power, which has 100% WebGL 2.0 support.

Yeah the UI is rather tiny.


This is great!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: