4 out uint packed_gradients;
6 uniform sampler2DArray tex;
8 uint pack_gradients(float x, float y, float v)
10 x = clamp(x, -0.5f, 0.5f);
11 y = clamp(y, -0.5f, 0.5f);
13 uint vi = uint(round(v * 255.0f));
14 uint xi = uint(round((x + 0.5f) * 4095.0f));
15 uint yi = uint(round((y + 0.5f) * 4095.0f));
16 return vi | (xi << 8) | (yi << 20);
21 // There are two common Sobel filters, horizontal and vertical
22 // (see e.g. Wikipedia, or the OpenCV documentation):
24 // [1 0 -1] [-1 -2 -1]
27 // Horizontal Vertical
29 // Note that Wikipedia and OpenCV gives entirely opposite definitions
30 // with regards to sign! This appears to be an error in the OpenCV
31 // documentation, forgetting that for convolution, the filters must be
32 // flipped. We have to flip the vertical matrix again comparing to
33 // Wikipedia, though, since we have bottom-left origin (y = up)
34 // and they define y as pointing downwards.
36 // Computing both directions at once allows us to get away with eight
37 // texture samples instead of twelve.
39 float top_left = textureOffset(tex, tc, ivec2(-1, 1)).x; // Note the bottom-left coordinate system.
40 float left = textureOffset(tex, tc, ivec2(-1, 0)).x;
41 float bottom_left = textureOffset(tex, tc, ivec2(-1, -1)).x;
43 float top = textureOffset(tex, tc, ivec2( 0, 1)).x;
44 float bottom = textureOffset(tex, tc, ivec2( 0, -1)).x;
46 float top_right = textureOffset(tex, tc, ivec2( 1, 1)).x;
47 float right = textureOffset(tex, tc, ivec2( 1, 0)).x;
48 float bottom_right = textureOffset(tex, tc, ivec2( 1, -1)).x;
51 gradients.x = (top_right + 2.0f * right + bottom_right) - (top_left + 2.0f * left + bottom_left);
52 gradients.y = (top_left + 2.0 * top + top_right) - (bottom_left + 2.0f * bottom + bottom_right);
54 // Normalize so that we have a normalized unit of intensity levels per pixel.
58 // Also store the actual pixel value, so that we get it “for free”
59 // when we sample the gradients in motion_search.frag later.
60 float center = texture(tex, tc).x;
62 // Pack everything into a single 32-bit value, using simple fixed-point.
63 packed_gradients = pack_gradients(gradients.x, gradients.y, center);