Changeset View
Changeset View
Standalone View
Standalone View
intern/opencolorio/gpu_shader_display_transform.glsl
| Show First 20 Lines • Show All 109 Lines • ▼ Show 20 Lines | vec4 curvemapping_evaluate_premulRGBF(vec4 col) | ||||
| vec4 result; | vec4 result; | ||||
| result.r = curvemap_evaluateF(0, col.r); | result.r = curvemap_evaluateF(0, col.r); | ||||
| result.g = curvemap_evaluateF(1, col.g); | result.g = curvemap_evaluateF(1, col.g); | ||||
| result.b = curvemap_evaluateF(2, col.b); | result.b = curvemap_evaluateF(2, col.b); | ||||
| result.a = col.a; | result.a = col.a; | ||||
| return result; | return result; | ||||
| } | } | ||||
| /* Using a triangle distribution which gives a more final uniform noise. | |||||
| * See Banding in Games:A Noisy Rant(revision 5) Mikkel Gjøl, Playdead (slide 27) */ | |||||
| /* GPUs are rounding before writting to framebuffer so we center the distribution around 0.0. */ | |||||
| /* Return triangle noise in [-1..1[ range */ | |||||
| float dither_random_value(vec2 co) | float dither_random_value(vec2 co) | ||||
| { | { | ||||
| return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453) * 0.005 * dither; | /* Original code from https://www.shadertoy.com/view/4t2SDh */ | ||||
| /* Uniform noise in [0..1[ range */ | |||||
| float nrnd0 = fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453); | |||||
| /* Convert uniform distribution into triangle-shaped distribution. */ | |||||
| float orig = nrnd0 * 2.0 - 1.0; | |||||
| nrnd0 = orig * inversesqrt(abs(orig)); | |||||
| nrnd0 = max(-1.0, nrnd0); /* Removes nan's */ | |||||
| return nrnd0 - sign(orig); | |||||
| } | } | ||||
| vec2 round_to_pixel(sampler2D tex, vec2 uv) | vec2 round_to_pixel(sampler2D tex, vec2 uv) | ||||
| { | { | ||||
| vec2 size = textureSize(tex, 0); | vec2 size = textureSize(tex, 0); | ||||
| return vec2(ivec2(uv * size)) / size; | return vec2(ivec2(uv * size)) / size; | ||||
| } | } | ||||
| vec4 apply_dither(vec4 col, vec2 uv) | vec4 apply_dither(vec4 col, vec2 uv) | ||||
| { | { | ||||
| col.rgb += dither_random_value(uv); | col.rgb += dither_random_value(uv) * 0.0033 * dither; | ||||
| return col; | return col; | ||||
| } | } | ||||
| vec4 OCIO_ProcessColor(vec4 col, vec4 col_overlay, vec2 noise_uv) | vec4 OCIO_ProcessColor(vec4 col, vec4 col_overlay, vec2 noise_uv) | ||||
| { | { | ||||
| if (curve_mapping) { | if (curve_mapping) { | ||||
| col = curvemapping_evaluate_premulRGBF(col); | col = curvemapping_evaluate_premulRGBF(col); | ||||
| } | } | ||||
| if (predivide) { | if (predivide) { | ||||
| if (col.a > 0.0 && col.a < 1.0) { | if (col.a > 0.0 && col.a < 1.0) { | ||||
| col.rgb *= 1.0 / col.a; | col.rgb *= 1.0 / col.a; | ||||
| } | } | ||||
| } | } | ||||
| /* NOTE: This is true we only do de-premul here and NO premul | /* NOTE: This is true we only do de-premul here and NO premul | ||||
| * and the reason is simple -- opengl is always configured | * and the reason is simple -- opengl is always configured | ||||
| * for straight alpha at this moment | * for straight alpha at this moment | ||||
| */ | */ | ||||
| col = OCIO_to_display_linear_with_look(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) { | if (overlay) { | ||||
| col *= 1.0 - col_overlay.a; | col *= 1.0 - col_overlay.a; | ||||
| col += col_overlay; /* Assumed unassociated alpha. */ | col += col_overlay; /* Assumed unassociated alpha. */ | ||||
| } | } | ||||
| col = OCIO_to_display_encoded(col, lut3d_display_texture); | col = OCIO_to_display_encoded(col, lut3d_display_texture); | ||||
| if (dither > 0.0) { | |||||
| col = apply_dither(col, noise_uv); | |||||
| } | |||||
| return col; | return col; | ||||
| } | } | ||||
| /* ------------------------------------------------------------------------ */ | /* ------------------------------------------------------------------------ */ | ||||
| in vec2 texCoord_interp; | in vec2 texCoord_interp; | ||||
| out vec4 fragColor; | out vec4 fragColor; | ||||
| void main() | void main() | ||||
| { | { | ||||
| vec4 col = texture(image_texture, texCoord_interp.st); | vec4 col = texture(image_texture, texCoord_interp.st); | ||||
| vec4 col_overlay = texture(overlay_texture, texCoord_interp.st); | vec4 col_overlay = texture(overlay_texture, texCoord_interp.st); | ||||
| vec2 noise_uv = round_to_pixel(image_texture, texCoord_interp.st); | vec2 noise_uv = round_to_pixel(image_texture, texCoord_interp.st); | ||||
| fragColor = OCIO_ProcessColor(col, col_overlay, noise_uv); | fragColor = OCIO_ProcessColor(col, col_overlay, noise_uv); | ||||
| } | } | ||||
| No newline at end of file | No newline at end of file | ||||