float shadow15(in sampler2D shadowtex, in vec3 wPos, in float cd, in float sigma) {
    float shadow    = 0.0;
    float weight    = 1.0/15.0;

    float noise     = ditherGradNoise()*pi;
    vec2 offset     = vec2(cos(noise), sin(noise))*0.5;
    for (int i = 0; i<15; i++) {
        shadow     += getTexshadow(shadowtex, wPos.xy+(bokeh15[i]+offset)*sigma, cd)*weight;
    }
    return shadow;
}

float shadow30(in sampler2D shadowtex, in vec3 wPos, in float cd, in float sigma) {
    float shadow    = 0.0;
    float weight    = 1.0/30.0;

    float noise     = ditherGradNoise()*pi;
    vec2 offset     = vec2(cos(noise), sin(noise))*0.5;
    for (int i = 0; i<30; i++) {
        shadow     += getTexshadow(shadowtex, wPos.xy+(bokeh30[i]+offset)*sigma, cd)*weight;
    }
    return shadow;
}

vec4 shadowcol15(in sampler2D shadowtex, in vec3 wPos, in float sigma) {
    vec4 color      = vec4(1.0, 1.0, 1.0, 0.0);
    float weight    = 1.0/15.0;

    float noise     = ditherGradNoise()*pi;
    vec2 offset     = vec2(cos(noise), sin(noise))*0.5;

    for (int i = 0; i<15; i++) {
        vec4 tex    = texture(shadowtex, wPos.xy+(bokeh15[i]+offset)*sigma);
        color.rgb   = min(color.rgb, tex.rgb);
        color.a     = max(color.a, tex.a);
    }
    return color;
}