

const vec2 shadowOffsets[6] = vec2[6](vec2(0.5303, 0.5303), vec2(-0.6250, -0.0000), vec2(0.3536, -0.3536),
                                      vec2(-0.0000, 0.3750), vec2(-0.1768, -0.1768), vec2(0.1250, 0.0000));

float shadowFunc(float diffuseSun, float sssAmount, vec3 p3, float noise, vec2 lightmap, vec3 normals)
{

    float shading = 1.0;
    p3 +=  normalize(shadowPosWorld) * 0.05; // Offset that reduces acne

    vec3 ProjShadowPos = mat3(shadowModelView) * p3 + shadowModelView[3].xyz;
    ProjShadowPos = diagonal3(shadowProjection) * ProjShadowPos + shadowProjection[3].xyz;

    float distortFac = calcDistort(ProjShadowPos.xy);


    ProjShadowPos.xy *= distortFac;
#ifdef SHADOWS_ENABLED

    diffuseSun = mix(diffuseSun, max(diffuseSun, 0.5 * sssAmount), float(sssAmount > 0.0));
#else

    diffuseSun = mix(diffuseSun, max(diffuseSun, pow(lightmap.y, 16) * 0.5), float(sssAmount > 0.0));

#endif
    vec2 bounds = vec2(1.0, 1.0) - 1.5 / shadowMapResolution;
    if (all(lessThan(abs(ProjShadowPos.xy), bounds)) && abs(ProjShadowPos.z) < 6 && diffuseSun > 0.001)
    {
        shading = 0.0;
        ProjShadowPos = ProjShadowPos * vec3(0.5, 0.5, 0.0833333) + vec3(0.5);

        float scaleFac = mix(distortFac, noise * PI, float(sssAmount > 0.0));

        const float threshMul = max(2048.0 / shadowMapResolution * shaddist / 128.0, 0.95);

        float distortThresh = clamp(sqrt(1.0 - diffuseSun * diffuseSun) / diffuseSun, 0.0, 1.0) / scaleFac;

        float diffthresh = mix(distortThresh, 0, sssAmount) / 6000.0 * threshMul;

#if SHADOW_FILTERING == 1

        float prec = noise * 6.2831;
        mat2 noiseM = mat2(cos(prec), -sin(prec), sin(prec), cos(prec)) * 0.001;
        float weight = 1.0 + noise * shadowMapResolution * 0.00016;
        float dweight = -diffthresh * weight;

        for (int i = 0; i < 6; i++)
        {
            vec2 offset = noiseM * shadowOffsets[i];

            vec3 shadowCoordWeighted = ProjShadowPos + vec3(offset, dweight);

            shading += texture(shadow, shadowCoordWeighted);
        }
        shading *= 0.1666;
#else
        ProjShadowPos.z -= diffthresh;
        shading = texture(shadow, ProjShadowPos);

#endif

#ifndef SHADOWS_ENABLED

        shading = pow(lightmap.y, 16);

#endif

        shading = mix(1.0, shading, nightblendShadows);
    }

    diffuseSun = min(diffuseSun, shading) * lightmap.y;
    diffuseSun = mix(0.0, diffuseSun, shadowblend);

    diffuseSun *= lightmap.y * (1 - rainStrength * 0.9);
    return diffuseSun;
}
