I spotted a small error in the Finally, Colors. section:
const color = floor(random() * palette.length);
...should probably be const paletteIdx = floor(random() * palette.length);
const color = palette[paletteIdx];If you don't know about it already, Gorilla Sun has a newsletter that this would be perfect for [0].
I see that some of your generative art i this styles has multicoloured flow lines, is that just random or are the splits computed somehow?
I even wrote a small UI using Rust and egui to render the drawings in real-time just to play around with that specific part. It looks like this https://imgur.com/a/Zfp1ls3 and is open source https://github.com/damoonrashidi/generative-art/tree/develop...
[1]: https://en.wikipedia.org/wiki/Projection_method_(fluid_dynam...
But! I’m not sure divergence free noise would necessarily solve any problems for what this artist is trying to achieve. The art he’s generating is currently making use of the field’s divergence and convergence properties; in the images it’s important that lines move further apart and become less dense sometimes, and then converge and become more dense in other places. The divergence can be ugly if you see too much of it or identify the pattern, and that’s a big reason the article uses collision detection to terminate converging lines. But the finished images he shows are also setting the noise scale and framing the image manually in order to maximize the benefits of the divergent noise, and minimize the downsides.
When I googled for the paper I found a few interesting links about curl noise:
2d example: https://al-ro.github.io/projects/curl/
3d example: https://al-ro.github.io/projects/embers/
Houdini offers curl noise. Houdini is amazing for generative art, btw, and has a free personal learning edition.
Docs: https://www.sidefx.com/docs/houdini/nodes/vop/curlnoise.html
Example usage: https://entagma.com/houdini-curl-noise-flow/
I suspect you could encode (some) flow fields in neural cellular automata though. "Some" because "flow fields" aren't too strictly defined I'd say, so some of the more creative variations might not quite fit within the constraints of neural cellular automata.
So I guess it depends on the angle from which you approach it. Probably not from the "default" angles that most people use for either topic. OTOH finding an unexpected connection by looking at both in a non-obvious way might be fruitful though!
I'll try to make an edit to the article where I try it out when I'm off work.
Thanks for the tip!
[1] https://developer.mozilla.org/en-US/docs/Web/API/SVGGeometry...
[2] https://developer.mozilla.org/en-US/docs/Web/API/SVGGeometry...
What I hoped to add to the topic was making it even more accessible for people who maybe haven't even heard of generative art yet, as well as provide some interactive illustrations to help showcase their behaviors. Hopefully that doesn't come across as me trying to take credit for his work, because I find the stuff he makes (his articles even more than his artworks sometimes) super influential.
I don't know it that mess of a paragraph was understandable, but hopefully it answers your question!
I feel justified now and can finally sleep well knowing the time I spent manually formatting the code blocks so they wouldn't have horizontal scroll wasn't wasted!
Every time I visit though, I can see it hasn't been updated to replace the java or flash bits.
First, I could only imagine playing ASCII like games (such as old Roguelikes, especially ones with outside worlds, such as OMEGA[0], with this as animating the fields, waters, etc - would be interesting.
However, I was really drawn to how this might be used on GIS pointclouds, topographical maps (for animating flows down topographic GIS data?)
[0] http://crpgaddict.blogspot.com/2011/05/game-55-omega-1988.ht...
For mine, I make fields by superimposing a bunch of harmonic functions. By playing with different periods, phases, etc. you can get some cool patterns that look irregular and interesting, though I think they have a different feel from some of these noise-based examples.
I also make some fields by using sources and sinks: a collection of points that push out or in. You don't need that many to make an interesting field.
For collision detection I use the trick @danbruc mentioned in another comment: I draw to an offscreen canvas, and just check pixel color to see if a trace is already there. It's probably very costly in terms of memory as a data structure, but it's very convenient :) https://www.instagram.com/p/CMi4QcXn6_y/?img_index=1
For me the interest has come in coloring the lines — by deferring rendering until after the path has been plotted, you can color different traces according to how long they are, how much they curve or change, etc. which can reveal interesting bits about the flow structure. https://www.instagram.com/p/CMvqZjkHYpV/?img_index=1
Thanks for this great writeup @tehrash, the explanations and examples are great!
It was a fun little hack, I didn't realize this is a thing. I was just messing around with an idea of pushing particles through a cube of tri-linearly interpolated direction vectors, without simulating any actual physics like mass/friction/fluids or anything like that.
Something which surprised me was during development I just populated the cube of vectors with randomized vectors, fully expecting I'd have to do something more intentional and clever before it was interesting to watch. But the emergent structure of the flow paths even with the pseudo-random vectors was surprisingly interesting and I just left it at that, with the addition of a second randomized field the direction vectors would be interpolated between in a ping-pong manner. When one field is dominant, it re-randomized the other, resulting in a continuously-looking evolving field...
Tinkering with graphics hacks is loads of fun.
[0] https://github.com/vcaputo/rototiller/blob/master/src/module...