Constant COMPOSITE

Source
pub const COMPOSITE: &str = r#"
uniform sampler2D u_dst;
uniform vec2 u_layer;
uniform mat3 u_inv;
uniform int u_scaler;
uniform int u_mode;
uniform float u_opacity;

vec4 tap(vec2 ip) {
    return texelFetch(tex, ivec2(clamp(ip, vec2(0.0), u_layer - 1.0)), 0);
}

vec4 catmull_w(float t) {
    float t2 = t * t;
    float t3 = t2 * t;
    return 0.5 * vec4(-t3 + 2.0 * t2 - t, 3.0 * t3 - 5.0 * t2 + 2.0, -3.0 * t3 + 4.0 * t2 + t, t3 - t2);
}

// Alpha-weighted accumulation (matches the CPU compositor: transparent texels must not darken edges).
vec4 sample_layer(vec2 uv) {
    vec2 sp = uv * u_layer - 0.5;
    if (u_scaler == 0) { return tap(floor(sp + 0.5)); }
    vec4 acc = vec4(0.0);
    if (u_scaler == 1) {
        vec2 f = floor(sp);
        vec2 t = sp - f;
        for (int j = 0; j < 2; j++) {
            for (int i = 0; i < 2; i++) {
                float w = (i == 0 ? 1.0 - t.x : t.x) * (j == 0 ? 1.0 - t.y : t.y);
                vec4 c = tap(f + vec2(float(i), float(j)));
                acc += vec4(c.rgb * c.a * w, c.a * w);
            }
        }
    } else {
        vec2 f = floor(sp);
        vec4 wx = catmull_w(sp.x - f.x);
        vec4 wy = catmull_w(sp.y - f.y);
        for (int j = 0; j < 4; j++) {
            for (int i = 0; i < 4; i++) {
                float w = wx[i] * wy[j];
                vec4 c = tap(f + vec2(float(i - 1), float(j - 1)));
                acc += vec4(c.rgb * c.a * w, c.a * w);
            }
        }
    }
    if (acc.a <= 0.0) { return vec4(0.0); }
    return vec4(clamp(acc.rgb / acc.a, 0.0, 1.0), clamp(acc.a, 0.0, 1.0));
}

void main() {
    vec3 h = u_inv * vec3(v_uv * u_res, 1.0);
    float z = (abs(h.z) < 1e-9) ? 1e-9 : h.z;
    vec2 uv = h.xy / z;
    // derivatives must be taken outside any branch
    vec2 e = max(fwidth(uv), vec2(1e-8));
    vec2 dd = min(uv, 1.0 - uv);
    float cov = clamp(min(dd.x / e.x, dd.y / e.y) + 0.5, 0.0, 1.0);
    vec4 d = texture(u_dst, v_uv);
    if (cov <= 0.0 || h.z <= 0.0) { out_color = d; return; }
    vec4 s = sample_layer(uv);
    float a = s.a * u_opacity * cov * mask_at(v_uv);
    if (a <= 0.0) { out_color = d; return; }
    float ao = a + d.a * (1.0 - a);
    if (ao <= 0.0) { out_color = vec4(0.0); return; }
    vec3 b = blend(u_mode, s.rgb, d.rgb);
    vec3 co = ((1.0 - d.a) * a * s.rgb + (1.0 - a) * d.a * d.rgb + a * d.a * b) / ao;
    out_color = vec4(co, ao);
}
"#;
Expand description

Composite/transform shader: samples a layer through an inverse 3x3 (perspective-capable) matrix with the chosen Scaler (0 = nearest, 1 = bilinear, 2 = bicubic Catmull-Rom) and blends it onto the canvas. Appended to PRELUDE + BLEND. u_inv maps canvas pixels (y down) to layer uv.