Code refactor: don't expose UpdateObjectTransformState in header.
[blender-staging.git] / intern / opencolorio / gpu_shader_display_transform.glsl
1 uniform sampler2D image_texture;
2 uniform sampler3D lut3d_texture;
3
4 #ifdef USE_DITHER
5 uniform float dither;
6 #endif
7
8 #ifdef USE_TEXTURE_SIZE
9 uniform float image_texture_width;
10 uniform float image_texture_height;
11 #endif
12
13 #ifdef USE_CURVE_MAPPING
14 /* Curve mapping parameters
15  *
16  * See documentation for OCIO_CurveMappingSettings to get fields descriptions.
17  * (this ones pretyt much copies stuff from C structure.)
18  */
19 uniform sampler1D curve_mapping_texture;
20 uniform int curve_mapping_lut_size;
21 uniform ivec4 use_curve_mapping_extend_extrapolate;
22 uniform vec4 curve_mapping_mintable;
23 uniform vec4 curve_mapping_range;
24 uniform vec4 curve_mapping_ext_in_x;
25 uniform vec4 curve_mapping_ext_in_y;
26 uniform vec4 curve_mapping_ext_out_x;
27 uniform vec4 curve_mapping_ext_out_y;
28 uniform vec4 curve_mapping_first_x;
29 uniform vec4 curve_mapping_first_y;
30 uniform vec4 curve_mapping_last_x;
31 uniform vec4 curve_mapping_last_y;
32 uniform vec3 curve_mapping_black;
33 uniform vec3 curve_mapping_bwmul;
34
35 float read_curve_mapping(int table, int index)
36 {
37         /* TODO(sergey): Without -1 here image is getting darken after applying unite curve.
38          *               But is it actually correct to subtract 1 here?
39          */
40         float texture_index = float(index) / float(curve_mapping_lut_size  - 1);
41         return texture1D(curve_mapping_texture, texture_index)[table];
42 }
43
44 float curvemap_calc_extend(int table, float x, vec2 first, vec2 last)
45 {
46         if (x <= first[0]) {
47                 if (use_curve_mapping_extend_extrapolate[table] == 0) {
48                         /* no extrapolate */
49                         return first[1];
50                 }
51                 else {
52                         if (curve_mapping_ext_in_x[table] == 0.0)
53                                 return first[1] + curve_mapping_ext_in_y[table] * 10000.0;
54                         else
55                                 return first[1] + curve_mapping_ext_in_y[table] * (x - first[0]) / curve_mapping_ext_in_x[table];
56                 }
57         }
58         else if (x >= last[0]) {
59                 if (use_curve_mapping_extend_extrapolate[table] == 0) {
60                         /* no extrapolate */
61                         return last[1];
62                 }
63                 else {
64                         if (curve_mapping_ext_out_x[table] == 0.0)
65                                 return last[1] - curve_mapping_ext_out_y[table] * 10000.0;
66                         else
67                                 return last[1] + curve_mapping_ext_out_y[table] * (x - last[0]) / curve_mapping_ext_out_x[table];
68                 }
69         }
70         return 0.0;
71 }
72
73 float curvemap_evaluateF(int table, float value)
74 {
75         float mintable_ = curve_mapping_mintable[table];
76         float range = curve_mapping_range[table];
77         float mintable = 0.0;
78         int CM_TABLE = curve_mapping_lut_size - 1;
79
80         float fi;
81         int i;
82
83         /* index in table */
84         fi = (value - mintable) * range;
85         i = int(fi);
86
87         /* fi is table float index and should check against table range i.e. [0.0 CM_TABLE] */
88         if (fi < 0.0 || fi > float(CM_TABLE)) {
89                 return curvemap_calc_extend(table, value,
90                                             vec2(curve_mapping_first_x[table], curve_mapping_first_y[table]),
91                                             vec2(curve_mapping_last_x[table], curve_mapping_last_y[table]));
92         }
93         else {
94                 if (i < 0) return read_curve_mapping(table, 0);
95                 if (i >= CM_TABLE) return read_curve_mapping(table, CM_TABLE);
96
97                 fi = fi - float(i);
98                 return (1.0 - fi) * read_curve_mapping(table, i) + fi * read_curve_mapping(table, i + 1);
99         }
100 }
101
102 vec4 curvemapping_evaluate_premulRGBF(vec4 col)
103 {
104         vec4 result = col;
105         result[0] = curvemap_evaluateF(0, (col[0] - curve_mapping_black[0]) * curve_mapping_bwmul[0]);
106         result[1] = curvemap_evaluateF(1, (col[1] - curve_mapping_black[1]) * curve_mapping_bwmul[1]);
107         result[2] = curvemap_evaluateF(2, (col[2] - curve_mapping_black[2]) * curve_mapping_bwmul[2]);
108         result[3] = col[3];
109         return result;
110 }
111 #endif
112
113 #ifdef USE_DITHER
114 float dither_random_value(vec2 co)
115 {
116         return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453) * 0.005 * dither;
117 }
118
119 vec2 round_to_pixel(vec2 st)
120 {
121         vec2 result;
122 #ifdef USE_TEXTURE_SIZE
123         vec2 size = vec2(image_texture_width, image_texture_height);
124 #else
125         vec2 size = textureSize(image_texture, 0);
126 #endif
127         result.x = float(int(st.x * size.x)) / size.x;
128         result.y = float(int(st.y * size.y)) / size.y;
129         return result;
130 }
131
132 vec4 apply_dither(vec2 st, vec4 col)
133 {
134         vec4 result;
135         float random_value = dither_random_value(round_to_pixel(st));
136         result.r = col.r + random_value;
137         result.g = col.g + random_value;
138         result.b = col.b + random_value;
139         result.a = col.a;
140         return result;
141 }
142 #endif
143
144 void main()
145 {
146         vec4 col = texture2D(image_texture, gl_TexCoord[0].st);
147 #ifdef USE_CURVE_MAPPING
148         col = curvemapping_evaluate_premulRGBF(col);
149 #endif
150
151 #ifdef USE_PREDIVIDE
152         if (col[3] > 0.0 && col[3] < 1.0) {
153                 float inv_alpha = 1.0 / col[3];
154                 col[0] *= inv_alpha;
155                 col[1] *= inv_alpha;
156                 col[2] *= inv_alpha;
157         }
158 #endif
159
160         /* NOTE: This is true we only do de-premul here and NO premul
161          *       and the reason is simple -- opengl is always configured
162          *       for straight alpha at this moment
163          */
164
165         vec4 result = OCIODisplay(col, lut3d_texture);
166
167 #ifdef USE_DITHER
168         result = apply_dither(gl_TexCoord[0].st, result);
169 #endif
170
171         gl_FragColor = result;
172 }