Yesterday, I read 834144373’s ShaderToy code which did Edge Detection in 97 chars, it was really simple and fast:

However, the result is astonishingly good:

edge0

Let’s expand the code a little bit:

According to OpenGL manual:

fwidth means  abs(dFdx(p)) + abs(dFdy(p))

and fwidthFine is equivalent to abs(dFdxFine(p)) + abs(dFdyFine(p)).

One can use a sigmoid function to increase the contrast:

sigmoid

Better, uh? Wait, there is still some noise… let’s add a bilateral filter!

A bilateral filter is an edge-preserving noise reduction filter:

org  bilateral

After bilateral filter, the results did get improved:

 

edge1

But this is still not as good as my canny edge filter:

swan_edge_advanced

I’ll write my canny edge detector in Shadertoy in some day…

 

edge detection can be further used for low-poly style image generation:

low-poly

 

Fwidth can be further used to render wireframes in 3D meshes.

  1. Label each vertices with pure Red, Green and Blue
  2. Use Fwidth to determine the fraction part of the derivatives: