<p>Let <span class="math-container">$f:\mathbb{R}^n\to \mathbb{R}$</span> be a <em>signed distance function</em> for the set <span class="math-container">$\mathbb{R}^n \setminus \Omega$</span>, meaning:
<span class="math-container">$$f(p) = \begin{cases} d(p, \partial\Omega), &amp; p \in \Omega, \\ -d(p,\partial\Omega), &amp; p \not\in \Omega,\end{cases}$$</span>
where <span class="math-container">$d(p, A) = \inf_{q\in A} \|p-q\|_2$</span> is the shortest euclidean distance between <span class="math-container">$p$</span> and <span class="math-container">$A$</span>. In other words the surface <span class="math-container">$\partial\Omega$</span> is given as the set of zeroes of <span class="math-container">$f$</span>:
<span class="math-container">$$\partial\Omega = f^{-1}(0) = \{p\in \mathbb{R}^3\,:\,f(p)=0\}.$$</span></p>
<p>Now consider a <em>signed distance bound function</em> <span class="math-container">$g$</span> for <span class="math-container">$f$</span>. This means that <span class="math-container">$g^{-1}(0) = \partial\Omega = f^{-1}(0)$</span>, <span class="math-container">$g$</span> is continuous, and <span class="math-container">$|g|$</span> is upper bounded by <span class="math-container">$|f|$</span>: <span class="math-container">$|g(p)|\leq |f(p)|$</span>.</p>
<p>If you assume that <span class="math-container">$f$</span> is continuously differentiable almost everywhere on some open set covering <span class="math-container">$\partial\Omega$</span> then you can unambiguously define the normal as <span class="math-container">$n(p) = \nabla f(p)$</span> for <span class="math-container">$p\in\partial\Omega$</span> almost everywhere (note that <span class="math-container">$\|\nabla f(p)\|_2=1$</span> so the normal is unit length). For what you asked to work one needs that <span class="math-container">$g$</span> is differentiable almost everywhere on <span class="math-container">$\partial\Omega$</span>, and moreover <span class="math-container">$\nabla g(p) = \lambda \nabla f(p)$</span> for <span class="math-container">$p\in\partial\Omega$</span> and <span class="math-container">$\lambda&gt;0$</span>, i.e. it is a first order approximation of <span class="math-container">$f$</span> around <span class="math-container">$\partial\Omega$</span> up to a positive constant <span class="math-container">$\lambda &gt;0$</span>: <span class="math-container">$$g(p+v) = g(p) + v\cdot \nabla g(p) + o(\|v\|^2) = v\cdot (\lambda\nabla f(p)) + o(\|v\|^2),\quad p\in\partial\Omega.$$</span></p>
<p>Now consider <span class="math-container">$g(p) = -f(p)$</span>. The function <span class="math-container">$g$</span> clearly satisfies all of the conditions for a signed distance bound but has a normal that points in the opposite direction. That's one possible fail case. A condition to disallow this would be to require that <span class="math-container">$0\leq g(p) \leq f(p)$</span> for <span class="math-container">$p\in\Omega$</span> and <span class="math-container">$0\leq -g(p) \leq -f(p)$</span> for <span class="math-container">$p\not\in\Omega$</span>, instead of <span class="math-container">$|g(p)|\leq |f(p)|$</span> in the definition of signed distance bound function. Then it cannot happen that <span class="math-container">$\nabla g(p)$</span> is outside of the hemisphere around <span class="math-container">$\nabla f(p)$</span> as otherwise we could move along it and get that <span class="math-container">$g(p)$</span> is negative where <span class="math-container">$f(p)$</span> is positive (i.e. in <span class="math-container">$\Omega$</span>) but then <span class="math-container">$g(p) &lt;0$</span> which violates <span class="math-container">$g(p)\geq 0$</span> for <span class="math-container">$p\in\Omega$</span>. So this case is taken care of by a small modification of the definition in Hart's paper.</p>
<p>Now let <span class="math-container">$\nabla g(p)\ne 0$</span> and <span class="math-container">$\nabla g(p) \not \parallel \nabla f(p)$</span>. Consider the vector <span class="math-container">$w = \nabla g(p) - \bigl(\nabla f(p) \cdot \nabla g(p)\bigr) \nabla f(p)$</span> which is perpendicular to <span class="math-container">$\nabla f(p)$</span> but has a positive dot product with <span class="math-container">$\nabla g(p)$</span>. The function <span class="math-container">$\psi(h) = g(p+hw)$</span> grows faster than <span class="math-container">$\phi(h) = f(p+hw)$</span> with <span class="math-container">$h$</span> increasing (at least for <span class="math-container">$h$</span> sufficiently close to <span class="math-container">$0$</span>), which means that we can make <span class="math-container">$g(q) &gt; f(q)$</span> for <span class="math-container">$q=p+hw$</span>, <span class="math-container">$h$</span> small enough and <span class="math-container">$p\in\partial\Omega$</span> since:
<span class="math-container">$$g(p+hw) \approx g(p) + hw \cdot \nabla g(p)&gt; 0 = f(p)+h w \cdot \nabla f(p) \approx f(p+hw).$$</span>
This means that allowing non-parallel and non-zero <span class="math-container">$\nabla g(p)$</span> for <span class="math-container">$p\in\partial\Omega$</span> would also violate the signed distance bound conditions.</p>
<p>Finally, if <span class="math-container">$\nabla g(p) = 0$</span> for every point <span class="math-container">$p\in\partial\Omega$</span> (or at
least for a subset that is not of measure zero) we have a problem. This can occur in practice for example for a half-space SDF: <span class="math-container">$f(x,y,z) = z$</span> and the following SDBF:
<span class="math-container">$$g(x,y,z) = \begin{cases} z, &amp; |z|\geq 1, \\ z^3, &amp; |z|&lt;1.\end{cases}$$</span>
So we additionally need to assume that the SDBF function <span class="math-container">$g$</span> is chosen such that <span class="math-container">$\nabla g(p) \ne 0$</span> almost everywhere on <span class="math-container">$\partial\Omega$</span>.</p>
<p>TLDR: You can use the normalized gradient <span class="math-container">$\frac{\nabla g(p)}{\|\nabla g(p)\|_2}$</span> of a signed distance bound function <span class="math-container">$g$</span> (whose derivative is non-zero) as <span class="math-container">$\pm$</span> the normal <span class="math-container">$n(p)$</span> at a surface point <span class="math-container">$p\in\partial\Omega$</span> since the signed distance bound conditions guarantee that it is parallel to the gradient <span class="math-container">$\nabla f(p) \equiv n(p)$</span> of the corresponding signed distance function <span class="math-container">$f$</span>. Replacing the signed distance bound condition <span class="math-container">$|g(p)|\leq |f(p)|$</span> from Hart's paper with <span class="math-container">$0\leq g(p)\leq f(p)$</span> for <span class="math-container">$p\in\Omega$</span> and <span class="math-container">$0\leq -g(p)\leq -f(p)$</span> for <span class="math-container">$p\not\in\Omega$</span> allows you to dispense away with the <span class="math-container">$\pm$</span> (i.e. you get the correctly facing normal).</p>
<p>Practical considerations: If <span class="math-container">$g$</span> deviates strongly from <span class="math-container">$f$</span> near the boundary then the numerical approximation of the gradient may require smaller step sizes. But as already mentioned in my comments, getting the step sizes right is a difficult problem even when using the sdf <span class="math-container">$f$</span> and not a signed distance bound function (sdbf) <span class="math-container">$g$</span>.</p>

