Constant CURVES

Source
const CURVES: &str = r#"
uniform float p8;
uniform float p9;
uniform float p10;
uniform float p11;
float fx_curve(float x, float a, float b, float c) {
    float y[5];
    y[0] = 0.0; y[1] = a; y[2] = b; y[3] = c; y[4] = 1.0;
    float d[4];
    for (int i = 0; i < 4; i++) {
        d[i] = (y[i + 1] - y[i]) * 4.0;
    }
    float m[5];
    m[0] = d[0];
    m[4] = d[3];
    for (int i = 1; i < 4; i++) {
        m[i] = (d[i - 1] * d[i] <= 0.0) ? 0.0 : (d[i - 1] + d[i]) * 0.5;
    }
    for (int i = 0; i < 4; i++) {
        if (abs(d[i]) < 1e-6) {
            m[i] = 0.0;
            m[i + 1] = 0.0;
        } else {
            float ai = m[i] / d[i];
            float bi = m[i + 1] / d[i];
            float s = ai * ai + bi * bi;
            if (s > 9.0) {
                float k = 3.0 / sqrt(s);
                m[i] = k * ai * d[i];
                m[i + 1] = k * bi * d[i];
            }
        }
    }
    float xc = clamp(x, 0.0, 1.0);
    int i = int(min(floor(xc * 4.0), 3.0));
    float t = xc * 4.0 - float(i);
    float t2 = t * t;
    float t3 = t2 * t;
    return (2.0 * t3 - 3.0 * t2 + 1.0) * y[i] + (t3 - 2.0 * t2 + t) * 0.25 * m[i]
         + (-2.0 * t3 + 3.0 * t2) * y[i + 1] + (t3 - t2) * 0.25 * m[i + 1];
}
void main() {
    vec2 uv = gl_FragCoord.xy / u_res;
    vec4 src = texture(tex, uv);
    vec3 c = vec3(fx_curve(src.r, p3, p4, p5), fx_curve(src.g, p6, p7, p8), fx_curve(src.b, p9, p10, p11));
    c = vec3(fx_curve(c.r, p0, p1, p2), fx_curve(c.g, p0, p1, p2), fx_curve(c.b, p0, p1, p2));
    vec4 res = vec4(clamp(c, 0.0, 1.0), src.a);
    float m = u_has_mask > 0.5 ? texture(u_mask, uv).r : 1.0;
    out_color = mix(src, res, m);
}
"#;
Expand description

Twelve knots (master, R, G, B) driving a monotone cubic through (0,0) (.25,a) (.5,b) (.75,c) (1,1). Fritsch-Carlson tangents keep the spline monotone, so a curve never folds back on itself. Declares p8..p11 itself: PRELUDE only carries p0..p7.