
Fibre:A WebGL application for visualizing 3D vector fields and dynamical systems - corysama
https://github.com/portsmouth/fibre
======
DonHopkins
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#...](https://github.com/portsmouth/fibre/blob/master/js/fibre.js#L1056)

    
    
            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;
            }

~~~
robin_reala
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.

------
grondilu
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.

~~~
martijn_himself
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?

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

[https://en.wikipedia.org/wiki/Integral_curve](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](https://github.com/anvaka/fieldplay)
(which I would agree, is a genuine "vector field renderer").

------
Sjeiti
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...](https://assets0.ello.co/uploads/asset/attachment/3485091/ello-
optimized-2f17a1e9.gif) so I'll be sure to sift through your code to look how
you tackled it.

~~~
jamportz
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/](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/](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/](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.

~~~
cr0sh
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?)...

~~~
jamportz
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.

------
molszanski
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 :)

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

[https://twitter.com/jamportz/status/1079777103892135936](https://twitter.com/jamportz/status/1079777103892135936)
[https://tinyurl.com/y859v78t](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...](https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/20010038494.pdf)).

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

------
dahart
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...](https://mathematica.stackexchange.com/questions/80284/plotting-
separatrices-for-nonlinear-system))

~~~
jamportz
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

~~~
dahart
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.

------
th0ma5
Demo is the first link
[https://portsmouth.github.io/fibre/](https://portsmouth.github.io/fibre/)

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

~~~
opencl
It uses WebGL 2, which Apple has not implemented.

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

The controls could use some love.

~~~
jamportz
Any specific suggestions would be appreciated! Cheers, - jamie

~~~
arendtio
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 ;-)

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

------
pjmlp
It fails on Chrome Android with an invalid framebuffer message.

~~~
jamportz
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](https://github.com/dataarts/dat.gui) is
not very mobile friendly, and it requires too much fine control for fingers I
think).

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

Yeah the UI is rather tiny.

------
aexol
This is great!

