const COLOR: &str = r#"
void main() {
vec2 uv = gl_FragCoord.xy / u_res;
vec4 src = texture(tex, uv);
vec3 c = src.rgb;
float l = dot(c, vec3(0.2126, 0.7152, 0.0722));
c = mix(vec3(l), c, p2);
float a = radians(p3), cs = cos(a), sn = sin(a);
mat3 hm = mat3(
0.213 + cs * 0.787 - sn * 0.213, 0.213 - cs * 0.213 + sn * 0.143, 0.213 - cs * 0.213 - sn * 0.787,
0.715 - cs * 0.715 - sn * 0.715, 0.715 + cs * 0.285 + sn * 0.140, 0.715 - cs * 0.715 + sn * 0.715,
0.072 - cs * 0.072 + sn * 0.928, 0.072 - cs * 0.072 - sn * 0.283, 0.072 + cs * 0.928 + sn * 0.072);
c = clamp((clamp(hm * c, 0.0, 1.0) - 0.5) * p1 + 0.5 + p0, 0.0, 1.0);
c = pow(c, vec3(1.0 / max(p4, 0.001)));
vec4 res = vec4(c, src.a);
float m = u_has_mask > 0.5 ? texture(u_mask, uv).r : 1.0;
out_color = mix(src, res, m);
}
"#;Expand description
Saturation + hue matrix (same feColorMatrix pair as the CPU path), then brightness/contrast/gamma.