aboutsummaryrefslogtreecommitdiffstats
path: root/mpv/shaders/deband.glsl
diff options
context:
space:
mode:
Diffstat (limited to 'mpv/shaders/deband.glsl')
-rw-r--r--mpv/shaders/deband.glsl42
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;
+}