
in vec4 v_color;
in vec2 v_position;
out vec4 frag_color;

layout(std140) uniform ShadowInfo {
    vec4 box_position;
    vec4 shift_position;
    vec4 shadow_params;
};

vec4 erf(vec4 x) {
    vec4 s = sign(x);
    vec4 a = abs(x);
    x = 1.0 + (0.278393 + (0.230389 + 0.078108 * (a * a)) * a) * a;
    x *= x;
    return s - s / (x * x);
}

// Return the mask for the shadow of a box from lower to upper
float boxShadow(vec2 lower, vec2 upper, vec2 point, float sigma) {
    vec4 query = vec4(point - lower, point - upper);
    vec4 integral = 0.5 + 0.5 * erf(query * (sqrt(0.5) / sigma));
    return (integral.z - integral.x) * (integral.w - integral.y);
}

void main() {
    vec2 inside = step(box_position.xy, v_position) - step(box_position.xy + box_position.zw, v_position);
    if (inside.x * inside.y > 0.5) {
        discard;
    }
    float shadow_val = boxShadow(shift_position.xy, shift_position.xy + shift_position.zw, v_position, shadow_params.y * 0.5);
    frag_color = v_color * vec4(1.0, 1.0, 1.0, shadow_val);
}