CC BY-SA 4.0
2024-10-04T15:19:05.550Z
Thanks for writing up a formal argument, a pleasure to read. (Though I admit that having done only so much math, it takes effort for someone like me to understand well, but I got the key idea of the argument)
jmichael
CC BY-SA 4.0
2024-10-04T23:10:59.200Z
@jmichael I have updated the answer since, notably my assumption that $\nabla g(p) = 0$ cannot occur on regions of non-zero measure was false and I have provided a counterexample. The initial counterexample was not provided by me: https://math.stackexchange.com/a/4980330/463794
This means that you have to make sure that your SDBF has a non-zero gradient almost everywhere on $\partial\Omega$, otherwise you can run into degenerate cases w.r.t. the normal.
lightxbulb
CC BY-SA 4.0
2024-10-04T11:11:40.320Z
2024-10-04T23:09:02.270Z
2024-10-04T23:09:02.270Z
lightxbulb
<p>In <a href="https://graphics.stanford.edu/courses/cs348b-20-spring-content/uploads/hart.pdf" rel="nofollow noreferrer">John Hart's paper</a>, at page 5-94 he mentions that - &quot;The surface normal function can be avoided by using a
general six-sample numerical gradient approximation of the distance bound gradient&quot;. I have some difficulty in understanding how a distance bound (as opposed to an exact distance) function can be used in this way.</p>
<p>Suppose for example, that we apply a non-uniform scaling, scaling along the x-axis. Distance along the y-axis remain unaffected, while those along the x-axis are scaled. In general, the scaling depends on the inclination with respect to the x axis.</p>
<p>If we only have the original distance function (before non-uniform scaling) at hand, we can divide uniformly by the scaling factor to get a distance bound. But this function would serve poorly as an approximation for the gradient, as distance in different directions are essentially in different &quot;units&quot;, so the normal would come out skewed wouldn't it? (Even if we sample points very close to the surface)</p>
<p>Is it that only specific kinds of distance bounds can be used for approximating the normal in this way? What technique is generally used for computing normals when you only have a distance bound?</p>

