X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=sobel.frag;h=c4dabd519712465a9d2a5495617ac9c1e2708c5b;hb=adf0740352b3caa51e67a28429a11d5b082f16a0;hp=e6b377f2a54fab04a99cef15549f2e4cec9cc567;hpb=23ac2e109b1f6abd1830420e47bfc3ffaf97b7df;p=nageru diff --git a/sobel.frag b/sobel.frag index e6b377f..c4dabd5 100644 --- a/sobel.frag +++ b/sobel.frag @@ -4,28 +4,35 @@ in vec2 tc; out vec2 gradients; uniform sampler2D tex; -uniform float inv_width, inv_height; +uniform vec2 inv_image_size; void main() { // There are two common Sobel filters, horizontal and vertical // (see e.g. Wikipedia, or the OpenCV documentation): // - // [-1 0 1] [ 1 2 1] - // [-2 0 2] [ 0 0 0] - // [-1 0 1] [-1 -2 -1] + // [1 0 -1] [-1 -2 -1] + // [2 0 -2] [ 0 0 0] + // [1 0 -1] [ 1 2 1] // Horizontal Vertical // - // Computing both at once allows us to get away with eight + // Note that Wikipedia and OpenCV gives entirely opposite definitions + // with regards to sign! This appears to be an error in the OpenCV + // documentation, forgetting that for convolution, the filters must be + // flipped. We have to flip the vertical matrix again comparing to + // Wikipedia, though, since we have bottom-left origin (y = up) + // and they define y as pointing downwards. + // + // Computing both directions at once allows us to get away with eight // texture samples instead of twelve. - float x_left = tc.x - inv_width; + float x_left = tc.x - inv_image_size.x; float x_mid = tc.x; - float x_right = tc.x + inv_width; + float x_right = tc.x + inv_image_size.x; - float y_top = tc.y + inv_height; // Note the bottom-left coordinate system. + float y_top = tc.y + inv_image_size.y; // Note the bottom-left coordinate system. float y_mid = tc.y; - float y_bottom = tc.y - inv_height; + float y_bottom = tc.y - inv_image_size.y; float top_left = texture(tex, vec2(x_left, y_top)).x; float left = texture(tex, vec2(x_left, y_mid)).x; @@ -40,4 +47,8 @@ void main() gradients.x = (top_right + 2.0f * right + bottom_right) - (top_left + 2.0f * left + bottom_left); gradients.y = (top_left + 2.0 * top + top_right) - (bottom_left + 2.0f * bottom + bottom_right); + + // Normalize so that we have a normalized unit of intensity levels per pixel. + gradients.x *= 0.125; + gradients.y *= 0.125; }