diff options
Diffstat (limited to 'mpv/shaders')
-rw-r--r-- | mpv/shaders/deband.glsl | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/mpv/shaders/deband.glsl b/mpv/shaders/deband.glsl new file mode 100644 index 0000000..1b2f047 --- /dev/null +++ b/mpv/shaders/deband.glsl @@ -0,0 +1,42 @@ +// vim: set ft=glsl: + +// roughly corresponds to f3kdb parameters, which this algorithm is +// loosely inspired by +#define threshold 64 +#define range 16 +#define grain 24 + +float rand(vec2 co){ + return fract(sin(dot(co.yx, vec2(12.9898,78.233))) * 43758.5453); +} + +vec4 sample(sampler2D tex, vec2 pos, vec2 tex_size) +{ + // Compute a random angle and distance + float dist = rand(pos + vec2(random)) * range; + vec2 pt = dist / image_size; + float dir = rand(pos.yx - vec2(random)) * 6.2831853; + vec2 o = vec2(cos(dir), sin(dir)); + + // Sample at quarter-turn intervals around the source pixel + vec4 ref[4]; + ref[0] = texture(tex, pos + pt * vec2( o.x, o.y)); + ref[1] = texture(tex, pos + pt * vec2(-o.y, o.x)); + ref[2] = texture(tex, pos + pt * vec2(-o.x, -o.y)); + ref[3] = texture(tex, pos + pt * vec2( o.y, -o.x)); + + // Average and compare with the actual sample + vec4 avg = cmul*(ref[0] + ref[1] + ref[2] + ref[3])/4.0; + vec4 col = cmul*texture(tex, pos); + vec4 diff = abs(col - avg); + + // Use the average if below the threshold + col = mix(avg, col, greaterThan(diff, vec4(threshold/16384.0))); + + // Add some random noise to the output + vec3 noise = vec3(rand(2*pos + vec2(random)), + rand(3*pos + vec2(random)), + rand(4*pos + vec2(random))); + col.rgb += (grain/8192.0) * (noise - vec3(0.5)); + return col; +} |