float tentKernel(in vec2 xy, in float r)
{
    return (1.0 - abs(xy.x/r)) * (1.0 - abs(xy.y/r)) / (r*r);
}

float gaussianWeight(in float delta, in float sigma)
{
    return exp(-delta*delta/(2.0 * sigma * sigma)) * 2.5 * sigma;
}

float luminance(in vec3 col)
{
    return dot(col, vec3(0.2126, 0.7152, 0.0722));
}

vec3 fasterBilateralFilter(in vec2 uv, in sampler2D tex, in int r, in int steping, in float omegaColor)
{
    vec2 scale = 1.0 / vec2(textureSize(tex, 0));

    vec3 sum = vec3(0);

    vec3 original = texture(tex, uv).rgb;

    float wp = 0.0;

    for (int x = -r; x <= r; x+=steping)
    for (int y = -r; y <= r; y+=steping)
    {
        vec2 off = vec2(x, y) * scale;

        vec3 col = texture(tex, uv + off).rgb;

        float di = luminance(original) - luminance(col);
        float space = tentKernel(vec2(x, y), float(r));
        float range = gaussianWeight(di, omegaColor);
        float w = space * range;

        wp += w;

        sum += col * w;
    }

    return sum / wp;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = fragCoord/iResolution.xy;

    vec3 col;

    if (uv.x < 0.33333)
    {
        col = texture(iChannel0, uv).rgb;
    }
    else if (uv.x > 0.33333 && uv.x < 0.66666)
    {
        col = fasterBilateralFilter(uv, iChannel0, 12, 3, 0.1);
    }
    else
    {
        col = texture(iChannel1, uv).rgb;
    }

    const float PI = 3.141592653589793;
    float border = step(0.02, abs(sin(uv.x*PI*3.0)));

    col *= border;

    fragColor = vec4(col,1.0);
}