CC BY-SA 4.0
2024-09-29T10:45:00.063Z
My guess is that since $f(p)=0$ must still hold at the points of the surface, and that $f$ is continuous, as you get closer to the boundary the normal must converge to the actual one.
lightxbulb
CC BY-SA 4.0
2024-09-30T09:07:32.063Z
Hmm, I see. This is quite enlightening, thanks for the comment, that makes sense. I was reasoning this way - if f approximates g, then it doesn't necessarily follow that the derivative of f approximates that of g. Which is true of course, but approximation at one point, and approximation over a surface are quite different.
jmichael
CC BY-SA 4.0
2024-09-30T10:15:34.923Z
To be precise you probably need a bit more than continuity.
lightxbulb
CC BY-SA 4.0
2024-09-30T14:42:52.237Z
Yeah, it would also need to be differentiable, at least
jmichael
CC BY-SA 4.0
2024-09-30T16:05:46.023Z
Actually that's not necessary with the numerical approximation, it would still work for functions that are almost everywhere differentiable (you can see this from the box sdf for example), and I think those constraints can be relaxed further. I would prefer using the analytical gradient most of the time though, as the step size in the numerical approximation is notoriously hard to get right.
lightxbulb
CC BY-SA 4.0
2024-10-01T13:20:11.843Z
Yes, I've read that hit and trial is usually the preferred method to get the step size, when you apply some unusual transformation that gives only a distance bound. I'm sort of a first timer on Stack Exchange. Since I think you've addressed nearly everything (thanks!), what would be the appropriate way to close the question?
jmichael
CC BY-SA 4.0
2024-10-01T14:59:05.587Z
Someone (could be you, could be @lightxbulb, could be someone else) should write and post an answer (that can then be marked as accepted, if you like it). Questions should not be left with only comments.
Kevin Reid
<normal-mapping><raymarching><signed-distance-field>
Approximating surface normals from signed distance bounds
jmichael
# Approximating surface normals from signed distance bounds

(Asked by: username_0 on 2024-09-28)

