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