<p>The usual way of doing this with raymarching is to define your surface as a <a href="https://en.wikipedia.org/wiki/Signed_distance_function" rel="noreferrer">signed-distance field</a> and use <a href="https://en.wikipedia.org/wiki/Finite_difference#Relation_with_derivatives" rel="noreferrer">finite differences</a> to get the gradient of the distance function at the point you’re sampling. In other words, if you have a function <code>map(p)</code> that returns the signed distance value at a point <code>p</code>, the normal at <code>p</code> is given by:</p>

<pre><code>float epsilon = 0.001; // arbitrary — should be smaller than any surface detail in your distance function, but not so small as to get lost in float precision
float centerDistance = map(p);
float xDistance = map(p + float3(epsilon, 0, 0));
float yDistance = map(p + float3(0, epsilon, 0));
float zDistance = map(p + float3(0, 0, epsilon));
float3 normal = (float3(xDistance, yDistance, zDistance) - centerDistance) / epsilon;
</code></pre>

<p>Note that you can improve the accuracy by taking an extra 3 samples on the other “side” of the center position and subtracting those from the first three, then dividing by 2× the epsilon value, but if your distance function is complicated then that can be a lot of additional work for not much visible benefit.</p>

<p>The sample function you provide isn’t a signed-distance function as-is, and I don’t know of a straightforward way to convert it into one, but there’s an article by Íñigo Quílez (kind of a legend in this field) <a href="https://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm" rel="noreferrer">here</a> with various functions you can make use of, including one for an ellipsoid. There’s also a lot of reference material available on <a href="https://shadertoy.com" rel="noreferrer">Shadertoy</a>—search for “raymarching” and you’ll find plenty of examples.</p>

CC BY-SA 4.0
2018-09-24T21:23:28.853Z
what about the treatment of general ovaloids?
user1868607
CC BY-SA 4.0
2018-09-24T22:18:37.520Z
As in non-ellipsoidal ones? The usual way to make odd shapes like that is to warp the domain—if you shift where you’re sampling your function, you shift the appearance of the shape. Check out the “domain deformations” section of the Quílez article for some examples.
Noah Witherspoon
CC BY-SA 4.0
2018-09-24T18:41:23.123Z
2018-09-24T18:41:23.123Z
Noah Witherspoon
<p>I want to represent ovaloids with ray-marching. I have ovaloids defined with an implicit equation. </p>

<p>For instance, we can consider the equation of an ellipsoid given as: <span class="math-container">$$ \frac{x^2}{a^2} + \frac{y^2}{b^2} + \frac{z^2}{c^2} -1 = 0, $$</span> where <span class="math-container">$a, b, c$</span> are constant. </p>

<p>Given this equation I need to caculate the normal for the shading of the suface. In an standard course of Curves and Surfaces I would take <span class="math-container">$f(x,y,z) = \frac{x^2}{a^2} + \frac{y^2}{b^2} + \frac{z^2}{c^2} -1 $</span> and compute <span class="math-container">$N(p) = \frac{\nabla f(p)}{|\nabla f(p)|}$</span> as the normal of the surface. </p>

<p>Here I have to check that <span class="math-container">$0$</span> is a regular value of <span class="math-container">$f$</span> and that <span class="math-container">$f  $</span> is differentiable. However, the second check is not automate.</p>

<ul>
<li>How is it done in real-world systems? </li>
<li>Can you give an explanation of the methods used and ideally point me some implementations that exist?</li>
</ul>

<p>Please, answer in full generality and not only considering the example given above. </p>

CC BY-SA 4.0
2018-09-23T16:16:57.413Z
One practical way to do this could be to calculate screen space derivatives of world space position, with ddx/ddy and do a cross product to get a world space normal.
Alan Wolfe
CC BY-SA 4.0
2018-09-24T21:25:15.270Z
https://www.google.ch/search?q=screen+space+derivatives+of+world+space+position&oq=screen+space+derivatives+of+world+space+position&aqs=chrome..69i57.410703j0j4&sourceid=chrome&ie=UTF-8 for the term "screen space derivatives of world space position"
user1868607
<shading><normal-mapping><raymarching>
How to compute normal of surface from implicit equation for ray-marching?
EvaMGG
# How to compute normal of surface from implicit equation for ray-marching?

(Asked by: username_0 on 2018-09-22)

I want to represent ovaloids with ray-marching. I have ovaloids defined with an implicit equation.

For instance, we can consider the equation of an ellipsoid given as: $$ \frac{x^2}{a^2} + \frac{y^2}{b^2} + \frac{z^2}{c^2} -1 = 0, $$ where $a, b, c$ are constant.

Given this equation I need to caculate the normal for the shading of the suface. In an standard course of Curves and Surfaces I would take $f(x,y,z) = \frac{x^2}{a^2} + \frac{y^2}{b^2} + \frac{z^2}{c^2} -1 $ and compute $N(p) = \frac{\nabla f(p)}{|\nabla f(p)|}$ as the normal of the surface.

Here I have to check that $0$ is a regular value of $f$ and that $f $ is differentiable. However, the second check is not automate.

* How is it done in real-world systems?
* Can you give an explanation of the methods used and ideally point me some implementations that exist?

Please, answer in full generality and not only considering the example given above.

**Tags:** shading, normal-mapping, raymarching

> **Comments:**
> **username_1**: One practical way to do this could be to calculate screen space derivatives of world space position, with ddx/ddy and do a cross product to get a world space normal.  
> **username_2**: https://www.google.ch/search?q=screen+space+derivatives+of+world+space+position&oq=screen+space+derivatives+of+world+space+position&aqs=chrome..69i57.410703j0j4&sourceid=chrome&ie=UTF-8 for the term "screen space derivatives of world space position"  

---

## 1 answers

### Answer by username_3 on 2018-09-24. Score: 5 | Accepted answer

The usual way of doing this with raymarching is to define your surface as a [signed-distance field](https://en.wikipedia.org/wiki/Signed_distance_function) and use [finite differences](https://en.wikipedia.org/wiki/Finite_difference#Relation_with_derivatives) to get the gradient of the distance function at the point you’re sampling. In other words, if you have a function `map(p)` that returns the signed distance value at a point `p`, the normal at `p` is given by:

```
float epsilon = 0.001; // arbitrary — should be smaller than any surface detail in your distance function, but not so small as to get lost in float precision
float centerDistance = map(p);
float xDistance = map(p + float3(epsilon, 0, 0));
float yDistance = map(p + float3(0, epsilon, 0));
float zDistance = map(p + float3(0, 0, epsilon));
float3 normal = (float3(xDistance, yDistance, zDistance) - centerDistance) / epsilon;

```

Note that you can improve the accuracy by taking an extra 3 samples on the other “side” of the center position and subtracting those from the first three, then dividing by 2× the epsilon value, but if your distance function is complicated then that can be a lot of additional work for not much visible benefit.

The sample function you provide isn’t a signed-distance function as-is, and I don’t know of a straightforward way to convert it into one, but there’s an article by Íñigo Quílez (kind of a legend in this field) [here](https://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm) with various functions you can make use of, including one for an ellipsoid. There’s also a lot of reference material available on [Shadertoy](https://shadertoy.com)—search for “raymarching” and you’ll find plenty of examples.

> **Comments:**
> **username_2**: what about the treatment of general ovaloids?  
> **username_3**: As in non-ellipsoidal ones? The usual way to make odd shapes like that is to warp the domain—if you shift where you’re sampling your function, you shift the appearance of the shape. Check out the “domain deformations” section of the Quílez article for some examples.  

---

