diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2020-02-17 16:14:30 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2020-02-17 17:47:17 +0300 |
commit | 852cdd476b5572b56418d377e379c07253363eff (patch) | |
tree | 14467e0c649819e95f4de6913dfc0ac7edf4d8b8 /intern/opencolorio/gpu_shader_display_transform.glsl | |
parent | 5231d06d4cd4a613b0493965893ae17df43c0f22 (diff) |
ColorManagement: Dithering Improvement
- Unlock property range.
- Use triangular noise to keep perceptual noise error more uniform.
Remap range to preserve perceptual intensity.
- Center noise distribution around 0 for GPU implementation because of
rounding.
- Do dithering after merging overlays.
Effect of using triangular noise is not really noticeable if you don't use
really low bitdepth. But doing a test in the shader were we artificially
reduce the bitdepth (`col = (col * 16) / 16;`) reveals the real difference.
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D6850
Diffstat (limited to 'intern/opencolorio/gpu_shader_display_transform.glsl')
-rw-r--r-- | intern/opencolorio/gpu_shader_display_transform.glsl | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/intern/opencolorio/gpu_shader_display_transform.glsl b/intern/opencolorio/gpu_shader_display_transform.glsl index f1f77cf7df2..f7c64244dd6 100644 --- a/intern/opencolorio/gpu_shader_display_transform.glsl +++ b/intern/opencolorio/gpu_shader_display_transform.glsl @@ -115,9 +115,20 @@ vec4 curvemapping_evaluate_premulRGBF(vec4 col) 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) { - 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) @@ -128,7 +139,7 @@ vec2 round_to_pixel(sampler2D tex, 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; } @@ -151,10 +162,6 @@ vec4 OCIO_ProcessColor(vec4 col, vec4 col_overlay, vec2 noise_uv) 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. */ @@ -162,6 +169,10 @@ vec4 OCIO_ProcessColor(vec4 col, vec4 col_overlay, vec2 noise_uv) col = OCIO_to_display_encoded(col, lut3d_display_texture); + if (dither > 0.0) { + col = apply_dither(col, noise_uv); + } + return col; } |