In [John Hart's paper](https://graphics.stanford.edu/courses/cs348b-20-spring-content/uploads/hart.pdf), at page 5-94 he mentions that - "The surface normal function can be avoided by using a
general six-sample numerical gradient approximation of the distance bound gradient". I have some difficulty in understanding how a distance bound (as opposed to an exact distance) function can be used in this way.

Suppose for example, that we apply a non-uniform scaling, scaling along the x-axis. Distance along the y-axis remain unaffected, while those along the x-axis are scaled. In general, the scaling depends on the inclination with respect to the x axis.

If we only have the original distance function (before non-uniform scaling) at hand, we can divide uniformly by the scaling factor to get a distance bound. But this function would serve poorly as an approximation for the gradient, as distance in different directions are essentially in different "units", so the normal would come out skewed wouldn't it? (Even if we sample points very close to the surface)

Is it that only specific kinds of distance bounds can be used for approximating the normal in this way? What technique is generally used for computing normals when you only have a distance bound?

**Tags:** normal-mapping, raymarching, signed-distance-field

> **Comments:**
> **username_1**: My guess is that since $f(p)=0$ must still hold at the points of the surface, and that $f$ is continuous, as you get closer to the boundary the normal must converge to the actual one.  
> **username_0**: Hmm, I see. This is quite enlightening, thanks for the comment, that makes sense. I was reasoning this way - if f approximates g, then it doesn't necessarily follow that the derivative of f approximates that of g. Which is true of course, but approximation at one point, and approximation over a surface are quite different.  
> **username_1**: To be precise you probably need a bit more than continuity.  
> **username_0**: Yeah, it would also need to be differentiable, at least  
> **username_1**: Actually that's not necessary with the numerical approximation, it would still work for functions that are almost everywhere differentiable (you can see this from the box sdf for example), and I think those constraints can be relaxed further. I would prefer using the analytical gradient most of the time though, as the step size in the numerical approximation is notoriously hard to get right.  
> **username_0**: Yes, I've read that hit and trial is usually the preferred method to get the step size, when you apply some unusual transformation that gives only a distance bound. I'm sort of a first timer on Stack Exchange. Since I think you've addressed nearly everything (thanks!), what would be the appropriate way to close the question?  
> **username_2**: Someone (could be you, could be @username_1, could be someone else) should write and post an answer (that can then be marked as accepted, if you like it). Questions should not be left with only comments.  

---

## 1 answers

### Answer by username_1 on 2024-10-04. Score: 3 | Accepted answer

Let $f:\mathbb{R}^n\to \mathbb{R}$ be a *signed distance function* for the set $\mathbb{R}^n \setminus \Omega$, meaning:
$$f(p) = \begin{cases} d(p, \partial\Omega), & p \in \Omega, \\ -d(p,\partial\Omega), & p \not\in \Omega,\end{cases}$$
where $d(p, A) = \inf\_{q\in A} \|p-q\|\_2$ is the shortest euclidean distance between $p$ and $A$. In other words the surface $\partial\Omega$ is given as the set of zeroes of $f$:
$$\partial\Omega = f^{-1}(0) = \{p\in \mathbb{R}^3\,:\,f(p)=0\}.$$

Now consider a *signed distance bound function* $g$ for $f$. This means that $g^{-1}(0) = \partial\Omega = f^{-1}(0)$, $g$ is continuous, and $|g|$ is upper bounded by $|f|$: $|g(p)|\leq |f(p)|$.

If you assume that $f$ is continuously differentiable almost everywhere on some open set covering $\partial\Omega$ then you can unambiguously define the normal as $n(p) = \nabla f(p)$ for $p\in\partial\Omega$ almost everywhere (note that $\|\nabla f(p)\|\_2=1$ so the normal is unit length). For what you asked to work one needs that $g$ is differentiable almost everywhere on $\partial\Omega$, and moreover $\nabla g(p) = \lambda \nabla f(p)$ for $p\in\partial\Omega$ and $\lambda>0$, i.e. it is a first order approximation of $f$ around $\partial\Omega$ up to a positive constant $\lambda >0$: $$g(p+v) = g(p) + v\cdot \nabla g(p) + o(\|v\|^2) = v\cdot (\lambda\nabla f(p)) + o(\|v\|^2),\quad p\in\partial\Omega.$$

Now consider $g(p) = -f(p)$. The function $g$ clearly satisfies all of the conditions for a signed distance bound but has a normal that points in the opposite direction. That's one possible fail case. A condition to disallow this would be to require that $0\leq g(p) \leq f(p)$ for $p\in\Omega$ and $0\leq -g(p) \leq -f(p)$ for $p\not\in\Omega$, instead of $|g(p)|\leq |f(p)|$ in the definition of signed distance bound function. Then it cannot happen that $\nabla g(p)$ is outside of the hemisphere around $\nabla f(p)$ as otherwise we could move along it and get that $g(p)$ is negative where $f(p)$ is positive (i.e. in $\Omega$) but then $g(p) <0$ which violates $g(p)\geq 0$ for $p\in\Omega$. So this case is taken care of by a small modification of the definition in Hart's paper.

Now let $\nabla g(p)\ne 0$ and $\nabla g(p) \not \parallel \nabla f(p)$. Consider the vector $w = \nabla g(p) - \bigl(\nabla f(p) \cdot \nabla g(p)\bigr) \nabla f(p)$ which is perpendicular to $\nabla f(p)$ but has a positive dot product with $\nabla g(p)$. The function $\psi(h) = g(p+hw)$ grows faster than $\phi(h) = f(p+hw)$ with $h$ increasing (at least for $h$ sufficiently close to $0$), which means that we can make $g(q) > f(q)$ for $q=p+hw$, $h$ small enough and $p\in\partial\Omega$ since:
$$g(p+hw) \approx g(p) + hw \cdot \nabla g(p)> 0 = f(p)+h w \cdot \nabla f(p) \approx f(p+hw).$$
This means that allowing non-parallel and non-zero $\nabla g(p)$ for $p\in\partial\Omega$ would also violate the signed distance bound conditions.

Finally, if $\nabla g(p) = 0$ for every point $p\in\partial\Omega$ (or at
least for a subset that is not of measure zero) we have a problem. This can occur in practice for example for a half-space SDF: $f(x,y,z) = z$ and the following SDBF:
$$g(x,y,z) = \begin{cases} z, & |z|\geq 1, \\ z^3, & |z|<1.\end{cases}$$
So we additionally need to assume that the SDBF function $g$ is chosen such that $\nabla g(p) \ne 0$ almost everywhere on $\partial\Omega$.

TLDR: You can use the normalized gradient $\frac{\nabla g(p)}{\|\nabla g(p)\|\_2}$ of a signed distance bound function $g$ (whose derivative is non-zero) as $\pm$ the normal $n(p)$ at a surface point $p\in\partial\Omega$ since the signed distance bound conditions guarantee that it is parallel to the gradient $\nabla f(p) \equiv n(p)$ of the corresponding signed distance function $f$. Replacing the signed distance bound condition $|g(p)|\leq |f(p)|$ from Hart's paper with $0\leq g(p)\leq f(p)$ for $p\in\Omega$ and $0\leq -g(p)\leq -f(p)$ for $p\not\in\Omega$ allows you to dispense away with the $\pm$ (i.e. you get the correctly facing normal).

Practical considerations: If $g$ deviates strongly from $f$ near the boundary then the numerical approximation of the gradient may require smaller step sizes. But as already mentioned in my comments, getting the step sizes right is a difficult problem even when using the sdf $f$ and not a signed distance bound function (sdbf) $g$.

> **Comments:**
> **username_0**: Thanks for writing up a formal argument, a pleasure to read. (Though I admit that having done only so much math, it takes effort for someone like me to understand well, but I got the key idea of the argument)  
> **username_1**: @username_0 I have updated the answer since, notably my assumption that $\nabla g(p) = 0$ cannot occur on regions of non-zero measure was false and I have provided a counterexample. The initial counterexample was not provided by me: https://math.stackexchange.com/a/4980330/463794 This means that you have to make sure that your SDBF has a non-zero gradient almost everywhere on $\partial\Omega$, otherwise you can run into degenerate cases w.r.t. the normal.  

---

