// postfx_frag.msl.h - Metal Shading Language del fragment shader del composite
// © 2026 JailDesigner
//
// IMPORTANT: mantenir sincronitzat a mà amb shaders/postfx.frag.glsl. SDL3 GPU
// compila aquest string MSL en runtime; no hi ha generador automàtic. Qualsevol
// canvi al struct PostFxUniforms (gpu_postfx_pipeline.hpp), al GLSL o al MSL
// cal replicar-lo a totes tres al mateix commit.
//
// Composite final: llegeix escena + bloom pre-calculat (per bloom.frag.glsl en
// separable two-pass) i aplica flicker + background pulse. Recursos:
//   - texture2d<float> scene [[texture(0)]] + sampler [[sampler(0)]]
//   - texture2d<float> bloom_tex [[texture(1)]] + sampler [[sampler(1)]]
//   - constant PostFxUBO& ubo [[buffer(0)]]   (slot 0 SDL → buffer(0) MSL)

#pragma once
#ifdef __APPLE__

namespace Rendering::GPU::Msl {

    inline constexpr const char* POSTFX_FRAG_MSL = R"(
#include <metal_stdlib>
using namespace metal;

struct PostVOut {
    float4 pos [[position]];
    float2 uv;
};

struct 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;

    float4 background_min;
    float4 background_max;
};

constant float TAU = 6.28318530718;

fragment float4 postfx_fs(PostVOut in [[stage_in]],
                          texture2d<float> scene     [[texture(0)]],
                          sampler          samp_s   [[sampler(0)]],
                          texture2d<float> bloom_tex [[texture(1)]],
                          sampler          samp_b   [[sampler(1)]],
                          constant PostFxUBO& ubo [[buffer(0)]]) {
    float3 src = scene.sample(samp_s, in.uv).rgb;
    float3 bloom = bloom_tex.sample(samp_b, in.uv).rgb * ubo.bloom_intensity;

    // === FLICKER ===
    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;
    float3 background = mix(ubo.background_min.rgb, ubo.background_max.rgb, bg_pulse);

    // === COMPOSICIÓ (preserve-core) ===
    // Bloom additiu atenuat per (1 - luma_src) — manté el color del core
    // i posa el halo intens només als píxels foscos del voltant.
    float src_luma = max(src.r, max(src.g, src.b));
    float3 bloom_contribution = bloom * (1.0 - src_luma);
    float3 lines_and_glow = (src + bloom_contribution) * flicker;
    return float4(background + lines_and_glow, 1.0);
}
)";

}  // namespace Rendering::GPU::Msl

#endif  // __APPLE__
