#version 330 core

in vec2 i_uv_out;

out vec4 o_fragColor;

uniform sampler2D u_texture;
uniform vec4 u_tint;
uniform vec3 u_color_offset;
uniform float uIntensity;
uniform float u_intensity;

const int RADIUS = 4;

float gaussianWeight(vec2 offset, float sigma)
{
    float dist = dot(offset, offset);
    return exp(-dist / (2.0 * sigma * sigma));
}

void main()
{
    float intensity = max(max(uIntensity, u_intensity), 0.0);
    vec2 texelSize = 1.0 / vec2(textureSize(u_texture, 0));

    if (intensity <= 0.001) {
        vec4 texColor = texture(u_texture, i_uv_out);
        texColor *= u_tint;
        texColor.rgb += u_color_offset;
        o_fragColor = texColor;
        return;
    }

    float sigma = max(intensity * 2.0, 0.001);
    vec4 color = vec4(0.0);
    float totalWeight = 0.0;

    for (int y = -RADIUS; y <= RADIUS; ++y) {
        for (int x = -RADIUS; x <= RADIUS; ++x) {
            vec2 kernelOffset = vec2(float(x), float(y));
            float weight = gaussianWeight(kernelOffset, sigma);
            vec2 sampleOffset = kernelOffset * texelSize * intensity;

            color += texture(u_texture, i_uv_out + sampleOffset) * weight;
            totalWeight += weight;
        }
    }

    vec4 texColor = color / totalWeight;
    texColor *= u_tint;
    texColor.rgb += u_color_offset;
    o_fragColor = texColor;
}
