added various convolution filter

This commit is contained in:
Sven Vogel 2023-07-03 13:00:56 +02:00
parent 262c83223b
commit 1f654d8c93
3 changed files with 150 additions and 0 deletions

View File

@ -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);
}

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 685 KiB