diff options
Diffstat (limited to 'intern/opencolorio/gpu_shader_display_transform.glsl')
-rw-r--r-- | intern/opencolorio/gpu_shader_display_transform.glsl | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/intern/opencolorio/gpu_shader_display_transform.glsl b/intern/opencolorio/gpu_shader_display_transform.glsl new file mode 100644 index 00000000000..6ba3fa55e8f --- /dev/null +++ b/intern/opencolorio/gpu_shader_display_transform.glsl @@ -0,0 +1,123 @@ +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); +} |