Squash linear gamma back into the sRGB curve at the end.
[movit] / fs.glsl
1 #version 120
2 uniform sampler2D tex;
3 varying vec2 tc;
4 uniform vec3 lift, gain;
5 uniform vec3 gain_pow_inv_gamma, inv_gamma_22;
6 uniform float saturation;
7
8 #if 0
9 // if we have the lut
10 uniform sampler1D srgb_tex, srgb_reverse_tex;
11 vec3 to_linear(vec3 x) {
12         vec3 ret;
13         ret.r = texture1D(srgb_tex, x.r).x;
14         ret.g = texture1D(srgb_tex, x.g).x;
15         ret.b = texture1D(srgb_tex, x.b).x;
16         return ret;
17 }
18 vec3 from_linear(vec3 x) {
19         vec3 ret;
20         ret.r = texture1D(srgb_reverse_tex, x.r).x;
21         ret.g = texture1D(srgb_reverse_tex, x.g).x;
22         ret.b = texture1D(srgb_reverse_tex, x.b).x;
23         return ret;
24 }
25 #else
26 // use arithmetic (slow)
27 vec3 to_linear(vec3 x) {
28         vec3 a = x * vec3(1.0/12.92); 
29         vec3 b = pow((x + vec3(0.055)) * vec3(1.0/1.055), vec3(2.4));
30         vec3 f = vec3(greaterThan(x, vec3(0.04045)));
31         return mix(a, b, f); 
32
33 vec3 from_linear(vec3 x) {
34         vec3 a = vec3(12.92) * x;
35         vec3 b = vec3(1.055) * pow(x, vec3(1.0/2.4)) - vec3(0.055);
36         vec3 f = vec3(greaterThan(x, vec3(0.0031308)));
37         return mix(a, b, f);
38 }
39 #endif
40
41 void main()
42 {
43         vec3 x = texture2D(tex, tc).rgb;
44         x = to_linear(x);
45
46         // do lift in nonlinear space (the others don't care)
47         x = pow(x, vec3(1.0/2.2));
48         x += lift * (vec3(1) - x);
49         x = pow(x, inv_gamma_22);
50         x *= gain_pow_inv_gamma;
51
52         // LMS correction
53 //      x = colorMat * x;
54
55         // saturate/desaturate (in linear space)
56         float luminance = dot(x, vec3(0.2126, 0.7152, 0.0722));
57         x = mix(vec3(luminance), x, saturation);
58
59         gl_FragColor.rgb = from_linear(x);
60         gl_FragColor.a = 1.0f;
61 }