173 lines
4.7 KiB
GLSL
173 lines
4.7 KiB
GLSL
uniform sampler2D image_texture;
|
|
uniform sampler3D lut3d_texture;
|
|
|
|
#ifdef USE_DITHER
|
|
uniform float dither;
|
|
#endif
|
|
|
|
#ifdef USE_TEXTURE_SIZE
|
|
uniform float image_texture_width;
|
|
uniform float image_texture_height;
|
|
#endif
|
|
|
|
#ifdef USE_CURVE_MAPPING
|
|
/* Curve mapping parameters
|
|
*
|
|
* See documentation for OCIO_CurveMappingSettings to get fields descriptions.
|
|
* (this ones pretyt much copies stuff from C structure.)
|
|
*/
|
|
uniform sampler1D curve_mapping_texture;
|
|
uniform int curve_mapping_lut_size;
|
|
uniform ivec4 use_curve_mapping_extend_extrapolate;
|
|
uniform vec4 curve_mapping_mintable;
|
|
uniform vec4 curve_mapping_range;
|
|
uniform vec4 curve_mapping_ext_in_x;
|
|
uniform vec4 curve_mapping_ext_in_y;
|
|
uniform vec4 curve_mapping_ext_out_x;
|
|
uniform vec4 curve_mapping_ext_out_y;
|
|
uniform vec4 curve_mapping_first_x;
|
|
uniform vec4 curve_mapping_first_y;
|
|
uniform vec4 curve_mapping_last_x;
|
|
uniform vec4 curve_mapping_last_y;
|
|
uniform vec3 curve_mapping_black;
|
|
uniform vec3 curve_mapping_bwmul;
|
|
|
|
float read_curve_mapping(int table, int index)
|
|
{
|
|
/* TODO(sergey): Without -1 here image is getting darken after applying unite curve.
|
|
* But is it actually correct to subtract 1 here?
|
|
*/
|
|
float texture_index = float(index) / float(curve_mapping_lut_size - 1);
|
|
return texture1D(curve_mapping_texture, texture_index)[table];
|
|
}
|
|
|
|
float curvemap_calc_extend(int table, float x, vec2 first, vec2 last)
|
|
{
|
|
if (x <= first[0]) {
|
|
if (use_curve_mapping_extend_extrapolate[table] == 0) {
|
|
/* no extrapolate */
|
|
return first[1];
|
|
}
|
|
else {
|
|
if (curve_mapping_ext_in_x[table] == 0.0)
|
|
return first[1] + curve_mapping_ext_in_y[table] * 10000.0;
|
|
else
|
|
return first[1] + curve_mapping_ext_in_y[table] * (x - first[0]) / curve_mapping_ext_in_x[table];
|
|
}
|
|
}
|
|
else if (x >= last[0]) {
|
|
if (use_curve_mapping_extend_extrapolate[table] == 0) {
|
|
/* no extrapolate */
|
|
return last[1];
|
|
}
|
|
else {
|
|
if (curve_mapping_ext_out_x[table] == 0.0)
|
|
return last[1] - curve_mapping_ext_out_y[table] * 10000.0;
|
|
else
|
|
return last[1] + curve_mapping_ext_out_y[table] * (x - last[0]) / curve_mapping_ext_out_x[table];
|
|
}
|
|
}
|
|
return 0.0;
|
|
}
|
|
|
|
float curvemap_evaluateF(int table, float value)
|
|
{
|
|
float mintable_ = curve_mapping_mintable[table];
|
|
float range = curve_mapping_range[table];
|
|
float mintable = 0.0;
|
|
int CM_TABLE = curve_mapping_lut_size - 1;
|
|
|
|
float fi;
|
|
int i;
|
|
|
|
/* index in table */
|
|
fi = (value - mintable) * range;
|
|
i = int(fi);
|
|
|
|
/* fi is table float index and should check against table range i.e. [0.0 CM_TABLE] */
|
|
if (fi < 0.0 || fi > float(CM_TABLE)) {
|
|
return curvemap_calc_extend(table, value,
|
|
vec2(curve_mapping_first_x[table], curve_mapping_first_y[table]),
|
|
vec2(curve_mapping_last_x[table], curve_mapping_last_y[table]));
|
|
}
|
|
else {
|
|
if (i < 0) return read_curve_mapping(table, 0);
|
|
if (i >= CM_TABLE) return read_curve_mapping(table, CM_TABLE);
|
|
|
|
fi = fi - float(i);
|
|
return (1.0 - fi) * read_curve_mapping(table, i) + fi * read_curve_mapping(table, i + 1);
|
|
}
|
|
}
|
|
|
|
vec4 curvemapping_evaluate_premulRGBF(vec4 col)
|
|
{
|
|
vec4 result = col;
|
|
result[0] = curvemap_evaluateF(0, (col[0] - curve_mapping_black[0]) * curve_mapping_bwmul[0]);
|
|
result[1] = curvemap_evaluateF(1, (col[1] - curve_mapping_black[1]) * curve_mapping_bwmul[1]);
|
|
result[2] = curvemap_evaluateF(2, (col[2] - curve_mapping_black[2]) * curve_mapping_bwmul[2]);
|
|
result[3] = col[3];
|
|
return result;
|
|
}
|
|
#endif
|
|
|
|
#ifdef USE_DITHER
|
|
float dither_random_value(vec2 co)
|
|
{
|
|
return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453) * 0.005 * dither;
|
|
}
|
|
|
|
vec2 round_to_pixel(vec2 st)
|
|
{
|
|
vec2 result;
|
|
#ifdef USE_TEXTURE_SIZE
|
|
vec2 size = vec2(image_texture_width, image_texture_height);
|
|
#else
|
|
vec2 size = textureSize(image_texture, 0);
|
|
#endif
|
|
result.x = float(int(st.x * size.x)) / size.x;
|
|
result.y = float(int(st.y * size.y)) / size.y;
|
|
return result;
|
|
}
|
|
|
|
vec4 apply_dither(vec2 st, vec4 col)
|
|
{
|
|
vec4 result;
|
|
float random_value = dither_random_value(round_to_pixel(st));
|
|
result.r = col.r + random_value;
|
|
result.g = col.g + random_value;
|
|
result.b = col.b + random_value;
|
|
result.a = col.a;
|
|
return result;
|
|
}
|
|
#endif
|
|
|
|
void main()
|
|
{
|
|
vec4 col = texture2D(image_texture, gl_TexCoord[0].st);
|
|
#ifdef USE_CURVE_MAPPING
|
|
col = curvemapping_evaluate_premulRGBF(col);
|
|
#endif
|
|
|
|
#ifdef USE_PREDIVIDE
|
|
if (col[3] > 0.0 && col[3] < 1.0) {
|
|
float inv_alpha = 1.0 / col[3];
|
|
col[0] *= inv_alpha;
|
|
col[1] *= inv_alpha;
|
|
col[2] *= inv_alpha;
|
|
}
|
|
#endif
|
|
|
|
/* NOTE: This is true we only do de-premul here and NO premul
|
|
* and the reason is simple -- opengl is always configured
|
|
* for straight alpha at this moment
|
|
*/
|
|
|
|
vec4 result = OCIODisplay(col, lut3d_texture);
|
|
|
|
#ifdef USE_DITHER
|
|
result = apply_dither(gl_TexCoord[0].st, result);
|
|
#endif
|
|
|
|
gl_FragColor = result;
|
|
}
|