
//#define DIAMOND_KERNEL
#define CIRCULAR_KERNEL

float luminance(in vec3 rgb)
{
    return dot(rgb, vec3(0.21, 0.72, 0.07));
}

/**
* Intensifies the brightest pixels of the applied kernel based on the luminance() function
*/
vec3 dilate(in sampler2D tex, in vec2 uv, in int size, in float sep, in float minb, in float maxb)
{
    vec3 cc = texture(tex, uv).rgb;
    vec3 tc = cc;
    float cl = luminance(cc);

    vec2 texSize = sep/vec2(textureSize(tex, 0));

    for (int x = -size; x <= size; ++x)
    for (int y = -size; y <= size; ++y)
    {
        // default kernel is box shaped
        
        // diamond shaped kernel (45° rotated square)
        #if defined(DIAMOND_KERNEL)
        
        if (abs(x) > size - abs(y))
            continue;

        #elif defined(CIRCULAR_KERNEL)
        
        if (distance(vec2(x, y), vec2(0, 0)) > float(size))
            continue;
            
        #endif
    
        vec3 s = texture(tex, uv + vec2(x,y)*texSize).rgb;
        float b = luminance(s);
        
        if (cl < b)
        {
            cl = b;
            tc = s;
        }
    }
    
    return mix(cc, tc, smoothstep(minb, maxb, cl));
}

/**
* Intensifies the darkest pixels of the applied kernel based on the luminance() function
*/
vec3 erode(in sampler2D tex, in vec2 uv, in int size, in float sep, in float minb, in float maxb)
{
    vec3 cc = texture(tex, uv).rgb;
    vec3 tc = cc;
    float cl = luminance(cc);

    vec2 texSize = sep/vec2(textureSize(tex, 0));

    for (int x = -size; x <= size; ++x)
    for (int y = -size; y <= size; ++y)
    {
        // default kernel is box shaped
        
        // diamond shaped kernel (45° rotated square)
        #if defined(DIAMOND_KERNEL)
        
        if (abs(x) > size - abs(y))
            continue;

        #elif defined(CIRCULAR_KERNEL)
        
        if (distance(vec2(x, y), vec2(0, 0)) > float(size))
            continue;
            
        #endif
    
        vec3 s = texture(tex, uv + vec2(x,y)*texSize).rgb;
        float b = luminance(s);
        
        if (cl > b)
        {
            cl = b;
            tc = s;
        }
    }
    
    return mix(tc, cc, smoothstep(minb, maxb, cl));
}

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

    float separation = (uv.x)*1.5;

    vec3 dilation = dilate(iChannel0, uv, 16, separation, 0.0, 1.0);
    vec3 erosion  = erode (iChannel0, uv, 16, separation, 0.0, 1.0);
    
    vec3 col = uv.x > 0.0 ? erosion : dilation;
    
    fragColor = vec4(col,1.0);
}