]> git.sesse.net Git - nageru/blobdiff - sobel.frag
Allow symlinked frame files. Useful for testing.
[nageru] / sobel.frag
index c4dabd519712465a9d2a5495617ac9c1e2708c5b..8c5c6ee8a69184147cd1f4e65b415dc292a1eaaa 100644 (file)
@@ -1,10 +1,20 @@
 #version 450 core
 
-in vec2 tc;
-out vec2 gradients;
+in vec3 tc;
+out uint packed_gradients;
 
-uniform sampler2D tex;
-uniform vec2 inv_image_size;
+uniform sampler2DArray tex;
+
+uint pack_gradients(float x, float y, float v)
+{
+       x = clamp(x, -0.5f, 0.5f);
+       y = clamp(y, -0.5f, 0.5f);
+
+       uint vi = uint(round(v * 255.0f));
+       uint xi = uint(round((x + 0.5f) * 4095.0f));
+       uint yi = uint(round((y + 0.5f) * 4095.0f));
+       return vi | (xi << 8) | (yi << 20);
+}
 
 void main()
 {
@@ -26,29 +36,29 @@ void main()
        // Computing both directions at once allows us to get away with eight
        // texture samples instead of twelve.
 
-       float x_left   = tc.x - inv_image_size.x;
-       float x_mid    = tc.x; 
-       float x_right  = tc.x + inv_image_size.x;
+       float top_left     = textureOffset(tex, tc, ivec2(-1,  1)).x;  // Note the bottom-left coordinate system.
+       float left         = textureOffset(tex, tc, ivec2(-1,  0)).x;
+       float bottom_left  = textureOffset(tex, tc, ivec2(-1, -1)).x;
 
-       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_image_size.y;
-       float top_left     = texture(tex, vec2(x_left,  y_top)).x;
-       float left         = texture(tex, vec2(x_left,  y_mid)).x;
-       float bottom_left  = texture(tex, vec2(x_left,  y_bottom)).x;
+       float top          = textureOffset(tex, tc, ivec2( 0,  1)).x;
+       float bottom       = textureOffset(tex, tc, ivec2( 0, -1)).x;
 
-       float top          = texture(tex, vec2(x_mid,   y_top)).x;
-       float bottom       = texture(tex, vec2(x_mid,   y_bottom)).x;
-
-       float top_right    = texture(tex, vec2(x_right, y_top)).x;
-       float right        = texture(tex, vec2(x_right, y_mid)).x;
-       float bottom_right = texture(tex, vec2(x_right, y_bottom)).x;
+       float top_right    = textureOffset(tex, tc, ivec2( 1,  1)).x;
+       float right        = textureOffset(tex, tc, ivec2( 1,  0)).x;
+       float bottom_right = textureOffset(tex, tc, ivec2( 1, -1)).x;
 
+       vec2 gradients;
        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;
+
+       // Also store the actual pixel value, so that we get it “for free”
+       // when we sample the gradients in motion_search.frag later.
+       float center = texture(tex, tc).x;
+
+       // Pack everything into a single 32-bit value, using simple fixed-point.
+       packed_gradients = pack_gradients(gradients.x, gradients.y, center);
 }