X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=sobel.frag;h=8c5c6ee8a69184147cd1f4e65b415dc292a1eaaa;hb=3795723be95f2fe82f3c8b8b45b1a905b2c811fd;hp=c4dabd519712465a9d2a5495617ac9c1e2708c5b;hpb=eb879cde156d29caedd25092362c168b45dc2c0a;p=nageru diff --git a/sobel.frag b/sobel.frag index c4dabd5..8c5c6ee 100644 --- a/sobel.frag +++ b/sobel.frag @@ -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); }