[HN Gopher] 2D Signed Distance Functions
       ___________________________________________________________________
        
       2D Signed Distance Functions
        
       Author : nickswalker
       Score  : 76 points
       Date   : 2025-12-24 22:41 UTC (4 days ago)
        
 (HTM) web link (iquilezles.org)
 (TXT) w3m dump (iquilezles.org)
        
       | on_the_train wrote:
       | I come back every couple of months when I have a new project
       | involving sdfs. And almost every time it's a bit of trial and
       | error figuring out the parameters. It's workable, but a minor pet
       | peeve that they're not described or named better.
       | 
       | It's a priceless resource nevertheless.
        
         | RogerL wrote:
         | I was just about to say the same thing. This is bad
         | code/documentation. Single letter variable names is almost
         | always wrong if it isn't i for an index or such (and even then,
         | would typing 'idx' kill you?). And as parameters, so much
         | worse. Don't make me guess how to call your function please.
        
       | Lerc wrote:
       | Can you freely compose signed distance functions? Obviously
       | people use them for + and - regularly. My intuition says you
       | should be able to apply *, / and more as well.
       | 
       | and sqrt( sdEquilateralTriangle(pos.xy, 10)**2 +
       | sdCircle(pos.xz,10)**2 )
       | 
       | seems like there's scope for a nice little domain specific
       | language to.
       | 
       | I think it would be interesting to have some composite operations
       | that did probabilistic branching based upon a hashing RNG to
       | conditionally combine shapes
       | 
       | something like                   float thingy(pos,r) {
       | float more = infinity           float pseudoRandom =
       | HashToUnit(pos)            if (pseudoRandom >0.5) {
       | float direction=randomAngleFromSeed(pseudoRandom+r)
       | more = thingy(pos+direction*r, r*0.75)            }
       | return  min(circle(pos,r),more)         }
        
         | sebastianmestre wrote:
         | You can take the minimum of two SDFs, which more or less gives
         | you an SDF for their union. The maximum is the intersection. A
         | few years ago I wrote a DSL that writes the SDFs for you, for
         | my university programming languages course.
         | https://github.com/SebastianMestre/school/tree/master/univer...
        
         | Sharlin wrote:
         | f * g is a symmetric difference (all zeros remain zeros, the
         | new internal points are those that are inside exactly one of f
         | and g: (-, +) -> -, (+, -) -> -, (+, +) -> +, (-, -) -> +).
         | 
         | f * g + x for some small constant x makes the symdiff smoother,
         | depending on the sign of x it makes the components either meld
         | together or "repel" each other. If the original components are
         | disjoint (or if it's 3D solids and the internal surfaces are
         | irrelevant) and x < 0, it functions as a smooth union.
         | 
         | f / g has the same inside/zero/outside behavior as f * g, but
         | is of course very pathological for all values of g close to
         | zero. I don't think it has any good uses.
        
           | jesse__ wrote:
           | f*g is good to mask one SDF by another. I use it all the time
           | in my little voxel engine.
        
         | jesse__ wrote:
         | There's a bit to unpack here.
         | 
         | There are two things one might care about when computing an SDF
         | .. the isosurface, or the SDF itself.
         | 
         | If you only care about the isosurface (ie. where the function
         | is 0), you can do any ridiculous operations you can think of,
         | and it'll work just fine. Add, sub, multiply, exp .. whatever
         | you want. Voxel engines do this trick a lot. Then it becomes
         | more of a density field, as apposed to a distance field.
         | 
         | If you care about having a correct SDF, for something like
         | raymarching, then you have to be somewhat more careful. Adding
         | two SDFs does not result in a valid SDF, but taking the min or
         | max of two SDFs does. Additionally, computing an analytical
         | derivative of an SDF breaks if you add them, but you can use
         | the analytical derivative if you take a min or max. Same
         | applies for smooth min/max.
        
           | Lerc wrote:
           | I did some simple experiments and fairly swiftly discovered
           | where I went wrong. I'm still not totally convinced that
           | there isn't something clever that can be done for more
           | operations.
           | 
           | My next thought is maybe you can do some interesting
           | shenanigans by jumping to the nearest point on one surface
           | then calculating a modulation that adjusts the distance by an
           | amount. I can certainly see how difficult it would become if
           | you start making convex shapes like that though. There must
           | be a way to take the min of a few candidates within the
           | radius of a less precise envelope surface.
        
             | jesse__ wrote:
             | I think you might be describing smoothmin?
             | 
             | https://iquilezles.org/articles/smin/
        
       | jesse__ wrote:
       | I owe iq so much; a living legend. Inigo, if you happen to ever
       | read this, thanks so much for all the work you've published. Your
       | Youtube videos (not to mention shadertoy) sparked an interest in
       | graphics I never knew I had.
       | 
       | For anyone that's unfamiliar, his Youtube videos are extremely
       | well put together, and well worth the handful of hours to watch.
       | 
       | https://www.youtube.com/c/InigoQuilez
        
       ___________________________________________________________________
       (page generated 2025-12-28 23:00 UTC)