uniform sampler2D image_texture; uniform sampler3D lut3d_texture; uniform bool predivide; #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 void main() { vec4 col = texture2D(image_texture, gl_TexCoord[0].st); #ifdef USE_CURVE_MAPPING col = curvemapping_evaluate_premulRGBF(col); #endif if (predivide && 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; } /* 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 */ gl_FragColor = OCIODisplay(col, lut3d_texture); }