// TruVisuals CRT Vignette — old CRT-tube edge darkening.
//   Superellipse falloff: pow(|nx|,k)+pow(|ny|,k) with nx,ny in -1..1 (frame-centered),
//   giving ROUNDED corners (k=2 oval .. k=8 squarish). Static, per-pixel darkening.
//   A very subtle extra falloff sits in the extreme corners for the tube feel.
//   Pixel math designed & verified in Python first (identical result).

DEFINE_UI_PARAMS(amount, Amount,    DCTLUI_SLIDER_FLOAT, 0.25, 0.0, 1.0, 0.01)
DEFINE_UI_PARAMS(vsize, Size,      DCTLUI_SLIDER_FLOAT, 0.25, 0.0, 0.7, 0.01)
DEFINE_UI_PARAMS(roundness, Roundness, DCTLUI_SLIDER_FLOAT, 4.0,  2.0, 8.0, 0.5)

__DEVICE__ float sstep(float e0, float e1, float x)
{
    float t = _saturatef((x - e0) / (e1 - e0));
    return t * t * (3.0f - 2.0f * t);
}

__DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B)
{
    // frame-centered normalized coords, pixel-center sampled  -> -1..1 on each axis
    float nx = ((float)p_X + 0.5f) / (float)p_Width  * 2.0f - 1.0f;
    float ny = ((float)p_Y + 0.5f) / (float)p_Height * 2.0f - 1.0f;

    // superellipse radius: r=1 at edge midpoints, r=2^(1/k) at the corners
    float k  = roundness;
    float se = _powf(_fabs(nx), k) + _powf(_fabs(ny), k);
    float r  = _powf(se, 1.0f / k);

    // main body darkening: starts at (1 - Size) in from center, full Amount by the edge (r=1)
    float start = 1.0f - vsize;
    float main  = sstep(start, 1.0f, r);

    // subtle extra darkening living only in the extreme corners (r>1 out to the corner)
    float cornerMax = _powf(2.0f, 1.0f / k);
    float corner    = sstep(1.0f, cornerMax, r);

    float darken = amount * main + 0.5f * amount * corner;
    float mult   = _saturatef(1.0f - darken);

    return make_float3(p_R * mult, p_G * mult, p_B * mult);
}
