#version 450

// Fragment shader del pase final de composite.
// Llegeix dos samplers: l'escena vectorial i el bloom ja pre-calculat (resultat
// del separable blur de dues passes a bloom.frag.glsl). Aplica:
//   1. Mescla del bloom amb la intensitat configurada.
//   2. Flicker: multiplicador global de brillo modulat per temps.
//   3. Background pulse: color de fons additiu que oscil·la entre min/max.
//
// L'arquitectura anterior tenia el bloom inline (kernel 7×7 single-pass), que
// produïa moiré per radis grans. Ara el bloom és pre-computed via separable
// gaussian (equivalent a kernel 15×15 dens) i aquí només cal samplejar-lo.
//
// Resource sets (SDL_gpu):
//   set=2, binding=0 → sampler2D (escena offscreen)
//   set=2, binding=1 → sampler2D (bloom pre-calculat)
//   set=3, binding=0 → uniform buffer (paràmetres del postpro)

layout(set = 2, binding = 0) uniform sampler2D scene;
layout(set = 2, binding = 1) uniform sampler2D bloom_tex;

layout(set = 3, binding = 0) uniform PostFxUBO {
    float time;
    float bloom_intensity;
    float flicker_amplitude;
    float flicker_frequency_hz;

    float background_pulse_freq_hz;
    float _pad_a;
    float _pad_b;
    float _pad_c;

    vec4 background_min;   // RGB en [0..1], A=1
    vec4 background_max;   // RGB en [0..1], A=1
} ubo;

layout(location = 0) in vec2 v_uv;
layout(location = 0) out vec4 frag;

const float TAU = 6.28318530718;

void main() {
    vec3 src = texture(scene, v_uv).rgb;
    vec3 bloom = texture(bloom_tex, v_uv).rgb * ubo.bloom_intensity;

    // === FLICKER ===
    // Multiplicador global de brillo. Oscil·la entre (1.0 - amplitude) i 1.0.
    float pulse = (sin(ubo.time * ubo.flicker_frequency_hz * TAU) * 0.5) + 0.5;
    float flicker = 1.0 - (ubo.flicker_amplitude * (1.0 - pulse));

    // === BACKGROUND PULSE ===
    float bg_pulse = (sin(ubo.time * ubo.background_pulse_freq_hz * TAU) * 0.5) + 0.5;
    vec3 background = mix(ubo.background_min.rgb, ubo.background_max.rgb, bg_pulse);

    // === COMPOSICIÓ (preserve-core) ===
    // Bloom additiu però atenuat per (1 - luma_src): no contribueix als píxels
    // on la línia ja és brillant (manté el color del core sense rentar-lo cap a
    // blanc) i contribueix al màxim als píxels foscos del voltant (halo intens).
    // El flicker només multiplica (línies + bloom); el fons va a banda perquè
    // els píxels foscos no han de pulsar.
    float src_luma = max(src.r, max(src.g, src.b));
    vec3 bloom_contribution = bloom * (1.0 - src_luma);
    vec3 lines_and_glow = (src + bloom_contribution) * flicker;
    frag = vec4(background + lines_and_glow, 1.0);
}
