Getting started with shaders: signed distance functions
jvns.ca
jvns.ca
https://www.iquilezles.org/www/articles/raymarchingdf/raymar...
iq didn't invent the technique, but he popularized it. His website has a lot of tutorials on making demoscene effects, especially for 4k intros. He is also one of the makers of shadertoy.
The other thing that gets me is these articles say "here's how you write a shader" but shaders are much more than a fragment shader over the whole screen (like what shadertoy provides).
One of the major down-sides is it's often more difficult to create the boundary surface, fewer editors and the like. More common methods are polygons, subdivision surfaces, and nurbs.
So, one common technique as you mentioned is ray-tracing, the key difference is ray-marching samples the world at intervals (often regularly spaced, but in SDFs you can search for the boundary since given any location, you know the distance to the closest surface) where ray-tracing you intersect each primitive directly, and normally build up data structures (BVH, for example) to minimize the amount of individual tests you need to do.
Another common technique, used almost exclusively in every real-time case (games, CAD tools, etc) Is rasterization, where you project the triangles into screenspace and intersect them with the pixels, the main difference being that your outer loop is now "for each triangle" rather than "for each pixel"
The differences might seem pretty subtle, and in a sense they are. But they have pretty enormous ramifications on the design of a renderer, how they handle content and their performance characteristics.
An alternate method of rendering could use the marching cubes[1] algorithm to convert the signed distance field into a triangle mesh and then render it using more conventional techniques (rasterization).
With a more standard forward rendering pipeline, you hand the geometry to the GPU as triangles, then your vertex shader tells the GPU how to move your geometry around, the GPU then handles determining which parts of which triangles are visible, then your fragment shader puts your textures on the triangles and handles lighting them.
1. https://steamcdn-a.akamaihd.net/apps/valve/2007/SIGGRAPH2007...
I wrote this blog post on writing interactive SDF shaders:
It's a fun puzzle to work out how to draw things like a question mark or on-off power icon in a fragment shader. Definitely not the easiest/quickest way to construct a UI though, especially with weak math-fu like mine.
Here I use 2D SDFs along with random mutation to generate images rendered from 1k of data. It's the Mona Lisa evolving thing again only using SDF shaders.
"Boolean" operations on these signed distance fields pretty much always cheat, except for Union, which can be done with a max(a,b) operation.
Deep Learning can be used to attempt to learn a function approximating a true signed distance field for a shape. https://deepai.org/publication/deepsdf-learning-continuous-s...
I think signed distance fields may turn out to be significantly better than old school raytracing if we can have super-optimized distance field functions!
I'm still a big fan of the union operation since GPU rasterizers can trivially hardware accelerate it, which means you can render a bunch of objects in one go and know that it will be performed at near-optimal efficiency by the GPU. I've been combining that with a packing technique to render 3 depth slices at once in RGB (plus an extra duplicate slice in A) so that I can accurately sample any point in space with a single bilinear texture read.