In more rigorous terms, signed distance functions (aka SDFs) are defined
as functions that satisfy a particular form of the
eikonal equation1. The general eikonal equation is of the form:
$$||\nabla u(x)|| = \frac{1}{f(x)},\quad x \in \Omega,$$
where \(\Omega\) is an open set in \(\mathbb{R}^n\), and
\(f(x) : \mathbb{R}^n \to \mathbb{R}\) is a function with positive
values. In physical terms, the solution \(u(x)\) to this nonlinear
partial differential equation can be interpreted as the shortest time
needed to travel from the boundary
\(\partial\Omega\) to \(x \in \Omega\), with \(f(x)\) being the
speed at \(x\).
Now, for a signed distance function, the speed will be unity throughout
the domain, and \(x\) will not be constrained to lie in \(\Omega\).
With \(f(x) \equiv 1\), the time to travel from the boundary
\(\partial\Omega\) to any \(x \in \mathbb{R}^n\) will simply be
equal to the shortest distance from \(x\) to \(\partial\Omega\). We
may then obtain a signed distance function \(\textsf{sdf}(x)\),
provided that the following conditions are satisfied:
Eikonal equation: $$\tag{EE} ||\nabla\textsf{sdf}(x)|| = 1,\quad x \in \mathbb{R}^3,$$
Zero distance at the boundary: $$\tag{BZ} \textsf{sdf}(x) = 0,\quad \forall \ x \in \partial\Omega,$$
Inward-facing normal at the boundary: $$\tag{IN} \nabla\textsf{sdf}(x) = N(x),\quad \forall \ x \in \partial\Omega.$$
If these conditions are satisfied, a function representing the shortest
Euclidean distance from \(x \in \mathbb{R}^n\) to a surface
\(\partial\Omega \subset \Omega \subset \mathbb{R}^n\) is obtained.
This distance is signed, meaning that when \(x \in \Omega\),
\(\textsf{sdf}(x)\) is nonnegative (\(\geq 0\)), while for
\(x \in \mathbb{R}^n \setminus \Omega\), \(\textsf{sdf}(x)\) it is
negative (\(< 0\)).
To prove that these conditions produce a distance field (disregarding
the sign for now), consider points \(x, y\) on a path of
steepest-descent, that is a path along gradient \(\nabla \textsf{sdf}\). As
established previously \(||\nabla \textsf{sdf}(x)|| = 1\)
(condition (EE)). The Euclidean distance between these two points will
be at most equal to the length of the steepest-descent path, denoted
here by \(\gamma\). We find that:
Then, considering a straight line path from \(x\) to \(y\), i.e.,
the shortest path between the two points, denoted here by \(\zeta\),
we find the following bound:
Finally, from the boundary conditions ((BZ) and (IN)),
it is ensured that the function will in fact be a signed distance
function for a given object \(\Omega\).
Differentiability
Since for certain geometries, the derivative at a point where there
exist multiple minima (e.g., along the diagonal of a rectangle), is
not defined. The points at which this is true are interesting in their
own right; as a matter of fact, this set of points is known as the
medial axis, or when this set is closed, the cut locus.
In the box below, an example of this phenomenon is given for a 2D square
SDF.
Boolean Operations (Combinations)
In order to create more complex shapes, it is reasonable to want to run
combination operatons on primitives. To get a better handle on what
these operations might be, consider the following basic examples:
Union
Difference
Intersection
Below, we consider these, and other, operations on two shapes (sets)
\(P\) and \(Q\), resulting in a set \(R\). The SDFs belonging to
these sets will be subscripted by the name of the set to which they
belong. For more information on this topic, see 2, 3.
Union
$$
R = P \cup Q \Leftrightarrow \textsf{sdf}_R (p) = \min[\textsf{sdf}_P (p), \textsf{sdf}_Q (p)].
$$
Intersection
$$
R = P \cap Q \Leftrightarrow \textsf{sdf}_R (p) = \max[\textsf{sdf}_P (p), \textsf{sdf}_Q (p)].
$$
Note:
This does not produce a proper SDF on the interior.
Difference
$$
R = P \setminus Q \Leftrightarrow \textsf{sdf}_R (p) = \max[\textsf{sdf}_P (p), -\textsf{sdf}_Q (p)].
$$
Note:
This does not produce a proper SDF on the interior.
Symmetric Difference
Also known as the disjunctive union. Expressed in words, this is the
union of the difference of the two sets.
We distinguish uniform and nonuniform scaling. In the first case, the
scaling factor is the same across all axes, while in the latter case
different scaling factors may be used on different axes.
Uniform Scaling
For uniform scaling, consider a scaling factor \(s \in \mathbb{R}_+\),
i.e, the positive orthant of \(\mathbb{R}\). It can be shown that
(see ‘Derivations’ below):
$$
\textsf{sdf}_R (p) = \textsf{sdf}_P (p/s) s .
$$
Nonuniform Scaling
As discussed in the ‘Derivation’ box below, there is no straightforward
solution to the nonuniform scaling problem that does not violate the
eikonal equation condition. The next best ‘solution’, would be to
obtain some sort of lower distance bound. This provides a
straightforward approach to obtaining a lower bound to the scale
surface, which will appear correctly when rendered, but does not have a
proper SDF. More advantages are listed in the
‘Derivation’ box below. For a similar
discussion, see 4.
Here, we consider a scaling factor \(s \in \mathbb{R}_+^3\). As a lower
bound, we obtain:
where \(s_\text{min}\) is the smallest element of \(s\), and
‘\(\oslash\)’ denotes componentwise division.
List of 2D Functions
The following signed distance functions assume that the primitive is
centered at the origin, unless stated otherwise. Most of these functions
are adapted from Inigo Quilez’s excellent
2D SDF functions article,
while others are derived from other sources in the literature.
For a rectangle, consider a 2D vector \(d\) consisting of the width
(in \(x\)-direction), and the height. Operators with the subscript \(i\)
notation (e.g., \(\textrm{abs}_i\)) will act on a vector in a
component-wise fashion (similar to Einstein’s tensor notation); see 5
for more information.
float rectangle(vec2 p, vec2 b)
{
vec2 d = abs(p)-b;
return length(max(d,0.0)) + min(max(d.x,d.y),0.0);
}
staticpublicfunctionrectangle(p:Vec2, b:Vec2):FFloat {
final d = p.abs().sub(b);
return d.max(0).length + Math.min(Math.max(d.x, d.y), 0);
}
Rounded Rectangle
The rounded rectangle follows a similar construction method to the
rectangle, although the individual corners are rounded independently,
producing a different result compared to the rectangle with uniform
rounding applied.