diff --git a/Image-Filtering/Convolution-Filter/Image.glsl b/Image-Filtering/Convolution-Filter/Image.glsl new file mode 100644 index 0000000..bc503e0 --- /dev/null +++ b/Image-Filtering/Convolution-Filter/Image.glsl @@ -0,0 +1,137 @@ + +vec3 conv(in sampler2D tex, in vec2 uv, in mat3 ker); + +vec3 edges(in sampler2D tex, in vec2 uv) +{ + mat3 ker = mat3( + vec3(-1, -2, -1), + vec3(-2, 12, -2), + vec3(-1, -2, -1) + ); + + return conv(tex, uv, ker)+.5; +} + +// can be used to remove high frequency noise +vec3 median(in sampler2D tex, in vec2 uv) +{ + float k = 1./8.; + mat3 ker = mat3( + vec3(k, k, k), + vec3(k, 0, k), + vec3(k, k, k) + ); + + return conv(tex, uv, ker); +} + +// sharpen filter including diagonals +vec3 laplace(in sampler2D tex, in vec2 uv, in float strength) +{ + float k = -strength; + mat3 ker = mat3( + vec3(k, k, k), + vec3(k, 8.*strength+1., k), + vec3(k, k, k) + ); + + return conv(tex, uv, ker); +} + +// subtracts high frequency edges from the source image +vec3 unsharp(in sampler2D tex, in vec2 uv) +{ + float k = 1./9.; + mat3 ker = mat3( + vec3(k, k, k), + vec3(k, k, k), + vec3(k, k, k) + ); + + vec3 blurred = conv(tex, uv, ker); + + return texture(iChannel0, uv).rgb - (texture(iChannel0, uv).rgb - blurred); +} + +vec3 emboss(in sampler2D tex, in vec2 uv, in float theta) +{ + // init kernel + mat3 ker = mat3( + vec3(0), + vec3(0), + vec3(0) + ); + + // direction of edge detection + vec2 dir = vec2(sin(theta), cos(theta)); + + // fill kernel with values + for (int x = -1; x < 2; x++) + for (int y = -1; y < 2; y++) + ker[x+1][y+1] = dot(dir, vec2(x,y)); + + return conv(tex, uv, ker)+.5; +} + +vec3 sobelFeldmann(in sampler2D tex, in vec2 uv) +{ + // init horizontal kernel + mat3 ker0 = mat3( + vec3(1, 0, -1), + vec3(2, 0, -2), + vec3(1, 0, -1) + ); + + // init vertical kernel + mat3 ker1 = mat3( + vec3(1, 2, 1), + vec3(0, 0, 0), + vec3(-1, -2, -1) + ); + + vec3 c0 = conv(tex, uv, ker0);// convolute horizontal + vec3 c1 = conv(tex, uv, ker1);// convolute vertical + + // pythagoras + return sqrt(c0*c0+c1*c1); +} + +vec3 conv(in sampler2D tex, in vec2 uv, in mat3 ker) +{ + vec3 sum = vec3(0); + + for (int x = 0; x < 3; x++) + for (int y = 0; y < 3; y++) + { + vec2 off = (vec2(x,y)*.3333-.5)/iResolution.xy; + sum += texture(tex, uv + off).rgb * ker[x][y]; + } + + return sum; +} + +bool sector(in vec2 uv, in vec2 hor, in vec2 ver) +{ + vec2 delta = 1./vec2(hor[1], ver[1]); + + vec2 low = delta * vec2(hor[0], ver[0]); + vec2 high = low + delta; + + return low.x < uv.x && low.y < uv.y && high.x > uv.x && high.y > uv.y; +} + +void mainImage( out vec4 fragColor, in vec2 fragCoord ) +{ + vec2 uv = fragCoord/iResolution.xy; + + vec3 col = texture(iChannel0, uv).rgb; + + if (sector(uv, vec2(0,4), vec2(1,2))) col = unsharp(iChannel0, uv); + if (sector(uv, vec2(1,4), vec2(0,2))) col = laplace(iChannel0, uv, 2.0); + if (sector(uv, vec2(1,2), vec2(0,2))) col = emboss(iChannel0, uv, iTime); + if (sector(uv, vec2(1,2), vec2(1,2))) col = sobelFeldmann(iChannel0, uv); + if (sector(uv, vec2(1,4), vec2(1,2))) col = median(iChannel0, uv); + if (sector(uv, vec2(1,4), vec2(1,2))) col = edges(iChannel0, uv); + + fragColor = vec4(col,1.0); +} \ No newline at end of file diff --git a/Image-Filtering/Convolution-Filter/README.md b/Image-Filtering/Convolution-Filter/README.md new file mode 100644 index 0000000..74961d5 --- /dev/null +++ b/Image-Filtering/Convolution-Filter/README.md @@ -0,0 +1,13 @@ +# Convolution-Filter +![overview.png](https://git.teridax.de/teridax/Shadertoy-Shaders/raw/branch/main/Image-Filtering/Convolution-Filter/overview.png) + +Convolution filter are filters that take a kernel and sum up every pixel and multiply that pixel with the corresponding element of the kernel. +Note that blur filter are technically convolution filters as well despite them not being listed here. + +This file contains example implemntations of the following convolution filters: +- Median Filter +- Unsharp mask +- Laplace (sharpen) +- Emboss (omni-directional) +- Sobel-Feldmann +- Edge Detection \ No newline at end of file diff --git a/Image-Filtering/Convolution-Filter/overview.png b/Image-Filtering/Convolution-Filter/overview.png new file mode 100644 index 0000000..87c8e1a Binary files /dev/null and b/Image-Filtering/Convolution-Filter/overview.png differ