<p>One way I can think of is to make a "signed distance transform" of the image where there is information for each pixel about how far the pixel is to the closest surface of the shape.  Since it's signed, youll be able to know if the pixel is inside or outside he shape, and by how much.</p>

<p>Using this knowledge, you could easily make a new image, where the pixel is black if the distance is greater than -10, else it is white.  That would make the shape shrink by 10 pixels.</p>

<p>You can use smoothstep or other curves to transition between black and white over a number of pixels, to soften it anti alias the edges.</p>

<p>You can make the distance transform by brute force, but another method would be to make a voronoi diagram first and then turn that into a distance transform.</p>

<p>There is lots of info out there on both voronoi diagrams as well as (signed) distance transforms but these two links will probably be helpful to get you started:</p>

<p><a href="http://blog.demofox.org/2016/02/29/fast-voronoi-diagrams-and-distance-dield-textures-on-the-gpu-with-the-jump-flooding-algorithm/">http://blog.demofox.org/2016/02/29/fast-voronoi-diagrams-and-distance-dield-textures-on-the-gpu-with-the-jump-flooding-algorithm/</a></p>

<p><a href="http://blog.demofox.org/2016/03/02/actually-making-signed-distance-field-textures-with-jfa/">http://blog.demofox.org/2016/03/02/actually-making-signed-distance-field-textures-with-jfa/</a></p>

