mediump float blend_stroke_screen(mediump float base, mediump float stroke) { return base + stroke - (base * stroke); } mediump float blend_stroke_hard_light(mediump float base, mediump float stroke) { if (stroke < 0.5) return base * (stroke * 2.0); // multiply else return blend_stroke_screen(base, 2.0 * stroke - 1.0); } mediump float blend_stroke_hard_mix(mediump float base, mediump float stroke) { return base + stroke < 0.5 ? 0.0 : base + stroke; } mediump float blend_stroke_color_dodge(mediump float base, mediump float stroke) { if (base == 0.0) return 0.0; else if (stroke == 1.0) return 1.0; else return base / (1.0 - stroke); } mediump float blend_stroke_color_burn(mediump float base, mediump float stroke) { if (base == 1.0) return 1.0; else if (stroke == 0.0) return 0.0; else return 1.0 - min(1.0, (1.0 - base) / stroke); } mediump float blend_stroke_linear_height(mediump float base, mediump float stroke, mediump float depth) { mediump float partial = (1.0 - stroke) * pow(depth, 0.25) + (base * depth * 10.0); return base * partial; } mediump float blend_stroke_height(mediump float base, mediump float stroke, mediump float depth) { mediump float A = pow((1.0 - stroke), max(1.0, (1.0 - depth) * 10.0)) * pow(depth, 0.25); mediump float B = (base * depth * 5.0); return base * (A + B); } mediump float blend_stroke(mediump float base, mediump float stroke, mediump float depth, int mode) { if (mode == 0) /* normal */ return mix(base, stroke, depth); else if (mode == 1) /* multiply */ return mix(base, base * stroke, depth); else if (mode == 2) /* subtract */ return mix(base, max(0.0, base - stroke), depth); else if (mode == 3) /* darken */ return mix(base, min(base, stroke), depth); else if (mode == 4) /* overlay */ return mix(base, blend_stroke_hard_light(stroke, base), depth); else if (mode == 5) /* col-dodge */ return mix(base, blend_stroke_color_dodge(base, stroke), depth); else if (mode == 6) /* col-burn */ return mix(base, blend_stroke_color_burn(base, stroke), depth); else if (mode == 7) /* lin-burn */ return mix(base, clamp(base + stroke - 1.0, 0.0, 1.0), depth); else if (mode == 8) /* hard-mix */ return mix(base, blend_stroke_hard_mix(base, stroke), depth); else if (mode == 9) /* lin-height */ return blend_stroke_linear_height(base, stroke, depth); else if (mode ==10) /* height */ return blend_stroke_height(base, stroke, depth); else return 1.0; }