added various convolution filter
This commit is contained in:
parent
262c83223b
commit
1f654d8c93
|
@ -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);
|
||||||
|
}
|
|
@ -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 |
Loading…
Reference in New Issue