CC BY-SA 3.0
2016-03-14T03:12:19.650Z
You might also want to read up on signed distance fields in general by the way. Seems relevant as you might possibly be able to skip the distance transform step and just draw sdf's
Alan Wolfe
CC BY-SA 3.0
2016-03-15T02:54:12.533Z
Thanks, it seems to work quite well. Using OpenCV, applying a distance transform, thresholding the image and finally normalizing it back to 0 to 255 values seems to give quite a good result. Some jagged lines are really visible though. I tried a Gaussian blur which kind of works but I would really like to know if there is a better solution.
Gentle Moose
CC BY-SA 3.0
2016-03-15T03:10:46.917Z
There is a better solution.  The topic kind of warrants it's own question but here's a short answer.  First step is to make it fade from white to black over a specific distance.  Like if 10 was the distance that went from black to white, you could make it fade between 9 and 11 where you use the distance value to figure out how light or dark to make the pixel based on distance.  Next, you take that pixel shade, which should be between 0 and 1, and put it through the smoothstep function.  That will turn it from a linear fade to something a lot more appealing. Adjust fade distance to taste (:
Alan Wolfe
CC BY-SA 3.0
2016-03-15T03:12:21.340Z
Here is the details of the smoothstep function:  https://en.m.wikipedia.org/wiki/Smoothstep  for a better or more detailed answer you might ask how to do anti aliasing when rendering using a distance field.
Alan Wolfe
CC BY-SA 3.0
2016-03-15T03:47:51.517Z
oh sorry, to address more towards your original question.  I believe the curve just says how to turn the linear distance into a pixel shade.  like if your width was 10 pixels, and you were 5 pixels away (either on the positive or negative side), that it would take that to mean you were at 50% distance, and do a lookup on the curve at 50% to see how white or black to make the output pixel.
Alan Wolfe
CC BY-SA 3.0
2016-03-15T20:24:52.497Z
Sorry if my comment was a bit unclear.

here is an [image](http://i.imgur.com/RKxyKtH.png) of the result I get.

As you can see in the result, jagged strips are quite visible.
Like I mentioned, I used the distance transform + threshold + normalize to "make it fade from white to black over a specific distance".

You mentioned "anti aliasing when rendering using a distance field". Is this what corresponds to the issue here?
Gentle Moose
CC BY-SA 3.0
2016-03-15T20:28:58.600Z
Did you put the shade color through smoothstep to make the blending non linear? If so that is really weird. Probably worth another question about just that specifically. (Using terminology of rendering using a distance field)
Alan Wolfe
CC BY-SA 3.0
2016-03-17T11:51:21.250Z
Smoothstep does not solve the jagged lines problem which is not really surprising. It remaps the values in a smoother curve but it does not fix the aliasing in any way. I will address another question targeting this specific issue.
Gentle Moose
CC BY-SA 3.0
2016-03-17T15:04:59.550Z
I'm looking forward to seeing the details in the new question. The artifacts you are seeing is strange. Fwiw the smoothstep-ing of the fade is a common technique. It might not help the specific issue you are hitting but it is useful / widely used. Just wanted to let you know I didn't just make it up :p
Alan Wolfe
CC BY-SA 3.0
2016-03-17T18:27:42.700Z
Don't  worry! I believe you haha! I read about it and it seems to be used in many situations. This is simply not useful in this case since I need to preserve the linear interpolation. Here is [another post](http://dsp.stackexchange.com/questions/530/bitmap-alpha-bevel-algorithm) I found that has similar request and technology in use. I think the artifacts could be related to the implementation of distance transform in OpenCV.
Gentle Moose
CC BY-SA 3.0
2016-03-14T02:55:34.097Z
2016-03-14T02:55:34.097Z
Alan Wolfe
<p>I am a beginner in digital image processing and computer graphics. I would like to program a similar behavior than the Shadermap 3 normal editor (displacement layer more specifically).</p>

<p>As shown in this <a href="https://youtu.be/NIHpBNnYYU8?t=34s" rel="noreferrer">Shadermap 3 demonstration video</a>, the displacement brush allows the user to paint a <strong>displacement map (grayscale)</strong></p>

<p><img src="https://i.sstatic.net/n3Jq2.png" alt="Shadermap 3"></p>

<p>The brush strokes produce shapes with a smooth value transitioning from the middle of the shape to its edge, in this case giving the shape a slightly curved profile. As it is also shown, the shape's profile can be fine-tuned with the brush curve editor.</p>

<p>What combination of filters and/or algorithms could Shadermap 3 possibly use to convert a pixel blob or shape to displacement map with a given width and curve?</p>

<p><img src="https://i.sstatic.net/HSo1c.png" alt="Combination"></p>

<algorithm><image-processing><curve>
Converting raster shape/blob into displacement map
Gentle Moose
# Converting raster shape/blob into displacement map

(Asked by: username_0 on 2016-03-13)

I am a beginner in digital image processing and computer graphics. I would like to program a similar behavior than the Shadermap 3 normal editor (displacement layer more specifically).

As shown in this [Shadermap 3 demonstration video](https://youtu.be/NIHpBNnYYU8?t=34s), the displacement brush allows the user to paint a **displacement map (grayscale)**

![Shadermap 3](https://i.sstatic.net/n3Jq2.png)

The brush strokes produce shapes with a smooth value transitioning from the middle of the shape to its edge, in this case giving the shape a slightly curved profile. As it is also shown, the shape's profile can be fine-tuned with the brush curve editor.

What combination of filters and/or algorithms could Shadermap 3 possibly use to convert a pixel blob or shape to displacement map with a given width and curve?

![Combination](https://i.sstatic.net/HSo1c.png)

**Tags:** algorithm, image-processing, curve


---

## 1 answers

### Answer by username_1 on 2016-03-14. Score: 5 | Accepted answer

One way I can think of is to make a "signed distance transform" of the image where there is information for each pixel about how far the pixel is to the closest surface of the shape. Since it's signed, youll be able to know if the pixel is inside or outside he shape, and by how much.

Using this knowledge, you could easily make a new image, where the pixel is black if the distance is greater than -10, else it is white. That would make the shape shrink by 10 pixels.

You can use smoothstep or other curves to transition between black and white over a number of pixels, to soften it anti alias the edges.

You can make the distance transform by brute force, but another method would be to make a voronoi diagram first and then turn that into a distance transform.

There is lots of info out there on both voronoi diagrams as well as (signed) distance transforms but these two links will probably be helpful to get you started:

<http://blog.demofox.org/2016/02/29/fast-voronoi-diagrams-and-distance-dield-textures-on-the-gpu-with-the-jump-flooding-algorithm/>

<http://blog.demofox.org/2016/03/02/actually-making-signed-distance-field-textures-with-jfa/>

> **Comments:**
> **username_1**: You might also want to read up on signed distance fields in general by the way. Seems relevant as you might possibly be able to skip the distance transform step and just draw sdf's  
> **username_0**: Thanks, it seems to work quite well. Using OpenCV, applying a distance transform, thresholding the image and finally normalizing it back to 0 to 255 values seems to give quite a good result. Some jagged lines are really visible though. I tried a Gaussian blur which kind of works but I would really like to know if there is a better solution.  
> **username_1**: There is a better solution.  The topic kind of warrants it's own question but here's a short answer.  First step is to make it fade from white to black over a specific distance.  Like if 10 was the distance that went from black to white, you could make it fade between 9 and 11 where you use the distance value to figure out how light or dark to make the pixel based on distance.  Next, you take that pixel shade, which should be between 0 and 1, and put it through the smoothstep function.  That will turn it from a linear fade to something a lot more appealing. Adjust fade distance to taste (:  
> **username_1**: Here is the details of the smoothstep function:  https://en.m.wikipedia.org/wiki/Smoothstep  for a better or more detailed answer you might ask how to do anti aliasing when rendering using a distance field.  
> **username_1**: oh sorry, to address more towards your original question.  I believe the curve just says how to turn the linear distance into a pixel shade.  like if your width was 10 pixels, and you were 5 pixels away (either on the positive or negative side), that it would take that to mean you were at 50% distance, and do a lookup on the curve at 50% to see how white or black to make the output pixel.  
> **username_0**: Sorry if my comment was a bit unclear.  here is an [image](http://i.imgur.com/RKxyKtH.png) of the result I get.  As you can see in the result, jagged strips are quite visible. Like I mentioned, I used the distance transform + threshold + normalize to "make it fade from white to black over a specific distance".  You mentioned "anti aliasing when rendering using a distance field". Is this what corresponds to the issue here?  
> **username_1**: Did you put the shade color through smoothstep to make the blending non linear? If so that is really weird. Probably worth another question about just that specifically. (Using terminology of rendering using a distance field)  
> **username_0**: Smoothstep does not solve the jagged lines problem which is not really surprising. It remaps the values in a smoother curve but it does not fix the aliasing in any way. I will address another question targeting this specific issue.  
> **username_1**: I'm looking forward to seeing the details in the new question. The artifacts you are seeing is strange. Fwiw the smoothstep-ing of the fade is a common technique. It might not help the specific issue you are hitting but it is useful / widely used. Just wanted to let you know I didn't just make it up :p  
> **username_0**: Don't  worry! I believe you haha! I read about it and it seems to be used in many situations. This is simply not useful in this case since I need to preserve the linear interpolation. Here is [another post](http://dsp.stackexchange.com/questions/530/bitmap-alpha-bevel-algorithm) I found that has similar request and technology in use. I think the artifacts could be related to the implementation of distance transform in OpenCV.  

---

