Assignment: Create an edge detection algorithm that also takes into account how far way from the surface is from the camera. Proper implementation will allow the edges *not* to pop or alias when the camera zooms in or out.
My Analysis:
Had some trouble at first, getting back into programming and working with shaders. Slowly became re-oriented. At first I tested side-by-side shots of the detected edges at different distances. I then tried to re-adjust the 'threshold(sensitivity)' and the 'next' step to try and compensate for the change in distance.
Distance -> 5 -> 10 -> 15 -> 20
next -> .005 -> .001 -> .009 -> .009?-.008?
threshold -> .1 -> .02 -> .008 -> .0064
Working with it a little more it seemed that only threshold was the one I need to work with and that it seemed as if it was something close to '1/x' where x was the camera distance. So I implemented this into the code.
If you look in the following in the before, when the surface is far away it seems as if there is barely any edge detection going on. In the after by using the following code the edge detection takes into account camera distance.
Of course even with this code there is still aliasing. So I then worked in improving the edge detection method as the previous was only taking into account two other pixels...then one to the right and the one below the original pixel. This is not really a good way to edge detect. So implementation of 2 for loops to helped by sampling all of the pixel directly surrounding the given pixel.
1 2 3
4 X 5
6 7 8
Also smoothstep() was used to give a gradient to the edges to help with the aliasing as it moved toward or away from the camera.
So this case is definitely a better edge detection method, however there is aliasing as the edge detection is picking up noise. My next idea was to get rid of the noise by blurring the original image then performing the edge detection. This is a known way of improving the edge detection as it basically blurs out the noise.
Using a blur convolution matrix where the value of the middle pixel is the average of the surrounding pixel. Take into account more surrounding pixels and more blur will be added.
1 1 1
1 2 1
1 1 1
Here is a slight bur result, if you look closely at the jersey mesh of #61 it has been mostly bur out. This is where the majority of the noise was produced during the edge detection:
Now the problem I faced was correctly implementing the bur, do the edge detection to the blurred image then apply the edge detection not to the blurred image, but the un blurred image. So basically I thought of a very brute force method of accomplishing it by using a quadruple nested for loop. Not very elegant and is slow, but it accomplished the job. I thought of much easier ways to do it in other languages, but my knowledge of the shading language is limited right now and this is the only way I could think of doing it.
Take a look at the following clips. The one on the left is with no blurring taking place. If you notice the in the mesh jersey of #61 there is a lot of noise that was produced during the edge detection. Now take a look at the clip on the right. By using the blur it has eliminated much of the noise in the jersey as well as in other parts of the image while pretty much maintaining the edge thickness. The combination of the '1/x' camera distance and the blur have almost completely taken care of the aliasing. There is only now a very slight pop within the final clip. Adjustment of the smoothstep threshold and further blurring should produce a better result. I only used a '1 step blur average' where as further blurring with a '2 step blur' as I did in the images above. Of course using a better edge detection algorithm such as 'Sobel' would help as well.
I also tried a different method of edge detection. I was trying to implement 'Sobel' Edge detection. I believe I implemented properly, but I am not sure. The edge detection does seem to be better than the box filter method I was using earlier. First is the original image then the image to the right is the image is Sobel detection(Maybe? Correctly implemented?) with blur.
Check out this link to a good page on different types of edge detection. Other Cool Stuff: