5.4 KiB
Brief history?
- I've done different forms of procedural graphics for awhile…
- POV-Ray is where I learned about implicit surfaces and some other kinds of parametric geometry.
- At some point I discovered Context Free and Structure Synth. (and synthopia blog and sphere tracing).
- I sort of pursued these as separate paths: implicit surfaces (great for rendering methods like sphere tracing), and parametric geometry (much easier to implement).
- It wasn't until about 2018 that I sketched out some ideas for parametric 3D geometry - based loosely around Structure Synth - and implemented some things.
- First this was some exploration of Parallel Frame Transport that I'd read about via thi.ng, and then python_extrude_meshgen.
- Things I learned there become Prosha.
- Things I learned there are at my current unnamed work.
Brief history, written out more
(TODO: a note to me, reading later: you don't need to give your entire life story here.)
(TODO: pictures will make this post make a lot more sense)
Context Free is one of my favorite projects since I discovered it about 2010. It's one I've written about before (TODO: link to my posts), played around in (TODO: link to images), presented on, as well as re-implemented myself in different ways (see: Contextual). That is sometimes because I wanted to do something Context Free couldn't, such as make it realtime and interactive, and sometimes because implementing its system of recursive grammars and replacement rules can be an excellent way to learn things in a new language.
I've also played around in 3D graphics, particularly raytracing, since about 1999 in PolyRay and POV-Ray. POV-Ray is probably what led me to learn about things like implicit surfaces, parametric surfaces, and procedural geometry - its scene language is full of constructs for that. Naturally, this led me to wonder how I might extend Context Free's model to work more generally with 3D geometry, and let me use it to produce procedural geometry.
Structure Synth of course already exists as a straightforward generalization of Context Free's model to 3D (thank you to Mikael Hvidtfeldt Christensen's blog Syntopia, another of my favorite things ever, for introducing me to it awhile ago). See also BrowserSynth. However, at some point I realized they weren't exactly what I wanted. Structure Synth lets you combine together 3D primitives to build up a more complex scene - but doesn't try to properly handle any sort of joining of these primitives in a way that respects many of the 'rules' of geometry that are necessary for a lot of tools, like having a well-defined inside/outside, not being self-intersecting, being manifold, and so forth.
Tools like OpenSCAD, based on CGAL, handle the details of this, and I suspect that Open CASCADE (thus FreeCAD) also does. In CAD work, it's crucial. I experimented with similar recursive systems with some of these, but I quickly ran into a problem: they were made for actual practical applications in CAD, not for my nonsensical generative art, and they scaled quite poorly with the sort of recursion I was asking for.
Implicit surfaces (or one of the many equivalent-except-for-when-it's-not names for this, e.g. F-Reps or distance bounds or SDFs or isosurfaces) handle almost all of this well! They express CSG (TODO: link to CSG) operations, blending shapes is easy, and they can be rendered directly on the GPU… see Syntopia again, or nearly anything by Inigo Quilez, or look up raymarching and sphere tracing, or see nTopology, or Matt Keeter's work with libfive and MPR. It's pure magic and it's wonderfully elegant and I'll probably have many other posts on this.
However, implicit surfaces still have one pretty big problem: converting them to good meshes for rendering is a huge pain. I have other posts on this as well, but for now, take it on faith. (TODO: Make those posts.)
With these limitations in mind, around 2018 June I had started jotting some ideas down. The gist is that I wanted to create "correct-by-construction" meshes from these recursive grammars. By that, I meant: incrementally producing the desired geometry as a mesh, triangle-by-triangle, in such a way that guaranteed that the resultant mesh had the desired detail level, was a manifold surface, and that it was otherwise a well-behaved mesh (e.g. no degenerate triangles, no self-intersection, no high-degree vertices) - rather than attempting to patch up the mesh after the fact, or subdivide it to the necessary detail level. The form it took in my notes was in sort of "growing" or "extruding" a mesh per these recursive rules, building in these guarantees (some of them at least) by way of inductive steps.
(TODO: Illustrate this somehow)
TODO while I'm not so tired:
- Summarize from prosha: this didn't fully work
- Summarize from python_extrude_meshgen?
- Much much easier to OpenSubdiv it