diff options
Diffstat (limited to 'intern/opencolorio/gpu_shader_display_transform.glsl')
-rw-r--r-- | intern/opencolorio/gpu_shader_display_transform.glsl | 183 |
1 files changed, 96 insertions, 87 deletions
diff --git a/intern/opencolorio/gpu_shader_display_transform.glsl b/intern/opencolorio/gpu_shader_display_transform.glsl index 9787398e2ae..f1f77cf7df2 100644 --- a/intern/opencolorio/gpu_shader_display_transform.glsl +++ b/intern/opencolorio/gpu_shader_display_transform.glsl @@ -1,70 +1,68 @@ +/* Blender OpenColorIO implementation */ + +uniform sampler1D curve_mapping_texture; uniform sampler2D image_texture; +uniform sampler2D overlay_texture; uniform sampler3D lut3d_texture; +uniform sampler3D lut3d_display_texture; -#ifdef USE_DITHER uniform float dither; -#endif - -in vec2 texCoord_interp; -out vec4 fragColor; +uniform bool predivide; +uniform bool curve_mapping; +uniform bool overlay; -#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 int 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; +layout(std140) uniform OCIO_GLSLCurveMappingParameters +{ + /* Curve mapping parameters + * + * See documentation for OCIO_CurveMappingSettings to get fields descriptions. + * (this ones pretty much copies stuff from C structure.) + */ + vec4 curve_mapping_mintable; + vec4 curve_mapping_range; + vec4 curve_mapping_ext_in_x; + vec4 curve_mapping_ext_in_y; + vec4 curve_mapping_ext_out_x; + vec4 curve_mapping_ext_out_y; + vec4 curve_mapping_first_x; + vec4 curve_mapping_first_y; + vec4 curve_mapping_last_x; + vec4 curve_mapping_last_y; + vec4 curve_mapping_black; + vec4 curve_mapping_bwmul; + int curve_mapping_lut_size; + int curve_mapping_use_extend_extrapolate; +}; 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 texture(curve_mapping_texture, texture_index)[table]; + return texelFetch(curve_mapping_texture, index, 0)[table]; } float curvemap_calc_extend(int table, float x, vec2 first, vec2 last) { if (x <= first[0]) { - if (use_curve_mapping_extend_extrapolate == 0) { + if (curve_mapping_use_extend_extrapolate == 0) { /* horizontal extrapolation */ 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]; + float fac = (curve_mapping_ext_in_x[table] != 0.0) ? + ((x - first[0]) / curve_mapping_ext_in_x[table]) : + 10000.0; + return first[1] + curve_mapping_ext_in_y[table] * fac; } } else if (x >= last[0]) { - if (use_curve_mapping_extend_extrapolate == 0) { + if (curve_mapping_use_extend_extrapolate == 0) { /* horizontal extrapolation */ 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]; + float fac = (curve_mapping_ext_out_x[table] != 0.0) ? + ((x - last[0]) / curve_mapping_ext_out_x[table]) : + -10000.0; + return last[1] + curve_mapping_ext_out_y[table] * fac; } } return 0.0; @@ -92,80 +90,91 @@ float curvemap_evaluateF(int table, float value) vec2(curve_mapping_last_x[table], curve_mapping_last_y[table])); } else { - if (i < 0) + if (i < 0) { return read_curve_mapping(table, 0); - if (i >= CM_TABLE) + } + 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); + float cm1 = read_curve_mapping(table, i); + float cm2 = read_curve_mapping(table, i + 1); + return mix(cm1, cm2, fi); } } 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]; + col.rgb = (col.rgb - curve_mapping_black.rgb) * curve_mapping_bwmul.rgb; + + vec4 result; + result.r = curvemap_evaluateF(0, col.r); + result.g = curvemap_evaluateF(1, col.g); + result.b = curvemap_evaluateF(2, col.b); + result.a = col.a; 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 round_to_pixel(sampler2D tex, vec2 uv) { - vec2 result; - vec2 size = textureSize(image_texture, 0); - result.x = float(int(st.x * size.x)) / size.x; - result.y = float(int(st.y * size.y)) / size.y; - return result; + vec2 size = textureSize(tex, 0); + return vec2(ivec2(uv * size)) / size; } -vec4 apply_dither(vec2 st, vec4 col) +vec4 apply_dither(vec4 col, vec2 uv) { - 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; + col.rgb += dither_random_value(uv); + return col; } -#endif -void main() +vec4 OCIO_ProcessColor(vec4 col, vec4 col_overlay, vec2 noise_uv) { - vec4 col = texture(image_texture, texCoord_interp.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; + if (curve_mapping) { + col = curvemapping_evaluate_premulRGBF(col); + } + + if (predivide) { + if (col.a > 0.0 && col.a < 1.0) { + col.rgb *= 1.0 / col.a; + } } -#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); + col = OCIO_to_display_linear_with_look(col, lut3d_texture); + + if (dither > 0.0) { + col = apply_dither(col, noise_uv); + } + + if (overlay) { + col *= 1.0 - col_overlay.a; + col += col_overlay; /* Assumed unassociated alpha. */ + } -#ifdef USE_DITHER - result = apply_dither(texCoord_interp.st, result); -#endif + col = OCIO_to_display_encoded(col, lut3d_display_texture); - fragColor = result; + return col; } + +/* ------------------------------------------------------------------------ */ + +in vec2 texCoord_interp; +out vec4 fragColor; + +void main() +{ + vec4 col = texture(image_texture, texCoord_interp.st); + vec4 col_overlay = texture(overlay_texture, texCoord_interp.st); + vec2 noise_uv = round_to_pixel(image_texture, texCoord_interp.st); + + fragColor = OCIO_ProcessColor(col, col_overlay, noise_uv); +}
\ No newline at end of file |