I bet a lovely repackaging of your work would be as a reinterpretation of Haskell programs via *Compiling to categories*.

An excellent reference is Sphere Tracing by John C. Hart: https://github.com/curv3d/curv/blob/master/docs/papers/sphere_tracing.pdf

Here’s a paper I wrote on the math behind Curv’s shape representation. It says some things that Hart does not, which are relevant to Curv: https://github.com/curv3d/curv/blob/master/docs/Theory.rst

My library of shape combinators is documented here: https://github.com/curv3d/curv/tree/master/docs/shapes

This doc explains that a shape has a distance field, and it classifies distance fields as exact, mitred, approximate, bad and discontinuous. You need to know this because shape combinators are sensitive to the class of distance field they receive as input, and they may return a worse class of distance than what they received as input. https://github.com/curv3d/curv/blob/master/docs/shapes/Shapes.rst

The documentation for each shape combinator describes its limitations with respect to the classes of distance field that it accepts as input and produces as output.

Other people have addressed this problem (of users needing to worry about distance field properties) by restricting expressiveness, limiting the set of shapes and shape combinators you can define or use. All of the related projects listed below restrict expressiveness and thereby make the abstraction less leaky.

Related projects:

ImplicitCAD is written in Haskell, and uses the same signed distance representation. No GPU compilation, and there is a fixed set of distance field operations hard coded into the library, which you have to hack to define new primitives. It’s not extensible like Curv is. No colour or animation. https://github.com/colah/ImplicitCAD

libfive uses Scheme as its extension language. It has some restrictions relative to Curv: distance functions must be closed form expressions (no conditionals, no recursion), so many Curv primitives cannot be ported. But, there is no Lipshitz continuity restriction on distance functions, so this restriction removes a burden from users. Shapes are converted to a triangle mesh before being displayed, so no fine detail, no infinite shapes. Also no colour or animation. The author, Matt Keeter, has a paper in this year’s SigGraph on compiling his closed-form distance functions to GPU shader code without using sphere tracing. This is a new algorithm: the paper and the source code are not yet available at time of writing.

The video game “Dreams” on Playstation by Media Molecule uses signed distance fields to represent all geometric shapes in the game. You can create your own content using an editor, by unioning, differencing and blending a small fixed set of geometric primitives. The set of geometric primitives and shape operators is sharply limited to make everything well behaved. The GPU implementation is quite interesting and impressive; I’m studying it with an eye to duplicating their best tricks in Curv some day. https://www.mediamolecule.com/blog/article/siggraph_2015

]]>The basic idea is to represent a 3D object as a “distance field”, i.e. a continuous function from R^3 to R that returns the distance to the object. The value of that function is zero inside the object, and grows as you get further away from it. That technique is well suited to ray marching on the GPU, because when you’re marching along the ray, evaluating the distance field at the current point gives you the size of the next step, so you can make bigger steps when the ray passes far from the object. Simple objects like spheres have distance fields that are easy to define, and simple operations on objects often correspond to simple operations on distance fields. It’s also easy to approximate things like normal direction, ambient occlusion, and even penumbras (send a ray to the light source and note how closely it passed to the occluder).

In a perfect world, we could have a combinator library in Haskell for rendering distance fields that would compile to a single GPU shader program. It’s scary how well this idea fits together.

]]>So do you have any intuition about what kind of shapes this essence you’re looking for might take?

Yes, I do. It will be simple, familiar, and general to math/types/FP folks. Sum/product/function — that sort of thing. It will explain known domain-specific operations as special cases of more general/simple operations. There will be plenty of TCMs in the API and not much else. Like Reactive’s FRP model built simply from product (Future) and function (Behavior).

As for extrapolation to yet unknown problems, my feeling is that it will practically come for free if the unification is successful.

Oh — then I guess we’re on the same track.

]]>So do you have any intuition about what kind of shapes this essence you’re looking for might take? Are you looking for the ‘SK calculus of 3D geometry’, or a higher-level view?

The notion of “real problems” is a slippery one. So often our difficulties are in the questions we’re used to asking and the old paradigms we’re attached to.

Of course it is slippery, since there are several ways to look at the same thing, which I also alluded to. But I was basically trying to say here that the ultimate ‘grand unified theory’ should be able to capture all these facets, so there will be a point where you’ll have to consider these connections. As for extrapolation to yet unknown problems, my feeling is that it will practically come for free if the unification is successful.

]]>Exposing the limitations of a model also gives me a clearer picture of it, which makes it simpler for me to reason about, although it loses a superficial appearance of simplicity in the process. Perhaps a good analogy would be my taste for Arch Linux over Ubuntu. They both share the same basic architecture, but Ubuntu hides its warts with a simple interface, having the advantage of not initially confusing a user, but the disadvantage of masking the true cause of problems that do arise, while Arch intentionally exposes the inherent complexity of its architecture, perhaps making the learning curve steeper, but also making it easier to reason about due to its full disclosure. While Ubuntu has an abstraction which Arch lacks, it is not a good abstraction because it leaks, therefore the user must learn not only the abstraction but also how it works. Masking or failing to make clear the inherent flaws of a model, I think, is kind of like a leaky abstraction.

]]>