| uniform half grayscale, invertStyle, contrast; |
| |
| half3 hsl_to_rgb(half3 hsl) { |
| half C = (1 - abs(2 * hsl.z - 1)) * hsl.y; |
| half3 p = hsl.xxx + half3(0, 2/3.0, 1/3.0); |
| half3 q = saturate(abs(fract(p) * 6 - 3) - 1); |
| |
| return (q - 0.5) * C + hsl.z; |
| } |
| |
| half3 rgb_to_hsl(half3 c) { |
| half mx = max(max(c.r,c.g),c.b), |
| mn = min(min(c.r,c.g),c.b), |
| d = mx-mn, |
| invd = 1.0 / d, |
| g_lt_b = c.g < c.b ? 6.0 : 0.0; |
| |
| // We'd prefer to write these tests like `mx == c.r`, but on some GPUs max(x,y) is |
| // not always equal to either x or y. So we use long form, c.r >= c.g && c.r >= c.b. |
| half h = (1/6.0) * (mx == mn ? 0.0 : |
| /*mx==c.r*/ c.r >= c.g && c.r >= c.b ? invd * (c.g - c.b) + g_lt_b : |
| /*mx==c.g*/ c.g >= c.b ? invd * (c.b - c.r) + 2.0 |
| /*mx==c.b*/ : invd * (c.r - c.g) + 4.0); |
| half sum = mx+mn, |
| l = sum * 0.5, |
| s = mx == mn ? 0.0 |
| : d / (l > 0.5 ? 2.0 - sum : sum); |
| return half3(h,s,l); |
| } |
| |
| half4 main(half4 inColor) { |
| half3 c = inColor.rgb; |
| if (grayscale == 1) { |
| c = dot(half3(0.2126, 0.7152, 0.0722), c).rrr; |
| } |
| if (invertStyle == 1) { // brightness |
| c = 1 - c; |
| } else if (invertStyle == 2) { // lightness |
| c = rgb_to_hsl(c); |
| c.b = 1 - c.b; |
| c = hsl_to_rgb(c); |
| } |
| c = mix(half3(0.5), c, contrast); |
| return half4(saturate(c), inColor.a); |
| } |