[Scummvm-git-logs] scummvm-shaders master -> bdebad9deb688a04ab5fd2afa07de6db1169c089

lotharsm noreply at scummvm.org
Sat Jan 7 23:25:48 UTC 2023


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm-shaders' repo located at https://github.com/scummvm/scummvm-shaders .

Summary:
bdebad9deb SHADERS: Add basic upscaling and interpolation filters, including xbr


Commit: bdebad9deb688a04ab5fd2afa07de6db1169c089
    https://github.com/scummvm/scummvm-shaders/commit/bdebad9deb688a04ab5fd2afa07de6db1169c089
Author: Lothar Serra Mari (mail at serra.me)
Date: 2023-01-08T00:25:41+01:00

Commit Message:
SHADERS: Add basic upscaling and interpolation filters, including xbr

Changed paths:
  A base/cubic/bicubic.glslp
  A base/cubic/catmull-rom.glslp
  A base/cubic/cubic-gamma-correct.glslp
  A base/cubic/cubic.glslp
  A base/cubic/shaders/bicubic.glsl
  A base/cubic/shaders/catmull-rom.glsl
  A base/cubic/shaders/cubic-gamma-correct.glsl
  A base/cubic/shaders/cubic.glsl
  A base/cubic/shaders/linearize.glsl
  A base/interpolation/aann.glslp
  A base/interpolation/bandlimit-pixel.glslp
  A base/interpolation/controlled_sharpness.glslp
  A base/interpolation/pixellate.glslp
  A base/interpolation/quilez.glslp
  A base/interpolation/shaders/ControlledSharpness.glsl
  A base/interpolation/shaders/aann.glsl
  A base/interpolation/shaders/bandlimit-pixel.glsl
  A base/interpolation/shaders/pixellate.glsl
  A base/interpolation/shaders/quilez.glsl
  A base/interpolation/shaders/sharp-bilinear-scanlines.glsl
  A base/interpolation/shaders/sharp-bilinear-simple.glsl
  A base/interpolation/shaders/sharp-bilinear.glsl
  A base/interpolation/shaders/smootheststep.glsl
  A base/interpolation/shaders/smuberstep.glsl
  A base/interpolation/sharp-bilinear-2x-prescale.glslp
  A base/interpolation/sharp-bilinear-scanlines.glslp
  A base/interpolation/sharp-bilinear-simple.glslp
  A base/interpolation/sharp-bilinear.glslp
  A base/interpolation/smootheststep.glslp
  A base/interpolation/smuberstep.glslp
  A base/linear/linearize.glsl
  A base/misc/anti-flicker.glsl
  A base/misc/bob-and-ghost-deinterlacing.glsl
  A base/misc/bob-deinterlacing.glsl
  A base/misc/cmyk-halftone-dot.glsl
  A base/misc/cocktail-cab-portrait.glsl
  A base/misc/cocktail-cabinet.glsl
  A base/misc/color-mangler.glsl
  A base/misc/colorimetry.glsl
  A base/misc/deband.glsl
  A base/misc/deposterize-pass0.glsl
  A base/misc/deposterize-pass1.glsl
  A base/misc/edge-detect.glsl
  A base/misc/flicker.glsl
  A base/misc/flip-horizontal.glsl
  A base/misc/grade.glsl
  A base/misc/image-adjustment.glsl
  A base/misc/interlacing.glsl
  A base/misc/natural-vision.glsl
  A base/misc/ntsc-colors.glsl
  A base/misc/white_point.glsl
  A base/xbr/2xBR-lv1-multipass.glslp
  A base/xbr/shaders/2xBR-multipass/2xbr-lv1-c-pass0.glsl
  A base/xbr/shaders/2xBR-multipass/2xbr-lv1-c-pass1.glsl
  A base/xbr/shaders/super-xbr/custom-jinc2-sharper.glsl
  A base/xbr/shaders/super-xbr/super-2xbr-3d-pass0.glsl
  A base/xbr/shaders/super-xbr/super-2xbr-3d-pass1.glsl
  A base/xbr/shaders/super-xbr/super-2xbr-3d-pass2.glsl
  A base/xbr/shaders/super-xbr/super-4xbr-3d-pass0.glsl
  A base/xbr/shaders/super-xbr/super-4xbr-3d-pass1.glsl
  A base/xbr/shaders/super-xbr/super-4xbr-3d-pass1f.glsl
  A base/xbr/shaders/super-xbr/super-4xbr-3d-pass2.glsl
  A base/xbr/shaders/super-xbr/super-4xbr-3d-pass3.glsl
  A base/xbr/shaders/super-xbr/super-4xbr-3d-pass3f.glsl
  A base/xbr/shaders/super-xbr/super-8xbr-3d-pass0.glsl
  A base/xbr/shaders/super-xbr/super-8xbr-3d-pass1.glsl
  A base/xbr/shaders/super-xbr/super-8xbr-3d-pass2.glsl
  A base/xbr/shaders/super-xbr/super-8xbr-3d-pass3.glsl
  A base/xbr/shaders/super-xbr/super-8xbr-3d-pass4.glsl
  A base/xbr/shaders/super-xbr/super-8xbr-3d-pass5.glsl
  A base/xbr/shaders/super-xbr/super-xbr-pass0.glsl
  A base/xbr/shaders/super-xbr/super-xbr-pass0b.glsl
  A base/xbr/shaders/super-xbr/super-xbr-pass1.glsl
  A base/xbr/shaders/super-xbr/super-xbr-pass2.glsl
  A base/xbr/shaders/xbr-hybrid/2xbr-hybrid-v5-gamma.glsl
  A base/xbr/shaders/xbr-lv2-3d.glsl
  A base/xbr/shaders/xbr-lv2-noblend.glsl
  A base/xbr/shaders/xbr-lv2.glsl
  A base/xbr/shaders/xbr-lv3-multipass/xbr-lv3-pass0.glsl
  A base/xbr/shaders/xbr-lv3-multipass/xbr-lv3-pass1.glsl
  A base/xbr/shaders/xbr-lv3.glsl
  A base/xbr/shaders/xbr-mlv4-multipass/xbr-mlv4-pass1.glsl
  A base/xbr/shaders/xbr-mlv4-multipass/xbr-mlv4-pass2.glsl
  A base/xbr/shaders/xbr-mlv4-multipass/xbr-mlv4-pass3.glsl
  A base/xbr/shaders/xbr-mlv4-multipass/xbr-mlv4-pass4.glsl
  A base/xbr/super-xbr-2p.glslp
  A base/xbr/super-xbr-3p-smoother.glslp
  A base/xbr/super-xbr-6p-adaptive.glslp
  A base/xbr/super-xbr-6p-small-details.glslp
  A base/xbr/super-xbr-6p.glslp
  A base/xbr/super-xbr-deposterize.glslp
  A base/xbr/xbr-hybrid.glslp
  A base/xbr/xbr-lv2-3d.glslp
  A base/xbr/xbr-lv2-noblend.glslp
  A base/xbr/xbr-lv2.glslp
  A base/xbr/xbr-lv3-multipass.glslp
  A base/xbr/xbr-lv3.glslp
  A base/xbr/xbr-mlv4-multipass.glslp


diff --git a/base/cubic/bicubic.glslp b/base/cubic/bicubic.glslp
new file mode 100644
index 0000000..7c949b0
--- /dev/null
+++ b/base/cubic/bicubic.glslp
@@ -0,0 +1,4 @@
+shaders = 1
+
+shader0 = shaders/bicubic.glsl
+filter_linear0 = false
\ No newline at end of file
diff --git a/base/cubic/catmull-rom.glslp b/base/cubic/catmull-rom.glslp
new file mode 100644
index 0000000..90fec2c
--- /dev/null
+++ b/base/cubic/catmull-rom.glslp
@@ -0,0 +1,3 @@
+shaders = 1
+shader0 = shaders/catmull-rom.glsl
+filter_linear0 = true 
diff --git a/base/cubic/cubic-gamma-correct.glslp b/base/cubic/cubic-gamma-correct.glslp
new file mode 100644
index 0000000..a9e2e17
--- /dev/null
+++ b/base/cubic/cubic-gamma-correct.glslp
@@ -0,0 +1,10 @@
+shaders = 2
+shader0 = shaders/linearize.glsl
+shader1 = shaders/cubic-gamma-correct.glsl
+
+filter_linear0 = false 
+scale_type0 = source
+scale0 = 1.0
+srgb_framebuffer0 = true
+
+filter_linear1 = false 
diff --git a/base/cubic/cubic.glslp b/base/cubic/cubic.glslp
new file mode 100644
index 0000000..552bf29
--- /dev/null
+++ b/base/cubic/cubic.glslp
@@ -0,0 +1,3 @@
+shaders = 1
+shader0 = shaders/cubic.glsl
+filter_linear0 = false 
diff --git a/base/cubic/shaders/bicubic.glsl b/base/cubic/shaders/bicubic.glsl
new file mode 100644
index 0000000..f1359d2
--- /dev/null
+++ b/base/cubic/shaders/bicubic.glsl
@@ -0,0 +1,188 @@
+/*
+   Copyright (C) 2010 Team XBMC
+   http://www.xbmc.org
+   Copyright (C) 2011 Stefanos A.
+   http://www.opentk.com
+
+This Program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This Program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with XBMC; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+http://www.gnu.org/copyleft/gpl.html
+*/
+
+// Default to Mitchel-Netravali coefficients for best psychovisual result
+// bicubic-sharp is B = 0.1 and C = 0.5
+// bicubic-sharper is B = 0.0 and C = 0.75
+#pragma parameter B "Bicubic Coeff B" 0.33 0.0 1.0 0.01
+#pragma parameter C "Bicubic Coeff C" 0.33 0.0 1.0 0.01
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 TEX0;
+
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+// compatibility #defines
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+void main()
+{
+   gl_Position = MVPMatrix * VertexCoord;
+   TEX0.xy = TexCoord.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out COMPAT_PRECISION vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+#ifdef PARAMETER_UNIFORM
+uniform COMPAT_PRECISION float B, C;
+#else
+#define B 0.3333
+#define C 0.3333
+#endif
+
+float weight(float x)
+{
+	float ax = abs(x);
+
+	if (ax < 1.0)
+	{
+		return
+			(
+			 pow(x, 2.0) * ((12.0 - 9.0 * B - 6.0 * C) * ax + (-18.0 + 12.0 * B + 6.0 * C)) +
+			 (6.0 - 2.0 * B)
+			) / 6.0;
+	}
+	else if ((ax >= 1.0) && (ax < 2.0))
+	{
+		return
+			(
+			 pow(x, 2.0) * ((-B - 6.0 * C) * ax + (6.0 * B + 30.0 * C)) +
+			 (-12.0 * B - 48.0 * C) * ax + (8.0 * B + 24.0 * C)
+			) / 6.0;
+	}
+	else
+	{
+		return 0.0;
+	}
+}
+	
+vec4 weight4(float x)
+{
+	return vec4(
+			weight(x - 2.0),
+			weight(x - 1.0),
+			weight(x),
+			weight(x + 1.0));
+}
+
+vec3 pixel(float xpos, float ypos, sampler2D tex)
+{
+	return COMPAT_TEXTURE(tex, vec2(xpos, ypos)).rgb;
+}
+
+vec3 line_run(float ypos, vec4 xpos, vec4 linetaps, sampler2D tex)
+{
+	return
+		pixel(xpos.r, ypos, tex) * linetaps.r +
+		pixel(xpos.g, ypos, tex) * linetaps.g +
+		pixel(xpos.b, ypos, tex) * linetaps.b +
+		pixel(xpos.a, ypos, tex) * linetaps.a;
+}
+
+void main()
+{
+        vec2 stepxy = vec2(1.0/SourceSize.x, 1.0/SourceSize.y);
+        vec2 pos = vTexCoord.xy + stepxy * 0.5;
+        vec2 f = fract(pos / stepxy);
+		
+	vec4 linetaps   = weight4(1.0 - f.x);
+	vec4 columntaps = weight4(1.0 - f.y);
+
+	//make sure all taps added together is exactly 1.0, otherwise some (very small) distortion can occur
+	linetaps /= linetaps.r + linetaps.g + linetaps.b + linetaps.a;
+	columntaps /= columntaps.r + columntaps.g + columntaps.b + columntaps.a;
+
+	vec2 xystart = (-1.5 - f) * stepxy + pos;
+	vec4 xpos = vec4(xystart.x, xystart.x + stepxy.x, xystart.x + stepxy.x * 2.0, xystart.x + stepxy.x * 3.0);
+
+
+// final sum and weight normalization
+   vec4 final = vec4(line_run(xystart.y                 , xpos, linetaps, Source) * columntaps.r +
+                      line_run(xystart.y + stepxy.y      , xpos, linetaps, Source) * columntaps.g +
+                      line_run(xystart.y + stepxy.y * 2.0, xpos, linetaps, Source) * columntaps.b +
+                      line_run(xystart.y + stepxy.y * 3.0, xpos, linetaps, Source) * columntaps.a,1);
+
+   FragColor = final;
+} 
+#endif
diff --git a/base/cubic/shaders/catmull-rom.glsl b/base/cubic/shaders/catmull-rom.glsl
new file mode 100644
index 0000000..55fb05d
--- /dev/null
+++ b/base/cubic/shaders/catmull-rom.glsl
@@ -0,0 +1,150 @@
+/*
+	Bicubic Catmull-Rom 9 taps (Fast) - ported by Hyllian - 2020
+	The following code is licensed under the MIT license: https://gist.github.com/TheRealMJP/bc503b0b87b643d3505d41eab8b332ae
+	Ported from code: https://gist.github.com/TheRealMJP/c83b8c0f46b63f3a88a5986f4fa982b1
+	Samples a texture with Catmull-Rom filtering, using 9 texture fetches instead of 16.
+	See http://vec3.ca/bicubic-filtering-in-fewer-taps/ for more details
+	ATENTION: This code only work using LINEAR filter sampling set on Retroarch!
+*/
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+precision COMPAT_PRECISION float;
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    COL0 = COLOR;
+    TEX0.xy = TexCoord.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out mediump vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define outsize vec4(OutputSize, 1.0 / OutputSize)
+
+#define mul(c,d) (d*c)
+
+void main()
+{
+    // We're going to sample a a 4x4 grid of texels surrounding the target UV coordinate. We'll do this by rounding
+    // down the sample location to get the exact center of our "starting" texel. The starting texel will be at
+    // location [1, 1] in the grid, where [0, 0] is the top left corner.
+    vec2 samplePos = vTexCoord * SourceSize.xy;
+    vec2 texPos1 = floor(samplePos - 0.5) + 0.5;
+
+    // Compute the fractional offset from our starting texel to our original sample location, which we'll
+    // feed into the Catmull-Rom spline function to get our filter weights.
+    vec2 f = samplePos - texPos1;
+
+    // Compute the Catmull-Rom weights using the fractional offset that we calculated earlier.
+    // These equations are pre-expanded based on our knowledge of where the texels will be located,
+    // which lets us avoid having to evaluate a piece-wise function.
+    vec2 w0 = f * (-0.5 + f * (1.0 - 0.5 * f));
+    vec2 w1 = 1.0 + f * f * (-2.5 + 1.5 * f);
+    vec2 w2 = f * (0.5 + f * (2.0 - 1.5 * f));
+    vec2 w3 = f * f * (-0.5 + 0.5 * f);
+ //   vec2 w3 = 1.0 - w0 - w1 - w2;
+
+    // Work out weighting factors and sampling offsets that will let us use bilinear filtering to
+    // simultaneously evaluate the middle 2 samples from the 4x4 grid.
+    vec2 w12 = w1 + w2;
+    vec2 offset12 = w2 / (w1 + w2);
+
+    // Compute the final UV coordinates we'll use for sampling the texture
+    vec2 texPos0  = texPos1 - 1.;
+    vec2 texPos3  = texPos1 + 2.;
+    vec2 texPos12 = texPos1 + offset12;
+
+    texPos0  *= SourceSize.zw;
+    texPos3  *= SourceSize.zw;
+    texPos12 *= SourceSize.zw;
+
+    vec4 c00  = COMPAT_TEXTURE(Source, vec2(texPos0.x, texPos0.y));
+    vec4 c10  = COMPAT_TEXTURE(Source, vec2(texPos12.x, texPos0.y));
+    vec4 c20  = COMPAT_TEXTURE(Source, vec2(texPos3.x, texPos0.y));
+
+    vec4 c01  = COMPAT_TEXTURE(Source, vec2(texPos0.x, texPos12.y));
+    vec4 c11  = COMPAT_TEXTURE(Source, vec2(texPos12.x, texPos12.y));
+    vec4 c21  = COMPAT_TEXTURE(Source, vec2(texPos3.x, texPos12.y));
+
+    vec4 c02  = COMPAT_TEXTURE(Source, vec2(texPos0.x, texPos3.y));
+    vec4 c12  = COMPAT_TEXTURE(Source, vec2(texPos12.x, texPos3.y));
+    vec4 c22  = COMPAT_TEXTURE(Source, vec2(texPos3.x, texPos3.y));
+
+    // initialize some variables
+    vec4 c1, c2, c3, wx, wy = vec4(0.,0.,0.,0.);
+    // junk vec4 used only to round out the non-square 3x4 matrices
+    vec4 dummy = vec4(0.,0.,0.,1.);
+
+    wx   = vec4(w0.x, w12.x, w3.x, 1.0);
+    wy   = vec4(w0.y, w12.y, w3.y, 1.0);
+
+    c1   = vec4(mul(wx, mat4(c00, c10, c20, dummy)));
+    c2   = vec4(mul(wx, mat4(c01, c11, c21, dummy)));
+    c3   = vec4(mul(wx, mat4(c02, c12, c22, dummy)));
+
+    FragColor = mul(wy, mat4(c1, c2, c3, dummy));
+}
+#endif
diff --git a/base/cubic/shaders/cubic-gamma-correct.glsl b/base/cubic/shaders/cubic-gamma-correct.glsl
new file mode 100644
index 0000000..5d8c2a1
--- /dev/null
+++ b/base/cubic/shaders/cubic-gamma-correct.glsl
@@ -0,0 +1,140 @@
+#version 130
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+precision COMPAT_PRECISION float;
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+
+vec4 _oPosition1; 
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    COL0 = COLOR;
+    TEX0.xy = TexCoord.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+// in variables go here as COMPAT_VARYING whatever
+
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define outsize vec4(OutputSize, 1.0 / OutputSize)
+
+void weights(out vec4 x, out vec4 y, vec2 t)
+{
+   vec2 t2 = t * t;
+   vec2 t3 = t2 * t;
+
+   vec4 xs = vec4(1.0, t.x, t2.x, t3.x);
+   vec4 ys = vec4(1.0, t.y, t2.y, t3.y);
+
+   const vec4 p0 = vec4(+0.0, -0.5, +1.0, -0.5);
+   const vec4 p1 = vec4(+1.0,  0.0, -2.5, +1.5);
+   const vec4 p2 = vec4(+0.0, +0.5, +2.0, -1.5);
+   const vec4 p3 = vec4(+0.0,  0.0, -0.5, +0.5);
+
+   x = vec4(dot(xs, p0), dot(xs, p1), dot(xs, p2), dot(xs, p3));
+   y = vec4(dot(ys, p0), dot(ys, p1), dot(ys, p2), dot(ys, p3));
+}
+
+void main()
+{
+   vec2 uv = vTexCoord * SourceSize.xy - 0.5;
+   vec2 texel = floor(uv);
+   vec2 tex = (texel + 0.5) * SourceSize.zw;
+   vec2 phase = uv - texel;
+
+#define TEX(x, y) textureLodOffset(Source, tex, 0.0, ivec2(x, y)).rgb
+
+   vec4 x;
+   vec4 y;
+   weights(x, y, phase);
+
+   vec3 color;
+   vec4 row = x * y.x;
+   color  = TEX(-1, -1) * row.x;
+   color += TEX(+0, -1) * row.y;
+   color += TEX(+1, -1) * row.z;
+   color += TEX(+2, -1) * row.w;
+
+   row = x * y.y;
+   color += TEX(-1, +0) * row.x;
+   color += TEX(+0, +0) * row.y;
+   color += TEX(+1, +0) * row.z;
+   color += TEX(+2, +0) * row.w;
+
+   row = x * y.z;
+   color += TEX(-1, +1) * row.x;
+   color += TEX(+0, +1) * row.y;
+   color += TEX(+1, +1) * row.z;
+   color += TEX(+2, +1) * row.w;
+
+   row = x * y.w;
+   color += TEX(-1, +2) * row.x;
+   color += TEX(+0, +2) * row.y;
+   color += TEX(+1, +2) * row.z;
+   color += TEX(+2, +2) * row.w;
+
+   color = sqrt(clamp(color, vec3(0.0), vec3(1.0)));
+   FragColor = vec4(color, 1.0);
+} 
+#endif
diff --git a/base/cubic/shaders/cubic.glsl b/base/cubic/shaders/cubic.glsl
new file mode 100644
index 0000000..d7b9095
--- /dev/null
+++ b/base/cubic/shaders/cubic.glsl
@@ -0,0 +1,137 @@
+#version 130
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+precision COMPAT_PRECISION float;
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    COL0 = COLOR;
+    TEX0.xy = TexCoord.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define outsize vec4(OutputSize, 1.0 / OutputSize)
+
+void weights(out vec4 x, out vec4 y, vec2 t)
+{
+   vec2 t2 = t * t;
+   vec2 t3 = t2 * t;
+
+   vec4 xs = vec4(1.0, t.x, t2.x, t3.x);
+   vec4 ys = vec4(1.0, t.y, t2.y, t3.y);
+
+   const vec4 p0 = vec4(+0.0, -0.5, +1.0, -0.5);
+   const vec4 p1 = vec4(+1.0,  0.0, -2.5, +1.5);
+   const vec4 p2 = vec4(+0.0, +0.5, +2.0, -1.5);
+   const vec4 p3 = vec4(+0.0,  0.0, -0.5, +0.5);
+
+   x = vec4(dot(xs, p0), dot(xs, p1), dot(xs, p2), dot(xs, p3));
+   y = vec4(dot(ys, p0), dot(ys, p1), dot(ys, p2), dot(ys, p3));
+}
+
+void main()
+{
+   vec2 uv = vTexCoord * SourceSize.xy - 0.5;
+   vec2 texel = floor(uv);
+   vec2 tex = (texel + 0.5) * SourceSize.zw;
+   vec2 phase = uv - texel;
+
+#define TEX(x, y) textureLodOffset(Source, tex, 0.0, ivec2(x, y)).rgb
+
+   vec4 x;
+   vec4 y;
+   weights(x, y, phase);
+
+   vec3 color;
+   vec4 row = x * y.x;
+   color  = TEX(-1, -1) * row.x;
+   color += TEX(+0, -1) * row.y;
+   color += TEX(+1, -1) * row.z;
+   color += TEX(+2, -1) * row.w;
+
+   row = x * y.y;
+   color += TEX(-1, +0) * row.x;
+   color += TEX(+0, +0) * row.y;
+   color += TEX(+1, +0) * row.z;
+   color += TEX(+2, +0) * row.w;
+
+   row = x * y.z;
+   color += TEX(-1, +1) * row.x;
+   color += TEX(+0, +1) * row.y;
+   color += TEX(+1, +1) * row.z;
+   color += TEX(+2, +1) * row.w;
+
+   row = x * y.w;
+   color += TEX(-1, +2) * row.x;
+   color += TEX(+0, +2) * row.y;
+   color += TEX(+1, +2) * row.z;
+   color += TEX(+2, +2) * row.w;
+
+   FragColor = vec4(color, 1.0);
+} 
+#endif
diff --git a/base/cubic/shaders/linearize.glsl b/base/cubic/shaders/linearize.glsl
new file mode 100644
index 0000000..a05abb4
--- /dev/null
+++ b/base/cubic/shaders/linearize.glsl
@@ -0,0 +1,87 @@
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+precision COMPAT_PRECISION float;
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    COL0 = COLOR;
+    TEX0.xy = TexCoord.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define outsize vec4(OutputSize, 1.0 / OutputSize)
+
+vec3 gamma(vec3 v)
+{
+   return v * v;
+}
+
+void main()
+{
+   FragColor = vec4(gamma(COMPAT_TEXTURE(Source, vTexCoord).rgb), 1.0);
+} 
+#endif
diff --git a/base/interpolation/aann.glslp b/base/interpolation/aann.glslp
new file mode 100644
index 0000000..b61c37e
--- /dev/null
+++ b/base/interpolation/aann.glslp
@@ -0,0 +1,4 @@
+shaders = 1
+
+shader0 = shaders/aann.glsl
+filter_linear0 = true
\ No newline at end of file
diff --git a/base/interpolation/bandlimit-pixel.glslp b/base/interpolation/bandlimit-pixel.glslp
new file mode 100644
index 0000000..e7307da
--- /dev/null
+++ b/base/interpolation/bandlimit-pixel.glslp
@@ -0,0 +1,10 @@
+shaders = 2
+shader0 = ../linear/linearize.glsl
+shader1 = shaders/bandlimit-pixel.glsl
+
+filter_linear0 = false 
+scale_type0 = source
+scale0 = 1.0
+srgb_framebuffer0 = true
+
+filter_linear1 = true
diff --git a/base/interpolation/controlled_sharpness.glslp b/base/interpolation/controlled_sharpness.glslp
new file mode 100644
index 0000000..2b979d5
--- /dev/null
+++ b/base/interpolation/controlled_sharpness.glslp
@@ -0,0 +1,4 @@
+shaders = 1
+
+shader0 = shaders/ControlledSharpness.glsl
+filter_linear0 = true
diff --git a/base/interpolation/pixellate.glslp b/base/interpolation/pixellate.glslp
new file mode 100644
index 0000000..ebff581
--- /dev/null
+++ b/base/interpolation/pixellate.glslp
@@ -0,0 +1,4 @@
+shaders = 1
+
+shader0 = shaders/pixellate.glsl
+filter_linear0 = false
\ No newline at end of file
diff --git a/base/interpolation/quilez.glslp b/base/interpolation/quilez.glslp
new file mode 100644
index 0000000..afcac1c
--- /dev/null
+++ b/base/interpolation/quilez.glslp
@@ -0,0 +1,4 @@
+shaders = 1
+
+shader0 = shaders/quilez.glsl
+filter_linear0 = true
\ No newline at end of file
diff --git a/base/interpolation/shaders/ControlledSharpness.glsl b/base/interpolation/shaders/ControlledSharpness.glsl
new file mode 100644
index 0000000..56e579e
--- /dev/null
+++ b/base/interpolation/shaders/ControlledSharpness.glsl
@@ -0,0 +1,113 @@
+#version 130
+
+//https://www.desmos.com/calculator/3zhzwbfrxd
+
+#pragma parameter sharpness "Sharpness" 0.4 0.001 0.95 0.05
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+
+vec4 _oPosition1; 
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+// compatibility #defines
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    TEX0.xy = TexCoord.xy * 1.00001;
+}
+
+#elif defined(FRAGMENT)
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out COMPAT_PRECISION vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+#ifdef PARAMETER_UNIFORM
+uniform COMPAT_PRECISION float sharpness;
+#else
+#define sharpness 0.4
+#endif
+
+vec2 f(vec2 x, float n) {
+    float c = 2.0 / (1.0-sharpness) - 1.0;
+    return pow(x,vec2(c)) / pow(n,c-1.0);
+}
+
+void main()
+{
+    vec2 SStep = vTexCoord * SourceSize.xy + 0.5;
+	vec2 SStepInt = floor(SStep);
+	vec2 SStepFra = SStep - SStepInt;
+
+
+    vec2 f0 = f(SStepFra,0.5);
+    vec2 f2 = 1-f(1-SStepFra,0.5);
+
+    SStep = ((mix(f0,f2,greaterThanEqual(SStepFra,vec2(0.5)))) + SStepInt - 0.5) * SourceSize.zw;
+
+    FragColor = COMPAT_TEXTURE(Source, SStep);
+} 
+#endif
diff --git a/base/interpolation/shaders/aann.glsl b/base/interpolation/shaders/aann.glsl
new file mode 100644
index 0000000..deb75ce
--- /dev/null
+++ b/base/interpolation/shaders/aann.glsl
@@ -0,0 +1,228 @@
+// AntiAliased Nearest Neighbor
+// by jimbo1qaz and wareya
+// Licensed MIT
+
+// Parameter lines go here:
+// set to true to interpolate in sRGB instead of a pseudo-perceptual colorspace
+#pragma parameter NOGAMMA "Interpolate in sRGB" 0.0 0.0 1.0 1.0
+
+// Do bilinear filtering instead of anti-aliased nearest neighbor filtering (used for debugging color)
+#pragma parameter BILINEAR "Force Bilinear Filtering" 0.0 0.0 1.0 1.0
+
+// http://i.imgur.com/kzwZkVf.png
+
+#define NOT(fl) (1.-fl)
+#define YES(fl) fl
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+// vertex compatibility #defines
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define outsize vec4(OutputSize, 1.0 / OutputSize)
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    COL0 = COLOR;
+    TEX0.xy = TexCoord.xy * TextureSize.xy / InputSize.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+
+// fragment compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define outsize vec4(OutputSize, 1.0 / OutputSize)
+
+#ifdef PARAMETER_UNIFORM
+uniform COMPAT_PRECISION float NOGAMMA;
+uniform COMPAT_PRECISION float BILINEAR;
+#else
+#define NOGAMMA 0.0
+#define BILINEAR 0.0
+#endif
+
+// http://entropymine.com/imageworsener/srgbformula/
+vec3 srgb2linear(vec3 srgb) {
+    return vec3(
+        srgb.r > 0.0404482362771082 ? pow(srgb.r*0.947867298578199 + 0.052132701421801, 2.4) : srgb.r*0.0773993808049536,
+        srgb.g > 0.0404482362771082 ? pow(srgb.g*0.947867298578199 + 0.052132701421801, 2.4) : srgb.g*0.0773993808049536,
+        srgb.b > 0.0404482362771082 ? pow(srgb.b*0.947867298578199 + 0.052132701421801, 2.4) : srgb.b*0.0773993808049536 
+    );
+}
+
+vec3 linear2srgb(vec3 linear) {
+    return vec3(
+        linear.x > 0.00313066844250063 ? pow(linear.x, 0.416666666666667)*1.055 - 0.055 : linear.x*12.92,
+        linear.y > 0.00313066844250063 ? pow(linear.y, 0.416666666666667)*1.055 - 0.055 : linear.y*12.92,
+        linear.z > 0.00313066844250063 ? pow(linear.z, 0.416666666666667)*1.055 - 0.055 : linear.z*12.92
+    );
+}
+
+// https://www.w3.org/Graphics/Color/srgb22
+#define RS 0.2126
+#define GS 0.7152
+#define BS 0.0722
+
+vec3 rgb2vry(vec3 rgb) {
+    if (NOGAMMA == 1.0)
+        return rgb;
+
+    // https://en.wikipedia.org/wiki/Opponent_process
+    vec3 linear = srgb2linear(rgb);
+
+    // https://en.wikipedia.org/wiki/Lightness#Relationship_between_lightness.2C_value.2C_and_relative_luminance
+    // "scientists eventually converged on a roughly cube-root curve"
+    // CIE does the same thing.
+    vec3 vry = vec3(
+        pow(linear.x*RS + linear.y*GS + linear.z*BS, 0.333333333333333),
+        linear.x - linear.y,
+        (linear.x + linear.y) * 0.49999 - linear.z
+    );
+
+    return vry;
+}
+vec3 vry2rgb(vec3 vry) {
+    if (NOGAMMA == 1.0)
+        return vry;
+
+    // Magic.
+    float t = pow(vry.x, 3.);
+    
+    vec3 rgb = vec3(
+        t + vry.y*(GS       + BS * 0.49999) + vry.z*BS,
+        t - vry.y*(RS       + BS * 0.49999) + vry.z*BS,
+        t + vry.y*(GS * 0.49999 - RS * 0.49999) - vry.z*(RS+GS)
+    );
+    
+    return linear2srgb(rgb);
+}
+
+vec3 vry_interp(vec3 first, vec3 second, float frac) {
+    if (NOGAMMA == 1.0)
+        return first*NOT(frac) + second*YES(frac);
+    
+    // Because the chroma values were generated on linear light, but the luma must be interpolated in perceptual gamma (3)
+    // it can cause out-of-gamut oversaturated values, since the chroma field is not a fixed size as luma values change.
+    // To compensate, we can "pull" the chroma interpolation path in the opposite way the luma path is curved.
+    float new_luma = first.x*NOT(frac) + second.x*YES(frac);
+    float linear_span = pow(second.x, 3.) - pow(first.x, 3.);
+    
+    if (linear_span == 0.) 
+        linear_span = 1.;
+
+    float luma_fraction = (pow(new_luma, 3.) - pow(first.x, 3.)) / linear_span;
+    
+    return  vec3(new_luma,
+                first.y*NOT(luma_fraction) + second.y*YES(luma_fraction),
+                first.z*NOT(luma_fraction) + second.z*YES(luma_fraction)
+            );
+}
+
+vec3 percent(float ssize, float tsize, float coord, float mod) {
+    if (BILINEAR == 1.0)
+        tsize = ssize;
+    
+    float minfull = (coord*tsize - 0.49999)/tsize*ssize * mod;
+    float maxfull = (coord*tsize + 0.49999)/tsize*ssize * mod;
+
+    float realfull = floor(maxfull) + 0.00001;
+
+    if (minfull > realfull) {
+        return vec3(1.00001, (realfull + 0.49999)/ssize, (realfull + 0.49999)/ssize);
+    }
+
+    return  vec3(
+                (maxfull - realfull) / (maxfull - minfull),
+                (realfull - 0.49999) / ssize,
+                (realfull + 0.49999) / ssize
+            );
+}
+
+void main()
+{
+    vec2 viewportSize = outsize.xy;
+    vec2 gameCoord = vTexCoord;
+
+    vec3 xstuff = percent(SourceSize.x, viewportSize.x, gameCoord.x,  InputSize.x / TextureSize.x);
+    vec3 ystuff = percent(SourceSize.y, viewportSize.y, gameCoord.y,  InputSize.y / TextureSize.y);
+
+    float xkeep = xstuff.x;
+    float ykeep = ystuff.x;
+
+    // get points to interpolate across in pseudo-perceptual colorspace
+    vec3 a = rgb2vry(COMPAT_TEXTURE(Source, vec2(xstuff.y, ystuff.y)).rgb);
+    vec3 b = rgb2vry(COMPAT_TEXTURE(Source, vec2(xstuff.z, ystuff.y)).rgb);
+    vec3 c = rgb2vry(COMPAT_TEXTURE(Source, vec2(xstuff.y, ystuff.z)).rgb);
+    vec3 d = rgb2vry(COMPAT_TEXTURE(Source, vec2(xstuff.z, ystuff.z)).rgb);
+
+    // interpolate
+    vec3 x1     = vry_interp(a,  b,  xkeep);
+    vec3 x2     = vry_interp(c,  d,  xkeep);
+    vec3 result = vry_interp(x1, x2, ykeep);
+
+    // convert back to sRGB and return
+    FragColor = vec4(vry2rgb(result), 1.);
+} 
+#endif
diff --git a/base/interpolation/shaders/bandlimit-pixel.glsl b/base/interpolation/shaders/bandlimit-pixel.glsl
new file mode 100644
index 0000000..57349b4
--- /dev/null
+++ b/base/interpolation/shaders/bandlimit-pixel.glsl
@@ -0,0 +1,235 @@
+#version 130
+
+/*
+ * Bandlimited pixel footprint shader.
+ * Author: Themaister
+ * License: MIT
+ * Adapted from: https://github.com/Themaister/Granite/blob/master/assets/shaders/inc/bandlimited_pixel_filter.h
+ */
+
+#pragma parameter SMOOTHNESS "Smoothness" 0.5 0.0 5.0 0.1
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION highp
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+
+vec4 _oPosition1; 
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+// compatibility #defines
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    TEX0.xy = TexCoord.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+precision highp int;
+#else
+precision mediump float;
+precision mediump int;
+#endif
+#define COMPAT_PRECISION highp
+#else
+#define COMPAT_PRECISION
+#endif
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out COMPAT_PRECISION vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+#ifdef PARAMETER_UNIFORM
+uniform COMPAT_PRECISION float SMOOTHNESS;
+#else
+#define SMOOTHNESS 0.5
+#endif
+
+// The cosine filter convolved with rect has a support of 0.5 + d pixels.
+// We can sample 4x4 regions, so we can deal with 2.0 pixel range in our filter,
+// and the maximum extent value we can have is 1.5.
+const float maximum_support_extent = 1.5;
+
+struct BandlimitedPixelInfo
+{
+	vec2 uv0;
+	vec2 uv1;
+	vec2 uv2;
+	vec2 uv3;
+	mediump vec4 weights;
+	mediump float l;
+};
+
+// Our Taylor approximation is not exact, normalize so the peak is 1.
+const float taylor_pi_half = 1.00452485553;
+const float taylor_normalization = 1.0 / taylor_pi_half;
+const float PI = 3.14159265359;
+const float PI_half = 0.5 * PI;
+
+#define gen_taylor(T) \
+mediump T taylor_sin(mediump T p) \
+{ \
+	mediump T p2 = p * p; \
+	mediump T p3 = p * p2; \
+	mediump T p5 = p2 * p3; \
+	return clamp(taylor_normalization * (p - p3 * (1.0 / 6.0) + p5 * (1.0 / 120.0)), -1.0, 1.0); \
+}
+// No templates in GLSL. Stamp out macros.
+gen_taylor(float)
+gen_taylor(vec2)
+gen_taylor(vec3)
+gen_taylor(vec4)
+
+// Given weights, compute a bilinear filter which implements the weight.
+// All weights are known to be non-negative, and separable.
+mediump vec3 compute_uv_phase_weight(mediump vec2 weights_u, mediump vec2 weights_v)
+{
+	// The sum of a bilinear sample has combined weight of 1, we will need to adjust the resulting sample
+	// to match our actual weight sum.
+	mediump float w = dot(weights_u.xyxy, weights_v.xxyy);
+	mediump float x = weights_u.y / max(weights_u.x + weights_u.y, 0.001);
+	mediump float y = weights_v.y / max(weights_v.x + weights_v.y, 0.001);
+	return vec3(x, y, w);
+}
+
+BandlimitedPixelInfo compute_pixel_weights(vec2 uv, vec2 size, vec2 inv_size)
+{
+	// Get derivatives in texel space.
+	// Need a non-zero derivative.
+	vec2 extent = max(fwidth(uv) * size * (SMOOTHNESS + 0.5), 1.0 / 256.0);
+
+	// Get base pixel and phase, range [0, 1).
+	vec2 pixel = uv * size - 0.5;
+	vec2 base_pixel = floor(pixel);
+	vec2 phase = pixel - base_pixel;
+
+	BandlimitedPixelInfo info;
+
+	mediump vec2 inv_extent = 1.0 / extent;
+	if (any(greaterThan(extent, vec2(maximum_support_extent))))
+	{
+		// We need to just do regular minimization filtering.
+		info = BandlimitedPixelInfo(vec2(0.0), vec2(0.0), vec2(0.0), vec2(0.0),
+		                            vec4(0.0, 0.0, 0.0, 0.0), 0.0);
+	}
+	else if (all(lessThanEqual(extent, vec2(0.5))))
+	{
+		// We can resolve the filter by just sampling a single 2x2 block.
+		mediump vec2 shift = 0.5 + 0.5 * taylor_sin(PI_half * clamp(inv_extent * (phase - 0.5), -1.0, 1.0));
+		info = BandlimitedPixelInfo((base_pixel + 0.5 + shift) * inv_size, vec2(0.0), vec2(0.0), vec2(0.0),
+		                            vec4(1.0, 0.0, 0.0, 0.0), 1.0);
+	}
+	else
+	{
+		// Full 4x4 sampling.
+
+		// Fade between bandlimited and normal sampling.
+		// Fully use bandlimited filter at LOD 0, normal filtering at approx. LOD -0.5.
+		mediump float max_extent = max(extent.x, extent.y);
+		mediump float l = clamp(1.0 - (max_extent - 1.0) / (maximum_support_extent - 1.0), 0.0, 1.0);
+
+		mediump vec4 sine_phases_x = PI_half * clamp(inv_extent.x * (phase.x + vec4(1.5, 0.5, -0.5, -1.5)), -1.0, 1.0);
+		mediump vec4 sines_x = taylor_sin(sine_phases_x);
+
+		mediump vec4 sine_phases_y = PI_half * clamp(inv_extent.y * (phase.y + vec4(1.5, 0.5, -0.5, -1.5)), -1.0, 1.0);
+		mediump vec4 sines_y = taylor_sin(sine_phases_y);
+
+		mediump vec2 sine_phases_end = PI_half * clamp(inv_extent * (phase - 2.5), -1.0, 1.0);
+		mediump vec2 sines_end = taylor_sin(sine_phases_end);
+
+		mediump vec4 weights_x = 0.5 * (sines_x - vec4(sines_x.yzw, sines_end.x));
+		mediump vec4 weights_y = 0.5 * (sines_y - vec4(sines_y.yzw, sines_end.y));
+
+		mediump vec3 w0 = compute_uv_phase_weight(weights_x.xy, weights_y.xy);
+		mediump vec3 w1 = compute_uv_phase_weight(weights_x.zw, weights_y.xy);
+		mediump vec3 w2 = compute_uv_phase_weight(weights_x.xy, weights_y.zw);
+		mediump vec3 w3 = compute_uv_phase_weight(weights_x.zw, weights_y.zw);
+
+		info = BandlimitedPixelInfo((base_pixel - 0.5 + w0.xy) * inv_size,
+									(base_pixel + vec2(1.5, -0.5) + w1.xy) * inv_size,
+									(base_pixel + vec2(-0.5, 1.5) + w2.xy) * inv_size,
+									(base_pixel + 1.5 + w3.xy) * inv_size,
+									vec4(w0.z, w1.z, w2.z, w3.z), l);
+	}
+
+	return info;
+}
+
+mediump vec4 sample_bandlimited_pixel(sampler2D samp, vec2 uv, BandlimitedPixelInfo info, float lod)
+{
+	mediump vec4 color = COMPAT_TEXTURE(samp, uv);
+	if (info.l > 0.0)
+	{
+		mediump vec4 bandlimited = info.weights.x * textureLod(samp, info.uv0, lod);
+		if (info.weights.x < 1.0)
+		{
+			bandlimited += info.weights.y * textureLod(samp, info.uv1, lod);
+			bandlimited += info.weights.z * textureLod(samp, info.uv2, lod);
+			bandlimited += info.weights.w * textureLod(samp, info.uv3, lod);
+		}
+		color = mix(color, bandlimited, info.l);
+	}
+	return color;
+}
+
+void main()
+{
+
+	BandlimitedPixelInfo info = compute_pixel_weights(vTexCoord, SourceSize.xy, SourceSize.zw);
+	mediump vec3 result = sample_bandlimited_pixel(Source, vTexCoord, info, 0.0).rgb;
+	FragColor = vec4(sqrt(clamp(result, 0.0, 1.0)), 1.0);
+} 
+#endif
diff --git a/base/interpolation/shaders/pixellate.glsl b/base/interpolation/shaders/pixellate.glsl
new file mode 100644
index 0000000..aa24846
--- /dev/null
+++ b/base/interpolation/shaders/pixellate.glsl
@@ -0,0 +1,143 @@
+//    Pixellate Shader
+//    Copyright (c) 2011, 2012 Fes
+//    Permission to use, copy, modify, and/or distribute this software for any
+//    purpose with or without fee is hereby granted, provided that the above
+//    copyright notice and this permission notice appear in all copies.
+//    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+//    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+//    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+//    SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+//   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+//    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+//    IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+//    (Fes gave their permission to have this shader distributed under this
+//    licence in this forum post:
+//        http://board.byuu.org/viewtopic.php?p=57295#p57295
+
+// Parameter lines go here:
+#pragma parameter INTERPOLATE_IN_LINEAR_GAMMA "Linear Gamma Weight" 1.0 0.0 1.0 1.0
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+// vertex compatibility #defines
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define outsize vec4(OutputSize, 1.0 / OutputSize)
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    COL0 = COLOR;
+    TEX0.xy = TexCoord.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION highp
+#else
+#define COMPAT_PRECISION
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+
+// fragment compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define outsize vec4(OutputSize, 1.0 / OutputSize)
+
+#ifdef PARAMETER_UNIFORM
+uniform COMPAT_PRECISION float INTERPOLATE_IN_LINEAR_GAMMA;
+#else
+#define INTERPOLATE_IN_LINEAR_GAMMA 1.0
+#endif
+
+void main()
+{
+   vec2 texelSize = SourceSize.zw;
+
+   vec2 range = vec2(abs(InputSize.x / (outsize.x * SourceSize.x)), abs(InputSize.y / (outsize.y * SourceSize.y)));
+   range = range / 2.0 * 0.999;
+
+   float left   = vTexCoord.x - range.x;
+   float top    = vTexCoord.y + range.y;
+   float right  = vTexCoord.x + range.x;
+   float bottom = vTexCoord.y - range.y;
+   
+   vec3 topLeftColor     = COMPAT_TEXTURE(Source, (floor(vec2(left, top)     / texelSize) + 0.5) * texelSize).rgb;
+   vec3 bottomRightColor = COMPAT_TEXTURE(Source, (floor(vec2(right, bottom) / texelSize) + 0.5) * texelSize).rgb;
+   vec3 bottomLeftColor  = COMPAT_TEXTURE(Source, (floor(vec2(left, bottom)  / texelSize) + 0.5) * texelSize).rgb;
+   vec3 topRightColor    = COMPAT_TEXTURE(Source, (floor(vec2(right, top)    / texelSize) + 0.5) * texelSize).rgb;
+
+   if (INTERPOLATE_IN_LINEAR_GAMMA > 0.5){
+	topLeftColor     = pow(topLeftColor, vec3(2.2));
+	bottomRightColor = pow(bottomRightColor, vec3(2.2));
+	bottomLeftColor  = pow(bottomLeftColor, vec3(2.2));
+	topRightColor    = pow(topRightColor, vec3(2.2));
+   }
+
+   vec2 border = clamp(floor((vTexCoord / texelSize) + vec2(0.5)) * texelSize, vec2(left, bottom), vec2(right, top));
+
+   float totalArea = 4.0 * range.x * range.y;
+
+   vec3 averageColor;
+   averageColor  = ((border.x - left)  * (top - border.y)    / totalArea) * topLeftColor;
+   averageColor += ((right - border.x) * (border.y - bottom) / totalArea) * bottomRightColor;
+   averageColor += ((border.x - left)  * (border.y - bottom) / totalArea) * bottomLeftColor;
+   averageColor += ((right - border.x) * (top - border.y)    / totalArea) * topRightColor;
+
+   FragColor = (INTERPOLATE_IN_LINEAR_GAMMA > 0.5) ? vec4(pow(averageColor, vec3(1.0 / 2.2)), 1.0) : vec4(averageColor, 1.0);
+} 
+#endif
diff --git a/base/interpolation/shaders/quilez.glsl b/base/interpolation/shaders/quilez.glsl
new file mode 100644
index 0000000..ec42de9
--- /dev/null
+++ b/base/interpolation/shaders/quilez.glsl
@@ -0,0 +1,103 @@
+/*
+	Fragment shader based on "Improved texture interpolation" by Iñigo Quílez
+	Original description: http://www.iquilezles.org/www/articles/texture/texture.htm
+*/
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+// vertex compatibility #defines
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define outsize vec4(OutputSize, 1.0 / OutputSize)
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    COL0 = COLOR;
+    TEX0.xy = TexCoord.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+
+// fragment compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define outsize vec4(OutputSize, 1.0 / OutputSize)
+
+void main()
+{
+	vec2 p = vTexCoord.xy;
+
+	p = p * SourceSize.xy + vec2(0.5, 0.5);
+
+	vec2 i = floor(p);
+	vec2 f = p - i;
+	f = f * f * f * (f * (f * 6.0 - vec2(15.0, 15.0)) + vec2(10.0, 10.0));
+	p = i + f;
+
+	p = (p - vec2(0.5, 0.5)) * SourceSize.zw;
+
+	// final sum and weight normalization
+   FragColor = vec4(COMPAT_TEXTURE(Source, p));
+} 
+#endif
diff --git a/base/interpolation/shaders/sharp-bilinear-scanlines.glsl b/base/interpolation/shaders/sharp-bilinear-scanlines.glsl
new file mode 100644
index 0000000..3293ab8
--- /dev/null
+++ b/base/interpolation/shaders/sharp-bilinear-scanlines.glsl
@@ -0,0 +1,150 @@
+/*
+   Author: rsn8887 (based on TheMaister)
+   License: Public domain
+
+   This is an integer prescale filter that should be combined
+   with a bilinear hardware filtering (GL_BILINEAR filter or some such) to achieve
+   a smooth scaling result with minimum blur. This is good for pixelgraphics
+   that are scaled by non-integer factors.
+   
+   The prescale factor and texel coordinates are precalculated
+   in the vertex shader for speed.
+*/
+
+// Parameter lines go here:
+#pragma parameter SCANLINE_BASE_BRIGHTNESS "Scanline Base Brightness" 0.60 0.0 1.0 0.01
+#pragma parameter SCANLINE_HORIZONTAL_MODULATION "Scanline Horizontal Modulation" 0.0 0.0 2.00 0.01
+#pragma parameter SCANLINE_VERTICAL_MODULATION "Scanline Vertical Modulation" 0.75 0.0 2.0 0.01
+
+#define pi 3.141592654
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+COMPAT_VARYING vec2 omega;
+
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+// vertex compatibility #defines
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define outsize vec4(OutputSize, 1.0 / OutputSize)
+
+COMPAT_VARYING vec2 precalc_texel;
+COMPAT_VARYING vec2 precalc_scale;
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    COL0 = COLOR;
+    TEX0.xy = TexCoord.xy;
+    omega = vec2(pi * OutputSize.x, 2.0 * pi * TextureSize.y);
+
+    precalc_texel = vTexCoord * SourceSize.xy;
+    precalc_scale = max(floor(outsize.xy / InputSize.xy), vec2(1.0, 1.0));
+}
+
+#elif defined(FRAGMENT)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+COMPAT_VARYING vec2 omega;
+
+// fragment compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define outsize vec4(OutputSize, 1.0 / OutputSize)
+
+#ifdef PARAMETER_UNIFORM
+// All parameter floats need to have COMPAT_PRECISION in front of them
+uniform COMPAT_PRECISION float SCANLINE_BASE_BRIGHTNESS;
+uniform COMPAT_PRECISION float SCANLINE_HORIZONTAL_MODULATION;
+uniform COMPAT_PRECISION float SCANLINE_VERTICAL_MODULATION;
+#else
+#define SCANLINE_BASE_BRIGHTNESS 0.60
+#define SCANLINE_HORIZONTAL_MODULATION 0.0
+#define SCANLINE_VERTICAL_MODULATION 0.75
+#endif
+
+COMPAT_VARYING vec2 precalc_texel;
+COMPAT_VARYING vec2 precalc_scale;
+
+void main()
+{
+   vec2 texel = precalc_texel;
+   vec2 scale = precalc_scale;
+
+   vec2 texel_floored = floor(texel);
+   vec2 s = fract(texel);
+   vec2 region_range = 0.5 - 0.5 / scale;
+
+   // Figure out where in the texel to sample to get correct pre-scaled bilinear.
+   // Uses the hardware bilinear interpolator to avoid having to sample 4 times manually.
+
+   vec2 center_dist = s - 0.5;
+   vec2 f = (center_dist - clamp(center_dist, -region_range, region_range)) * scale + 0.5;
+
+   vec2 mod_texel = texel_floored + f;
+
+   vec3 res = COMPAT_TEXTURE(Source, mod_texel / SourceSize.xy).xyz;
+
+   // thick scanlines (thickness pre-calculated in vertex shader based on source resolution)
+   vec2 sine_comp = vec2(SCANLINE_HORIZONTAL_MODULATION, SCANLINE_VERTICAL_MODULATION);
+
+   vec3 scanline = res * (SCANLINE_BASE_BRIGHTNESS + dot(sine_comp * sin(vTexCoord * omega), vec2(1.0, 1.0)));
+   FragColor = vec4(scanline.rgb, 1.0);
+} 
+#endif
diff --git a/base/interpolation/shaders/sharp-bilinear-simple.glsl b/base/interpolation/shaders/sharp-bilinear-simple.glsl
new file mode 100644
index 0000000..8da93fe
--- /dev/null
+++ b/base/interpolation/shaders/sharp-bilinear-simple.glsl
@@ -0,0 +1,123 @@
+/*
+   Author: rsn8887 (based on TheMaister)
+   License: Public domain
+
+   This is an integer prescale filter that should be combined
+   with a bilinear hardware filtering (GL_BILINEAR filter or some such) to achieve
+   a smooth scaling result with minimum blur. This is good for pixelgraphics
+   that are scaled by non-integer factors.
+   
+   The prescale factor and texel coordinates are precalculated
+   in the vertex shader for speed.
+*/
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+// vertex compatibility #defines
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define outsize vec4(OutputSize, 1.0 / OutputSize)
+
+COMPAT_VARYING vec2 precalc_texel;
+COMPAT_VARYING vec2 precalc_scale;
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    COL0 = COLOR;
+    TEX0.xy = TexCoord.xy;
+
+    precalc_texel = vTexCoord * SourceSize.xy;
+    precalc_scale = max(floor(outsize.xy / InputSize.xy), vec2(1.0, 1.0));
+}
+
+#elif defined(FRAGMENT)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+
+// fragment compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define outsize vec4(OutputSize, 1.0 / OutputSize)
+
+COMPAT_VARYING vec2 precalc_texel;
+COMPAT_VARYING vec2 precalc_scale;
+
+void main()
+{
+   vec2 texel = precalc_texel;
+   vec2 scale = precalc_scale;
+
+   vec2 texel_floored = floor(texel);
+   vec2 s = fract(texel);
+   vec2 region_range = 0.5 - 0.5 / scale;
+
+   // Figure out where in the texel to sample to get correct pre-scaled bilinear.
+   // Uses the hardware bilinear interpolator to avoid having to sample 4 times manually.
+
+   vec2 center_dist = s - 0.5;
+   vec2 f = (center_dist - clamp(center_dist, -region_range, region_range)) * scale + 0.5;
+
+   vec2 mod_texel = texel_floored + f;
+
+   FragColor = vec4(COMPAT_TEXTURE(Source, mod_texel / SourceSize.xy).rgb, 1.0);
+} 
+#endif
diff --git a/base/interpolation/shaders/sharp-bilinear.glsl b/base/interpolation/shaders/sharp-bilinear.glsl
new file mode 100644
index 0000000..dfb4b80
--- /dev/null
+++ b/base/interpolation/shaders/sharp-bilinear.glsl
@@ -0,0 +1,122 @@
+/*
+ * sharp-bilinear
+ * Author: Themaister
+ * License: Public domain
+ * 
+ * Does a bilinear stretch, with a preapplied Nx nearest-neighbor scale, giving a
+ * sharper image than plain bilinear.
+ */
+
+// Parameter lines go here:
+#pragma parameter SHARP_BILINEAR_PRE_SCALE "Sharp Bilinear Prescale" 4.0 1.0 10.0 1.0
+#pragma parameter AUTO_PRESCALE "Automatic Prescale" 1.0 0.0 1.0 1.0
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+// vertex compatibility #defines
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define outsize vec4(OutputSize, 1.0 / OutputSize)
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    COL0 = COLOR;
+    TEX0.xy = TexCoord.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+
+// fragment compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define outsize vec4(OutputSize, 1.0 / OutputSize)
+
+#ifdef PARAMETER_UNIFORM
+// All parameter floats need to have COMPAT_PRECISION in front of them
+uniform COMPAT_PRECISION float SHARP_BILINEAR_PRE_SCALE;
+uniform COMPAT_PRECISION float AUTO_PRESCALE;
+#else
+#define SHARP_BILINEAR_PRE_SCALE 4.0
+#define AUTO_PRESCALE 1.0
+#endif
+
+void main()
+{
+   vec2 texel = vTexCoord * SourceSize.xy;
+   vec2 texel_floored = floor(texel);
+   vec2 s = fract(texel);
+   float scale = (AUTO_PRESCALE > 0.5) ? floor(outsize.y / InputSize.y + 0.01) : SHARP_BILINEAR_PRE_SCALE;
+   float region_range = 0.5 - 0.5 / scale;
+
+   // Figure out where in the texel to sample to get correct pre-scaled bilinear.
+   // Uses the hardware bilinear interpolator to avoid having to sample 4 times manually.
+
+   vec2 center_dist = s - 0.5;
+   vec2 f = (center_dist - clamp(center_dist, -region_range, region_range)) * scale + 0.5;
+
+   vec2 mod_texel = texel_floored + f;
+
+   FragColor = vec4(COMPAT_TEXTURE(Source, mod_texel / SourceSize.xy).rgb, 1.0);
+} 
+#endif
diff --git a/base/interpolation/shaders/smootheststep.glsl b/base/interpolation/shaders/smootheststep.glsl
new file mode 100644
index 0000000..89907d4
--- /dev/null
+++ b/base/interpolation/shaders/smootheststep.glsl
@@ -0,0 +1,113 @@
+/*
+	Fragment shader based on "Improved texture interpolation" by Iñigo Quílez
+	Original description: http://www.iquilezles.org/www/articles/texture/texture.htm
+*/
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+// vertex compatibility #defines
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define outsize vec4(OutputSize, 1.0 / OutputSize)
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    COL0 = COLOR;
+    TEX0.xy = TexCoord.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+
+// fragment compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define outsize vec4(OutputSize, 1.0 / OutputSize)
+
+void main()
+{
+	vec2 p = vTexCoord.xy;
+
+	p = p * SourceSize.xy + vec2(0.5, 0.5);
+
+	vec2 i = floor(p);
+	vec2 f = p - i;
+
+	// Smoothstep - amazingly, smoothstep() is slower than calculating directly the expression!
+//	f = smoothstep(0.0, 1.0, f);
+//	f = f * f * ( -2.0 * f + 3.0);
+
+	// Quilez - This is sharper than smoothstep.
+	//f = f * f * f * (f * (f * 6.0 - vec2(15.0, 15.0)) + vec2(10.0, 10.0));
+
+	// smootheststep - This is even sharper than Quilez!
+	f = f * f * f * f * (f * (f * (-20.0 * f + vec2(70.0, 70.0)) - vec2(84.0, 84.0)) + vec2(35.0, 35.0));
+
+	p = i + f;
+
+	p = (p - vec2(0.5, 0.5)) * SourceSize.zw;
+
+	// final sum and weight normalization
+   FragColor = vec4(COMPAT_TEXTURE(Source, p).rgb, 1.0);
+} 
+#endif
diff --git a/base/interpolation/shaders/smuberstep.glsl b/base/interpolation/shaders/smuberstep.glsl
new file mode 100644
index 0000000..f12847c
--- /dev/null
+++ b/base/interpolation/shaders/smuberstep.glsl
@@ -0,0 +1,95 @@
+//SmuberStep - Like SmoothestStep but even Smoothester
+//by torridgristle
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+// vertex compatibility #defines
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define outsize vec4(OutputSize, 1.0 / OutputSize)
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    COL0 = COLOR;
+    TEX0.xy = TexCoord.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+
+// fragment compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define outsize vec4(OutputSize, 1.0 / OutputSize)
+
+void main()
+{
+    vec2 SStep = vTexCoord * SourceSize.xy + 0.5;
+	vec2 SStepInt = floor(SStep);
+	vec2 SStepFra = SStep - SStepInt;
+
+    SStep = ((924.*pow(SStepFra,vec2(13)) - 6006.*pow(SStepFra,vec2(12)) + 16380.*pow(SStepFra,vec2(11)) - 24024.*pow(SStepFra,vec2(10)) + 20020.*pow(SStepFra,vec2(9)) - 9009.*pow(SStepFra,vec2(8)) + 1716.*pow(SStepFra,vec2(7))) + SStepInt - 0.5) * SourceSize.zw;
+
+    FragColor = COMPAT_TEXTURE(Source, SStep);
+} 
+#endif
diff --git a/base/interpolation/sharp-bilinear-2x-prescale.glslp b/base/interpolation/sharp-bilinear-2x-prescale.glslp
new file mode 100644
index 0000000..36008a1
--- /dev/null
+++ b/base/interpolation/sharp-bilinear-2x-prescale.glslp
@@ -0,0 +1,7 @@
+shaders = 2
+shader0 = ../stock.glsl
+filter_linear0 = false
+scale_type0 = source
+scale0 = 2.0
+shader1 = ../stock.glsl
+filter_linear1 = true
\ No newline at end of file
diff --git a/base/interpolation/sharp-bilinear-scanlines.glslp b/base/interpolation/sharp-bilinear-scanlines.glslp
new file mode 100644
index 0000000..a71347b
--- /dev/null
+++ b/base/interpolation/sharp-bilinear-scanlines.glslp
@@ -0,0 +1,4 @@
+shaders = 1
+
+shader0 = shaders/sharp-bilinear-scanlines.glsl
+filter_linear0 = true
diff --git a/base/interpolation/sharp-bilinear-simple.glslp b/base/interpolation/sharp-bilinear-simple.glslp
new file mode 100644
index 0000000..37be32e
--- /dev/null
+++ b/base/interpolation/sharp-bilinear-simple.glslp
@@ -0,0 +1,4 @@
+shaders = 1
+
+shader0 = shaders/sharp-bilinear-simple.glsl
+filter_linear0 = true
\ No newline at end of file
diff --git a/base/interpolation/sharp-bilinear.glslp b/base/interpolation/sharp-bilinear.glslp
new file mode 100644
index 0000000..615a699
--- /dev/null
+++ b/base/interpolation/sharp-bilinear.glslp
@@ -0,0 +1,4 @@
+shaders = 1
+
+shader0 = shaders/sharp-bilinear.glsl
+filter_linear0 = true
\ No newline at end of file
diff --git a/base/interpolation/smootheststep.glslp b/base/interpolation/smootheststep.glslp
new file mode 100644
index 0000000..ff83567
--- /dev/null
+++ b/base/interpolation/smootheststep.glslp
@@ -0,0 +1,4 @@
+shaders = 1
+
+shader0 = shaders/smootheststep.glsl
+filter_linear0 = true
\ No newline at end of file
diff --git a/base/interpolation/smuberstep.glslp b/base/interpolation/smuberstep.glslp
new file mode 100644
index 0000000..298854a
--- /dev/null
+++ b/base/interpolation/smuberstep.glslp
@@ -0,0 +1,4 @@
+shaders = 1
+
+shader0 = shaders/smuberstep.glsl
+filter_linear0 = true
diff --git a/base/linear/linearize.glsl b/base/linear/linearize.glsl
new file mode 100644
index 0000000..c87ec0c
--- /dev/null
+++ b/base/linear/linearize.glsl
@@ -0,0 +1,91 @@
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+
+vec4 _oPosition1; 
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+// compatibility #defines
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    TEX0.xy = TexCoord.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out COMPAT_PRECISION vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+vec3 gamma(vec3 v)
+{
+   return v * v;
+}
+
+void main()
+{
+   FragColor = vec4(gamma(COMPAT_TEXTURE(Source, vTexCoord).rgb), 1.0);
+}
+#endif
diff --git a/base/misc/anti-flicker.glsl b/base/misc/anti-flicker.glsl
new file mode 100644
index 0000000..3b897f8
--- /dev/null
+++ b/base/misc/anti-flicker.glsl
@@ -0,0 +1,130 @@
+/*
+	Anti-Flicker shader
+	by hunterk
+	License: public domain
+	
+	This shader detects large variations in luminance from frame to frame
+	and then blends frames to smooth the transition. In flicker-based
+	shadow effects, this should result in true transparency.
+*/
+
+#pragma parameter lum_diff_thresh "Flicker Luma Diff. Threshold" 0.5 0.0 1.0 0.05
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 TEX0;
+
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+// compatibility #defines
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+void main()
+{
+   gl_Position = MVPMatrix * VertexCoord;
+   TEX0.xy = TexCoord.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out COMPAT_PRECISION vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+uniform sampler2D PrevTexture;
+uniform sampler2D Prev1Texture;
+COMPAT_VARYING vec4 TEX0;
+
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+#ifdef PARAMETER_UNIFORM
+uniform COMPAT_PRECISION float lum_diff_thresh;
+#else
+#define lum_diff_thresh 0.5
+#endif
+
+vec3 RGBtoYIQ(vec3 RGB)
+  {
+     const mat3 m = mat3(
+     0.2989, 0.5870, 0.1140,
+     0.5959, -0.2744, -0.3216,
+     0.2115, -0.5229, 0.3114);
+     return RGB * m;
+  }
+
+vec3 YIQtoRGB(vec3 YIQ)
+  {
+     const mat3 m = mat3(
+     1.0, 0.956, 0.6210,
+     1.0, -0.2720, -0.6474,
+     1.0, -1.1060, 1.7046);
+   return YIQ * m;
+  }
+
+void main()
+{
+    vec3 curr = RGBtoYIQ(COMPAT_TEXTURE(Source, vTexCoord).rgb);
+    vec3 prev0 = RGBtoYIQ(COMPAT_TEXTURE(PrevTexture, vTexCoord).rgb);
+    vec3 prev1 = RGBtoYIQ(COMPAT_TEXTURE(Prev1Texture, vTexCoord).rgb);
+
+    if((abs(curr.r - prev0.r) > lum_diff_thresh) && (abs(curr.r - prev1.r) < 1.0 - lum_diff_thresh))
+      FragColor.rgb = (prev0 + curr) / 2.;
+    else
+      FragColor.rgb = curr;
+    FragColor.rgb = YIQtoRGB(FragColor.rgb);
+    FragColor.a = 1.0;
+} 
+#endif
diff --git a/base/misc/bob-and-ghost-deinterlacing.glsl b/base/misc/bob-and-ghost-deinterlacing.glsl
new file mode 100644
index 0000000..e609c6a
--- /dev/null
+++ b/base/misc/bob-and-ghost-deinterlacing.glsl
@@ -0,0 +1,121 @@
+/*
+   Bob-and-ghost Deinterlacing
+   Author: hunterk
+   License: Public domain
+   
+   Note: This shader is designed to work with the typical interlaced output from an emulator, which displays both even and odd fields twice.
+   As such, it is inappropriate for general video use unless the video has already been similarly woven beforehand.
+*/
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+
+vec4 _oPosition1; 
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+// compatibility #defines
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    TEX0.xy = TexCoord.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out COMPAT_PRECISION vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+#define one_pixel vec2(1.0 / TextureSize)
+
+vec4 bob_and_ghost(vec2 texture_size, vec2 video_size, float frame_count, vec2 texCoord, sampler2D tex)
+{
+	vec4 res = vec4(pow(COMPAT_TEXTURE(tex, texCoord), vec4(2.2)));
+	vec4 color = vec4(0.,0.,0.,0.);
+	float y = 0.0;
+
+	// assume anything with a vertical resolution greater than 400 lines is interlaced
+	if (video_size.y > 400.0) 
+	{
+		y = texture_size.y * texCoord.y + frame_count;
+		res = pow(vec4(COMPAT_TEXTURE(tex, texCoord + vec2(0.0, one_pixel.y))), vec4(2.2));
+		color = pow((vec4(COMPAT_TEXTURE(tex, texCoord - vec2(0.0, 0.5 * one_pixel.y))) + vec4(COMPAT_TEXTURE(tex, texCoord + vec2(0.0, 0.5 * one_pixel.y)))) / 2.0, vec4(2.2));
+	}
+	else
+	{
+		y = 2.000001 * texture_size.y * texCoord.y;
+		color = res;
+	}
+
+	if (mod(y, 2.0) > 0.99999) res = res;
+	else res = vec4(pow(COMPAT_TEXTURE(tex, texCoord), vec4(2.2)));
+	return vec4(pow((res + color) / vec4(2.,2.,2.,2.), vec4(1.0 / 2.2, 1.0 / 2.2, 1.0 / 2.2, 1.0 / 2.2)));
+}
+
+void main()
+{
+    FragColor = bob_and_ghost(TextureSize, InputSize, float(FrameCount), TEX0.xy, Texture);
+} 
+#endif
diff --git a/base/misc/bob-deinterlacing.glsl b/base/misc/bob-deinterlacing.glsl
new file mode 100644
index 0000000..7348a83
--- /dev/null
+++ b/base/misc/bob-deinterlacing.glsl
@@ -0,0 +1,112 @@
+/*
+   Bob-Deinterlacing
+   Author: hunterk
+   License: Public domain
+   
+   Note: This shader is designed to work with the typical interlaced output from an emulator, which displays both even and odd fields twice.
+   As such, it is inappropriate for general video use unless the video has already been similarly woven beforehand.
+*/
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+
+vec4 _oPosition1; 
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+// compatibility #defines
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    TEX0.xy = TexCoord.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out COMPAT_PRECISION vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+#define one_pixel vec2(1.0 / TextureSize)
+
+vec4 bob(vec2 texture_size, vec2 video_size, float frame_count, vec2 texCoord, sampler2D tex)
+{
+   vec4 res = COMPAT_TEXTURE(tex, texCoord);
+   float y = 0.0;
+
+   // assume anything with a vertical resolution greater than 400 lines is interlaced
+   if (video_size.y > 400.0) y = texture_size.y * texCoord.y + frame_count;
+   else
+      y = 2.000001 * texture_size.y * texCoord.y;
+
+   if (mod(y, 2.0) > 0.99999) return vec4(COMPAT_TEXTURE(tex, texCoord + vec2(0.0, one_pixel.y)));
+   else
+return res;
+}
+
+void main()
+{
+    FragColor = bob(TextureSize, InputSize, float(FrameCount), TEX0.xy, Texture);
+} 
+#endif
diff --git a/base/misc/cmyk-halftone-dot.glsl b/base/misc/cmyk-halftone-dot.glsl
new file mode 100644
index 0000000..2171c8e
--- /dev/null
+++ b/base/misc/cmyk-halftone-dot.glsl
@@ -0,0 +1,146 @@
+/*
+CMYK Halftone Dot Shader
+
+Adapted from Stefan Gustavson's GLSL shader demo for WebGL:
+http://webstaff.itn.liu.se/~stegu/OpenGLinsights/shadertutorial.html
+
+Ported to RetroArch by hunterk
+
+This shader is licensed in the public domain, as per S. Gustavson's original license.
+Note: the MIT-licensed noise functions have been purposely removed.
+*/
+
+#pragma parameter frequency "CMYK HalfTone Dot Density" 225.0 25.0 700.0 25.0
+#define mul(a,b) (b*a)
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+
+vec4 _oPosition1; 
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+// compatibility #defines
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    TEX0.xy = TexCoord.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+#ifdef PARAMETER_UNIFORM
+uniform float frequency;
+#else
+#define frequency 550.0 // controls the density of the dot pattern
+#endif
+
+void main()
+{
+	// Distance to nearest point in a grid of
+	// (frequency x frequency) points over the unit square
+	mat2 rotation_matrix = mat2(0.707, 0.707, -0.707, 0.707);
+	vec2 st2 = mul(rotation_matrix , vTexCoord);
+	vec2 nearest = 2.0 * fract(frequency * st2) - 1.0;
+	float dist = length(nearest);
+	vec3 texcolor = COMPAT_TEXTURE(Source, vTexCoord).rgb; // Unrotated coords
+	vec3 black = texcolor; // kinda cheating, but it makes the colors look much better
+
+	// Perform a rough RGB-to-CMYK conversion
+	vec4 cmyk;
+	cmyk.xyz = 1.0 - texcolor;
+	cmyk.w = min(cmyk.x, min(cmyk.y, cmyk.z)); // Create K
+
+	mat2 k_matrix = mat2(0.707, 0.707, -0.707, 0.707);
+	vec2 Kst = frequency * (TextureSize / InputSize) * mul(k_matrix , vTexCoord);
+	vec2 Kuv = 2.0 * fract(Kst) - 1.0;
+	float k = step(0.0, sqrt(cmyk.w) - length(Kuv));
+	mat2 c_matrix = mat2(0.966, 0.259, -0.259, 0.966);
+	vec2 Cst = frequency * (TextureSize / InputSize) * mul(c_matrix , vTexCoord);
+	vec2 Cuv = 2.0 * fract(Cst) - 1.0;
+	float c = step(0.0, sqrt(cmyk.x) - length(Cuv));
+	mat2 m_matrix = mat2(0.966, -0.259, 0.259, 0.966);
+	vec2 Mst = frequency * (TextureSize / InputSize) * mul(m_matrix , vTexCoord);
+	vec2 Muv = 2.0 * fract(Mst) - 1.0;
+	float m = step(0.0, sqrt(cmyk.y) - length(Muv));
+	vec2 Yst = frequency * (TextureSize / InputSize) * vTexCoord; // 0 deg
+	vec2 Yuv = 2.0 * fract(Yst) - 1.0;
+	float y = step(0.0, sqrt(cmyk.z) - length(Yuv));
+
+	vec3 rgbscreen = 1.0 - vec3(c,m,y);
+	rgbscreen = mix(rgbscreen, black, k);
+
+	float afwidth = 2.0 * frequency * length(OutSize.zw);
+	float blend = smoothstep(0.0, 1.0, afwidth);
+	
+	vec4 color = vec4(mix(rgbscreen , texcolor, blend), 1.0);
+	color = (max(texcolor.r, max(texcolor.g, texcolor.b)) < 0.01) ? vec4(0.,0.,0.,0.) : color; // make blacks actually black
+
+	FragColor = color;
+} 
+#endif
diff --git a/base/misc/cocktail-cab-portrait.glsl b/base/misc/cocktail-cab-portrait.glsl
new file mode 100644
index 0000000..f2f0d4c
--- /dev/null
+++ b/base/misc/cocktail-cab-portrait.glsl
@@ -0,0 +1,116 @@
+// Cocktail Table Portrait
+// by hunterk
+// license: public domain
+
+#pragma parameter width "Cocktail Width" 1.0 0.0 2.0 0.01
+#pragma parameter height "Cocktail Height" 0.49 0.0 2.0 0.01
+#pragma parameter x_loc "Cocktail X Mod" 0.0 -2.0 2.0 0.01
+#pragma parameter y_loc "Cocktail Y Mod" 0.51 -2.0 2.0 0.01
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+COMPAT_VARYING vec2 t1;
+
+vec4 _oPosition1; 
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+// compatibility #defines
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+#ifdef PARAMETER_UNIFORM
+uniform COMPAT_PRECISION float width, height, x_loc, y_loc;
+#else
+#define width 1.0
+#define height 0.49
+#define x_loc 0.0
+#define y_loc 0.51
+#endif
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    TEX0.xy = TexCoord.xy;
+	TEX0.xy = TEX0.xy - 0.5 * InputSize / TextureSize;
+	TEX0.xy = TEX0.xy * vec2(1. / width, 1. / height);
+	TEX0.xy = TEX0.xy + 0.5 * InputSize / TextureSize;
+	t1.xy = 1.* InputSize / TextureSize - TEX0.xy;
+	TEX0.xy -= vec2(x_loc, y_loc) * InputSize / TextureSize;
+	t1.xy -= vec2(x_loc, y_loc) * InputSize / TextureSize;
+}
+
+#elif defined(FRAGMENT)
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out COMPAT_PRECISION vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+COMPAT_VARYING vec2 t1;
+
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+void main()
+{
+	vec4 screen1 = COMPAT_TEXTURE(Source, vTexCoord);
+	screen1 *= float(vTexCoord.x > 0.0001) * float(vTexCoord.y > 0.0001) * float(vTexCoord.x < 0.9999) * float(vTexCoord.y < 0.9999);
+	vec4 screen2 = COMPAT_TEXTURE(Source, t1);
+	screen2 *= float(t1.x > 0.0001) * float(t1.y > 0.0001) * float(t1.x < 0.9999) * float(t1.y < 0.9999);
+	FragColor = screen1 + screen2;
+} 
+#endif
diff --git a/base/misc/cocktail-cabinet.glsl b/base/misc/cocktail-cabinet.glsl
new file mode 100644
index 0000000..8235512
--- /dev/null
+++ b/base/misc/cocktail-cabinet.glsl
@@ -0,0 +1,170 @@
+#pragma parameter height "Image Height" -1.145 -6.0 6.0 0.01
+#pragma parameter width "Image Width" 2.0 0.0 10.0 0.05
+#pragma parameter location_y "Image Location Y" 0.75 -4.0 4.0 0.005
+#pragma parameter location_x "Image Location X" -0.5 -4.0 4.0 0.005
+#pragma parameter ZOOM "Image Zoom" 1.0 0.0 2.0 0.005
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying
+#define COMPAT_ATTRIBUTE attribute
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+COMPAT_VARYING     vec4 _color1;
+COMPAT_VARYING     float _frame_rotation;
+struct input_dummy {
+    vec2 _video_size;
+    vec2 _texture_size;
+    vec2 _output_dummy_size;
+    float _frame_count;
+    float _frame_direction;
+    float _frame_rotation;
+};
+struct output_dummy {
+    vec4 _color1;
+};
+vec4 _oPosition1;
+vec4 _r0020;
+vec4 _r0022;
+vec2 _r0024;
+vec2 _r0026;
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+COMPAT_VARYING vec4 TEX1;
+ 
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+#ifdef PARAMETER_UNIFORM
+uniform COMPAT_PRECISION float height;
+uniform COMPAT_PRECISION float width;
+uniform COMPAT_PRECISION float location_y;
+uniform COMPAT_PRECISION float location_x;
+uniform COMPAT_PRECISION float ZOOM;
+#else
+#define height -1.145
+#define width 2.0
+#define location_y 0.75
+#define location_x -0.5
+#define ZOOM 1.0
+#endif
+
+void main()
+{
+    vec4 _oColor;
+    vec2 _otexCoord1;
+    vec2 _otexCoord2;
+    _r0020 = VertexCoord.x*MVPMatrix[0];
+    _r0020 = _r0020 + VertexCoord.y*MVPMatrix[1];
+    _r0020 = _r0020 + VertexCoord.z*MVPMatrix[2];
+    _r0020 = _r0020 + VertexCoord.w*MVPMatrix[3];
+    _r0022 = _r0020.x*vec4( height, 0.00000000E+00, 0.00000000E+00, 0.00000000E+00);
+    _r0022 = _r0022 + _r0020.y*vec4( 0.00000000E+00, width, 0.00000000E+00, 0.00000000E+00);
+    _r0022 = _r0022 + _r0020.z*vec4( 0.00000000E+00, 0.00000000E+00, 1.00000000E+00, 0.00000000E+00);
+    _r0022 = _r0022 + _r0020.w*vec4( 0.00000000E+00, 0.00000000E+00, 0.00000000E+00, 1.00000000E+00);
+    _oPosition1 = _r0022;
+    _oColor = COLOR;
+    _r0024 = VertexCoord.x*vec2( 0.00000000E+00, 1.00000000E+00);
+    _r0024 = _r0024 + VertexCoord.y*vec2( -1.00000000E+00, 0.00000000E+00);
+    _otexCoord1 = _r0024 + vec2( location_y, location_x);
+    _r0026 = VertexCoord.x*vec2( 0.00000000E+00, 1.00000000E+00);
+    _r0026 = _r0026 + VertexCoord.y*vec2( -1.00000000E+00, 0.00000000E+00);
+    _otexCoord2 = -(_r0026 + vec2( 1.0 - location_y, -1.0 - location_x));
+    gl_Position = _r0022;
+    COL0 = COLOR;
+    TEX0.xy = _otexCoord1;
+    TEX1.xy = _otexCoord2;
+}
+
+#elif defined(FRAGMENT)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+COMPAT_VARYING     vec4 _color1;
+COMPAT_VARYING     float _frame_rotation;
+struct input_dummy {
+    vec2 _video_size;
+    vec2 _texture_size;
+    vec2 _output_dummy_size;
+    float _frame_count;
+    float _frame_direction;
+    float _frame_rotation;
+};
+struct output_dummy {
+    vec4 _color1;
+};
+vec4 _TMP1;
+vec4 _TMP0;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+COMPAT_VARYING vec4 TEX1;
+ 
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+#ifdef PARAMETER_UNIFORM
+uniform COMPAT_PRECISION float height;
+uniform COMPAT_PRECISION float width;
+uniform COMPAT_PRECISION float location_y;
+uniform COMPAT_PRECISION float location_x;
+uniform COMPAT_PRECISION float ZOOM;
+#endif
+
+void main()
+{
+    vec4 _color;
+
+//fix for clamping issues on GLES
+vec2 fragCoord1 = TEX0.xy * InputSize / TextureSize;
+vec2 fragCoord2 = TEX1.xy* InputSize / TextureSize;
+
+_TMP0 = vec4(0.0);
+if ( fragCoord1.x < 1.0 && fragCoord1.x > 0.0 && fragCoord1.y < 1.0 && fragCoord1.y > 0.0 )
+_TMP0 = COMPAT_TEXTURE(Texture, TEX0.xy / ZOOM);
+_TMP1 = vec4(0.0);
+if ( fragCoord2.x < 1.0 && fragCoord2.x > 0.0 && fragCoord2.y < 1.0 && fragCoord2.y > 0.0 )
+_TMP1 = COMPAT_TEXTURE(Texture, TEX1.xy / ZOOM);
+
+    _color = _TMP0 + _TMP1;
+    FragColor = _color;
+    return;
+} 
+#endif
diff --git a/base/misc/color-mangler.glsl b/base/misc/color-mangler.glsl
new file mode 100644
index 0000000..0d693a7
--- /dev/null
+++ b/base/misc/color-mangler.glsl
@@ -0,0 +1,151 @@
+/*
+   Color Mangler
+   Author: hunterk
+   License: Public domain
+*/
+
+#pragma parameter gamma_boost_r "Gamma Mod Red Channel" 0.0 -5.0 5.0 0.1
+#pragma parameter gamma_boost_g "Gamma Mod Green Channel" 0.0 -5.0 5.0 0.1
+#pragma parameter gamma_boost_b "Gamma Mod Blue Channel" 0.0 -5.0 5.0 0.1
+#pragma parameter sat "Saturation" 1.0 0.0 3.0 0.01
+#pragma parameter lum "Luminance" 1.0 0.0 5.0 0.01
+#pragma parameter cntrst "Contrast" 1.0 0.0 2.0 0.01
+#pragma parameter r "Red" 1.0 0.0 2.0 0.01
+#pragma parameter g "Green" 1.0 0.0 2.0 0.01
+#pragma parameter b "Blue" 1.0 0.0 2.0 0.01
+#pragma parameter rg "Red-Green Tint" 0.0 0.0 1.0 0.005
+#pragma parameter rb "Red-Blue Tint" 0.0 0.0 1.0 0.005
+#pragma parameter gr "Green-Red Tint" 0.0 0.0 1.0 0.005
+#pragma parameter gb "Green-Blue Tint" 0.0 0.0 1.0 0.005
+#pragma parameter br "Blue-Red Tint" 0.0 0.0 1.0 0.005
+#pragma parameter bg "Blue-Green Tint" 0.0 0.0 1.0 0.005
+#pragma parameter blr "Black-Red Tint" 0.0 0.0 1.0 0.005
+#pragma parameter blg "Black-Green Tint" 0.0 0.0 1.0 0.005
+#pragma parameter blb "Black-Blue Tint" 0.0 0.0 1.0 0.005
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+// compatibility #defines
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+void main()
+{
+   gl_Position = MVPMatrix * VertexCoord;
+   TEX0.xy = TexCoord.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out COMPAT_PRECISION vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+#ifdef PARAMETER_UNIFORM
+uniform COMPAT_PRECISION float gamma_boost_r, gamma_boost_g, gamma_boost_b, sat, lum, cntrst, blr, blg, blb, r, g, b, rg, rb, gr, gb, br, bg;
+#else
+#define gamma_boost_r 0.0
+#define gamma_boost_g 0.0
+#define gamma_boost_b 0.0
+#define sat 1.0
+#define lum 1.0
+#define cntrst 1.0
+#define blr 0.0
+#define blg 0.0
+#define blb 0.0
+#define r 1.0
+#define g 1.0
+#define b 1.0
+#define rg 0.0
+#define rb 0.0
+#define gr 0.0
+#define gb 0.0
+#define br 0.0
+#define bg 0.0
+#endif
+
+void main()
+{
+   vec4 screen = pow(COMPAT_TEXTURE(Source, vTexCoord), vec4(2.2)).rgba;
+   vec4 avglum = vec4(0.5);
+   screen = mix(screen, avglum, (1.0 - cntrst));
+
+                   //  r    g    b  alpha ; alpha does nothing for our purposes
+   mat4 color = mat4(  r,  rg,  rb, 0.0,  //red tint
+                      gr,   g,  gb, 0.0,  //green tint
+                      br,  bg,   b, 0.0,  //blue tint
+                     blr, blg, blb, 0.0); //black tint
+
+   mat4 adjust = mat4((1.0 - sat) * 0.2126 + sat, (1.0 - sat) * 0.2126, (1.0 - sat) * 0.2126, 1.0,
+                      (1.0 - sat) * 0.7152, (1.0 - sat) * 0.7152 + sat, (1.0 - sat) * 0.7152, 1.0,
+                      (1.0 - sat) * 0.0722, (1.0 - sat) * 0.0722, (1.0 - sat) * 0.0722 + sat, 1.0,
+                      0.0, 0.0, 0.0, 1.0);
+   color *= adjust;
+   screen = clamp(screen * lum, 0.0, 1.0);
+   screen = color * screen;
+	vec3 out_gamma = vec3(1.) / (vec3(2.2) - vec3(gamma_boost_r, gamma_boost_g, gamma_boost_b));
+	FragColor = pow(screen, vec4(out_gamma, 1.0));
+}
+#endif
\ No newline at end of file
diff --git a/base/misc/colorimetry.glsl b/base/misc/colorimetry.glsl
new file mode 100644
index 0000000..72271ef
--- /dev/null
+++ b/base/misc/colorimetry.glsl
@@ -0,0 +1,308 @@
+#version 130
+
+/*
+   Colorimetry shader
+   Ported from Drag's NES Palette Generator
+   http://drag.wootest.net/misc/palgen.html
+*/
+
+// Parameter lines go here:
+#pragma parameter color_mode "Colorimetry mode" 0.0 0.0 2.0 1.0
+#pragma parameter white_point_d93 "Use D93 white point" 1.0 0.0 1.0 1.0
+#pragma parameter clipping_method "Color clipping method" 0.0 0.0 2.0 1.0
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+
+vec4 _oPosition1; 
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    COL0 = COLOR;
+    TEX0.xy = TexCoord.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out COMPAT_PRECISION vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+
+#ifdef PARAMETER_UNIFORM
+uniform COMPAT_PRECISION float color_mode;
+uniform COMPAT_PRECISION float white_point_d93;
+uniform COMPAT_PRECISION float clipping_method;
+#else
+#define color_mode 0.0
+#define white_point_d93 0.0
+#define clipping_method 0.0
+#endif
+
+vec3 huePreserveClipDarken(float r, float g, float b)
+{
+   float ratio = 1.0;
+   if ((r > 1.0) || (g > 1.0) || (b > 1.0))
+   {
+      float max = r;
+      if (g > max)
+         max = g;
+      if (b > max)
+         max = b;
+      ratio = 1.0 / max;
+   }
+
+   r *= ratio;
+   g *= ratio;
+   b *= ratio;
+
+   r = clamp(r, 0.0, 1.0);
+   g = clamp(g, 0.0, 1.0);
+   b = clamp(b, 0.0, 1.0);
+
+   return vec3(r, g, b);
+}
+
+vec3 huePreserveClipDesaturate(float r, float g, float b)
+{
+   float l = (.299 * r) + (0.587 * g) + (0.114 * b);
+   bool ovr = false;
+   float ratio = 1.0;
+
+   if ((r > 1.0) || (g > 1.0) || (b > 1.0))
+   {
+      ovr = true;
+      float max = r;
+      if (g > max) max = g;
+      if (b > max) max = b;
+      ratio = 1.0 / max;
+   }
+
+   if (ovr)
+   {
+      r -= 1.0;
+      g -= 1.0;
+      b -= 1.0;
+      r *= ratio;
+      g *= ratio;
+      b *= ratio;
+      r += 1.0;
+      g += 1.0;
+      b += 1.0;
+   }
+
+   r = clamp(r, 0.0, 1.0);
+   g = clamp(g, 0.0, 1.0);
+   b = clamp(b, 0.0, 1.0);
+
+   return vec3(r, g, b);
+}
+
+vec3 ApplyColorimetry(vec3 color)
+{
+   //http://www.brucelindbloom.com/Eqn_RGB_XYZ_Matrix.html
+   //http://www.dr-lex.be/random/matrix_inv.html
+   // Convert the (x,y) values to X Y Z.
+
+   float R = color.r;
+   float G = color.g;
+   float B = color.b;
+
+   float Rx = 0.0;
+   float Ry = 0.0;
+   float Gx = 0.0;
+   float Gy = 0.0;
+   float Bx = 0.0;
+   float By = 0.0;
+   float Wx = 0.0;
+   float Wy = 0.0;
+
+   if (white_point_d93 > 0.5)
+   {
+      Wx = 0.31;
+      Wy = 0.316;
+   }
+   else
+   {
+      Wx = 0.3127;
+      Wy = 0.329;
+   }
+
+   if (color_mode < 0.5)
+   {
+      // FCC 1953
+      // Original FCC standard for the color of the phosphors
+      Rx = 0.67;
+      Ry = 0.33;
+      Gx = 0.21;
+      Gy = 0.71;
+      Bx = 0.14;
+      By = 0.08;
+   }
+   else if (color_mode == 1.0) 
+   {
+      // SMPTE C (1987)
+      // A newer standard for the color of the phospors. (Not used in Japan)
+      Rx = 0.63;
+      Ry = 0.34;
+      Gx = 0.31;
+      Gy = 0.595;
+      Bx = 0.155;
+      By = 0.07;
+   }
+   else
+   {
+      //sRGB (PC Monitors)
+      //The colorimetry used in PC monitors, like the one you're (probably) looking at right now.
+      Rx = 0.64;
+      Ry = 0.33;
+      Gx = 0.3;
+      Gy = 0.6;
+      Bx = 0.15;
+      By = 0.06;
+   }
+
+   float Xr = Rx / Ry;
+   float Xg = Gx / Gy;
+   float Xb = Bx / By;
+   float Xw = Wx / Wy;
+   float Yr = 1.0;
+   float Yg = 1.0;
+   float Yb = 1.0;
+   float Yw = 1.0;
+   float Zr = (1.0 - Rx - Ry) / Ry;
+   float Zg = (1.0 - Gx - Gy) / Gy;
+   float Zb = (1.0 - Bx - By) / By;
+   float Zw = (1.0 - Wx - Wy) / Wy;
+
+   // Get ready for a bunch of painful math. I need to invert a matrix, then multiply it by a vector.
+   // Determinant for inverse matrix
+
+   float sDet = (Xr*((Zb*Yg)-(Zg*Yb)))-(Yr*((Zb*Xg)-(Zg*Xb)))+(Zr*((Yb*Xg)-(Yg*Xb)));
+
+   float Sr = ((((Zb*Yg)-(Zg*Yb))/sDet)*Xw) + ((-((Zb*Xg)-(Zg*Xb))/sDet)*Yw) + ((((Yb*Xg)-(Yg*Xb))/sDet)*Zw);
+   float Sg = ((-((Zb*Yr)-(Zr*Yb))/sDet)*Xw) + ((((Zb*Xr)-(Zr*Xb))/sDet)*Yw) + ((-((Yb*Xr)-(Yr*Xb))/sDet)*Zw);
+   float Sb = ((((Zg*Yr)-(Zr*Yg))/sDet)*Xw) + ((-((Zg*Xr)-(Zr*Xg))/sDet)*Yw) + ((((Yg*Xr)-(Yr*Xg))/sDet)*Zw);
+
+   // This should be the completed RGB -> XYZ matrix.
+   // Multiply each of the first three members by R, then add them together to get X
+   float convMatrix[9] = float[] (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+
+   convMatrix[0] = Sr*Xr;
+   convMatrix[1] = Sg*Xg;
+   convMatrix[2] = Sb*Xb;
+   convMatrix[3] = Sr*Yr;
+   convMatrix[4] = Sg*Yg;
+   convMatrix[5] = Sb*Yb;
+   convMatrix[6] = Sr*Zr;
+   convMatrix[7] = Sg*Zg;
+   convMatrix[8] = Sb*Zb;
+
+   // Convert RGB to XYZ using the matrix generated with the specified RGB and W points.	
+   float X = (convMatrix[0] * R) + (convMatrix[1] * G) + (convMatrix[2] * B);
+   float Y = (convMatrix[3] * R) + (convMatrix[4] * G) + (convMatrix[5] * B);
+   float Z = (convMatrix[6] * R) + (convMatrix[7] * G) + (convMatrix[8] * B);
+
+   // This is the conversion matrix for CIEXYZ -> sRGB. I nicked this from:
+   // http://www.brucelindbloom.com/Eqn_RGB_XYZ_Matrix.html
+   // and I know it's right because when you use the sRGB colorimetry, this matrix produces identical results to
+   // just using the raw R, G, and B above.
+   float xyztorgb[9] = float[] (3.2404, -1.5371, -0.4985, -0.9693, 1.876, 0.0416, 0.0556, -0.204, 1.0572);
+
+   // Convert back to RGB using the XYZ->sRGB matrix.
+   R = (xyztorgb[0]*X) + (xyztorgb[1]*Y) + (xyztorgb[2]*Z);
+   G = (xyztorgb[3]*X) + (xyztorgb[4]*Y) + (xyztorgb[5]*Z);
+   B = (xyztorgb[6]*X) + (xyztorgb[7]*Y) + (xyztorgb[8]*Z);
+
+   vec3 corrected_rgb;
+
+   // Apply desired clipping method to out-of-gamut colors.
+   if (clipping_method < 0.5)
+   {
+      //If a channel is out of range (> 1.0), it's simply clamped to 1.0. This may change hue, saturation, and/or lightness.
+      R = clamp(R, 0.0, 1.0);
+      G = clamp(G, 0.0, 1.0);
+      B = clamp(B, 0.0, 1.0);
+      corrected_rgb = vec3(R, G, B);
+   }
+   else if (clipping_method == 1.0)
+   {
+      //If any channels are out of range, the color is darkened until it is completely in range.
+      corrected_rgb = huePreserveClipDarken(R, G, B);
+   }
+   else if (clipping_method == 2.0)
+   {
+      //If any channels are out of range, the color is desaturated towards the luminance it would've had.
+      corrected_rgb = huePreserveClipDesaturate(R, G, B);
+   }
+
+   return corrected_rgb;
+}
+
+void main()
+{
+   vec4 c = COMPAT_TEXTURE(Source, vTexCoord.xy);
+   vec3 rgb = vec3(c.r, c.g, c.b);
+
+   vec3 out_color = ApplyColorimetry(rgb);
+   FragColor = vec4(out_color, 1.0);
+} 
+#endif
diff --git a/base/misc/deband.glsl b/base/misc/deband.glsl
new file mode 100644
index 0000000..637fd0e
--- /dev/null
+++ b/base/misc/deband.glsl
@@ -0,0 +1,195 @@
+/*
+ * Deband shader by haasn
+ * https://github.com/mpv-player/mpv/blob/master/video/out/opengl/video_shaders.c
+ *
+ * This file is part of mpv.
+ *
+ * mpv is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpv is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with mpv.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * You can alternatively redistribute this file and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * Modified and optimized for RetroArch by hunterk
+*/
+
+// Parameter lines go here:
+#pragma parameter iterations "Deband Iterations" 2.0 1.0 10.0 1.0
+#pragma parameter threshold "Deband Threshold" 1.0 1.0 16.0 0.5
+#pragma parameter range "Deband Range" 1.5 0.0 10.0 0.5
+#pragma parameter grain "Deband Grain" 0.0 0.0 2.0 0.1
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+
+vec4 _oPosition1; 
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+// compatibility #defines
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    TEX0.xy = TexCoord.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+
+
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+#ifdef PARAMETER_UNIFORM
+// All parameter floats need to have COMPAT_PRECISION in front of them
+uniform COMPAT_PRECISION float iterations;
+uniform COMPAT_PRECISION float threshold;
+uniform COMPAT_PRECISION float range;
+uniform COMPAT_PRECISION float grain;
+#else
+#define iterations 2.0
+#define threshold 1.0
+#define range 1.5
+#define grain 0.0
+#endif
+
+// Wide usage friendly PRNG, shamelessly stolen from a GLSL tricks forum post.
+// Obtain random numbers by calling rand(h), followed by h = permute(h) to
+// update the state. Assumes the texture was hooked.
+float mod289(float x)
+{
+	return x - floor(x / 289.0) * 289.0;
+}
+
+float permute(float x)
+{
+	return mod289((34.0 * x + 1.0) * x);
+}
+
+float rand(float x)
+{
+	return fract(x * 0.024390243);
+}
+
+vec4 average(sampler2D tex, vec2 coord, float range, inout float h, vec2 size)
+{
+	float dist = rand(h) * range;	h = permute(h);
+	float dir = rand(h) * 6.2831853;	h = permute(h);
+	vec2 o = vec2(cos(dir), sin(dir));
+	vec2 pt = dist / size.xy;
+	
+	vec4 ref[4];
+	ref[0] = COMPAT_TEXTURE(tex, coord + pt * vec2( o.x, o.y));
+	ref[1] = COMPAT_TEXTURE(tex, coord + pt * vec2(-o.y, o.x));
+	ref[2] = COMPAT_TEXTURE(tex, coord + pt * vec2(-o.x,-o.y));
+	ref[3] = COMPAT_TEXTURE(tex, coord + pt * vec2( o.y,-o.x));
+	
+	return (ref[0] + ref[1] + ref[2] + ref[3]) * 0.25;
+}
+
+void main()
+{
+	// Initialize the PRNG by hashing the position + a random uniform
+	vec3 m = vec3(vTexCoord, rand(sin(vTexCoord.x / vTexCoord.y) * mod(float(FrameCount), 79.) + 22.759)) + vec3(1.0);
+	float h = permute(permute(permute(m.x) + m.y) + m.z);
+	
+	vec4 avg;
+	vec4 diff;
+	
+	// Sample the source pixel
+	vec4 color = COMPAT_TEXTURE(Source, vTexCoord).rgba;
+	
+	for (int i = 1; i <= int(iterations); i++)
+		{
+			// Sample the average pixel and use it instead of the original if
+			// the difference is below the given threshold
+			avg = average(Source, vTexCoord, float(i) * range, h, TextureSize.xy);
+			diff = abs(color - avg);
+			color = mix(avg, color, float(greaterThan(diff, vec4(threshold / (float(i) * 10.0)))));
+		}
+	if (grain > 0.0)
+		{
+			// Add some random noise to smooth out residual differences
+			vec3 noise;
+			noise.x = rand(h); h = permute(h);
+			noise.y = rand(h); h = permute(h);
+			noise.z = rand(h); h = permute(h);
+			color.rgb += grain * (noise - vec3(0.5));
+		}
+	
+   FragColor = vec4(color);
+} 
+#endif
diff --git a/base/misc/deposterize-pass0.glsl b/base/misc/deposterize-pass0.glsl
new file mode 100644
index 0000000..cfbaa85
--- /dev/null
+++ b/base/misc/deposterize-pass0.glsl
@@ -0,0 +1,152 @@
+/*
+   Hyllian's Deposterize Shader - Pass0
+   
+   Copyright (C) 2011/2016 Hyllian/Jararaca - sergiogdb at gmail.com
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   as published by the Free Software Foundation; either version 2
+   of the License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+// Parameter lines go here:
+#pragma parameter EQ_THRESH1 "Eq Limit Horizontal" 0.01 0.0 1.0 0.01
+#pragma parameter DIFF_THRESH1 "Diff Limit Horizontal" 0.06 0.0 1.0 0.01
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+COMPAT_VARYING vec4 t1;
+
+vec4 _oPosition1; 
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize)
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    COL0 = COLOR;
+    TEX0.xy = TexCoord.xy * 1.0001;
+	vec2 ps = vec2(SourceSize.zw);
+	float dx = ps.x;
+	float dy = ps.y;
+	t1 = vTexCoord.xxxy + vec4( -dx, 0, dx,      0); //  D  E  F
+}
+
+#elif defined(FRAGMENT)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+COMPAT_VARYING vec4 t1;
+
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutputSize vec4(OutputSize, 1.0 / OutputSize)
+
+#ifdef PARAMETER_UNIFORM
+uniform COMPAT_PRECISION float EQ_THRESH1;
+uniform COMPAT_PRECISION float DIFF_THRESH1;
+#else
+#define EQ_THRESH1 0.01
+#define DIFF_THRESH1 0.06
+#endif
+
+#define EQ   EQ_THRESH1
+#define DF  DIFF_THRESH1
+
+vec3 df3(vec3 c1, vec3 c2)
+{
+      return abs(c1 - c2);
+}
+
+bvec3 eq3(vec3 A, vec3 B)
+{
+	return lessThanEqual(df3(A, B) , vec3(EQ));
+}
+
+void main()
+{
+	vec3 res;
+
+	vec3 D  = COMPAT_TEXTURE(Source, t1.xw).rgb;
+	vec3 E  = COMPAT_TEXTURE(Source, t1.yw).rgb;
+	vec3 F  = COMPAT_TEXTURE(Source, t1.zw).rgb;
+	
+	bvec3 test1 = eq3(D, F);
+	bvec3 test2 = eq3(D, E);
+	bvec3 test3 = eq3(E, F);
+	
+	bvec3 test4 = lessThanEqual(df3(E, F) , vec3(DF, DF, DF));
+	bvec3 test5 = lessThanEqual(df3(D, E) , vec3(DF, DF, DF));
+
+	res = ((test1 == bvec3(false)) && ((test4 == bvec3(true)) && (test2 == bvec3(true)) || (test5 == bvec3(true)) && (test3 == bvec3(true)))) ? 0.5*(D+F) : E;
+
+   FragColor = vec4(res, 1.0);
+} 
+#endif
diff --git a/base/misc/deposterize-pass1.glsl b/base/misc/deposterize-pass1.glsl
new file mode 100644
index 0000000..7944755
--- /dev/null
+++ b/base/misc/deposterize-pass1.glsl
@@ -0,0 +1,154 @@
+/*
+   Hyllian's Deposterize Shader - Pass1
+   
+   Copyright (C) 2011/2016 Hyllian/Jararaca - sergiogdb at gmail.com
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   as published by the Free Software Foundation; either version 2
+   of the License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+// Parameter lines go here:
+#pragma parameter EQ_THRESH2 "Eq Limit Vertical" 0.01 0.0 1.0 0.01
+#pragma parameter DIFF_THRESH2 "Diff Limit Vertical" 0.06 0.0 1.0 0.01
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+COMPAT_VARYING vec4 t1;
+
+vec4 _oPosition1; 
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize)
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    COL0 = COLOR;
+    TEX0.xy = TexCoord.xy * 1.0001;
+
+	vec2 ps = vec2(SourceSize.zw);
+	float dx = ps.x;
+	float dy = ps.y;
+	t1 = vTexCoord.xyyy + vec4(   0, -dy, 0,  dy); //  B  E  H
+}
+
+#elif defined(FRAGMENT)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+COMPAT_VARYING vec4 t1;
+
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutputSize vec4(OutputSize, 1.0 / OutputSize)
+
+#ifdef PARAMETER_UNIFORM
+// All parameter floats need to have COMPAT_PRECISION in front of them
+uniform COMPAT_PRECISION float EQ_THRESH2;
+uniform COMPAT_PRECISION float DIFF_THRESH2;
+#else
+#define EQ_THRESH2 0.01
+#define DIFF_THRESH2 0.06
+#endif
+
+#define EQ   EQ_THRESH2
+#define DF  DIFF_THRESH2
+
+vec3 df3(vec3 c1, vec3 c2)
+{
+      return abs(c1 - c2);
+}
+
+bvec3 eq3(vec3 A, vec3 B)
+{
+	return lessThanEqual(df3(A, B) , vec3(EQ));
+}
+
+void main()
+{
+	vec3 res;
+
+	vec3 B  = COMPAT_TEXTURE(Source, t1.xy).rgb;
+	vec3 E  = COMPAT_TEXTURE(Source, t1.xz).rgb;
+	vec3 H  = COMPAT_TEXTURE(Source, t1.xw).rgb;
+	
+	bvec3 test1 = eq3(B, H);
+	bvec3 test2 = eq3(B, E);
+	bvec3 test3 = eq3(E, H);
+	
+	bvec3 test4 = lessThanEqual(df3(E, H) , vec3(DF, DF, DF));
+	bvec3 test5 = lessThanEqual(df3(B, E) , vec3(DF, DF, DF));
+
+	res = ((test1 == bvec3(false)) && ((test4 == bvec3(true)) && (test2 == bvec3(true)) || (test5 == bvec3(true)) && (test3 == bvec3(true)))) ? 0.5*(B+H) : E;
+
+	FragColor = vec4(res, 1.0);
+} 
+#endif
diff --git a/base/misc/edge-detect.glsl b/base/misc/edge-detect.glsl
new file mode 100644
index 0000000..895ac07
--- /dev/null
+++ b/base/misc/edge-detect.glsl
@@ -0,0 +1,148 @@
+#pragma parameter minimum "Edge Thresh Min" 0.05 0.0 1.0 0.01
+#pragma parameter maximum "Edge Thresh Max" 0.35 0.0 1.0 0.01
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+// vertex compatibility #defines
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define outsize vec4(OutputSize, 1.0 / OutputSize)
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    COL0 = COLOR;
+    TEX0.xy = TexCoord.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+precision mediump int;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+uniform sampler2D PassPrevTexture;
+uniform sampler2D PassPrev1Texture;
+uniform sampler2D OrigTexture;
+COMPAT_VARYING vec4 TEX0;
+
+// fragment compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define outsize vec4(OutputSize, 1.0 / OutputSize)
+#define Smooth PassPrev1Texture
+#define Sharp PassPrevTexture
+
+#ifdef PARAMETER_UNIFORM
+uniform COMPAT_PRECISION float minimum;
+uniform COMPAT_PRECISION float maximum;
+#else
+#define minimum 0.05
+#define maximum 0.35
+#endif
+
+float threshold(float thr1, float thr2 , float val) {
+ val = (val < thr1) ? 0.0 : val;
+ val = (val > thr2) ? 1.0 : val;
+ return val;
+}
+
+// averaged pixel intensity from 3 color channels
+float avg_intensity(vec4 pix) {
+ return dot(pix.rgb, vec3(0.2126, 0.7152, 0.0722));
+}
+
+vec4 get_pixel(sampler2D tex, vec2 coords, float dx, float dy) {
+ return COMPAT_TEXTURE(tex, coords + vec2(dx, dy));
+}
+
+// returns pixel color
+float IsEdge(sampler2D tex, vec2 coords){
+  float dxtex = SourceSize.z;
+  float dytex = SourceSize.w;
+  float pix[9];
+  int k = -1;
+  float delta;
+
+  // read neighboring pixel intensities
+  for (int i=-1; i<2; i++) {
+   for(int j=-1; j<2; j++) {
+    k++;
+    pix[k] = avg_intensity(get_pixel(tex, coords, float(i) * dxtex,
+                                          float(j) * dytex));
+   }
+  }
+
+  // average color differences around neighboring pixels
+  delta = (abs(pix[1]-pix[7])+
+          abs(pix[5]-pix[3]) +
+          abs(pix[0]-pix[8])+
+          abs(pix[2]-pix[6])
+           )/4.;
+
+  return threshold(minimum, maximum,clamp(delta,0.0,1.0));
+}
+
+void main()
+{
+   float test = IsEdge(Source, vTexCoord);
+//   vec4 hybrid = vec4(0.0);
+//   hybrid = (test > 0.01) ? COMPAT_TEXTURE(Sharp, vTexCoord) : COMPAT_TEXTURE(Smooth, vTexCoord);
+   FragColor = vec4(test);
+} 
+#endif
diff --git a/base/misc/flicker.glsl b/base/misc/flicker.glsl
new file mode 100644
index 0000000..b1af585
--- /dev/null
+++ b/base/misc/flicker.glsl
@@ -0,0 +1,92 @@
+// flicker
+// show a black screen every other frame
+// license: public domain
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+
+vec4 _oPosition1; 
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+// compatibility #defines
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    TEX0.xy = TexCoord.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+void main()
+{
+	float check = mod(float(FrameCount), 2.0);
+
+    FragColor = COMPAT_TEXTURE(Source, vTexCoord) * check;
+} 
+#endif
diff --git a/base/misc/flip-horizontal.glsl b/base/misc/flip-horizontal.glsl
new file mode 100644
index 0000000..b87aecd
--- /dev/null
+++ b/base/misc/flip-horizontal.glsl
@@ -0,0 +1,101 @@
+// Mirror image shader
+// by hunterk
+// license: too simple to license but let's call it
+// public domain if that makes you feel better
+ 
+#pragma parameter MIRROR "Flip Horizontal" 1.0 0.0 1.0 1.0
+ 
+#if defined(VERTEX)
+ 
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying
+#define COMPAT_ATTRIBUTE attribute
+#define COMPAT_TEXTURE texture2D
+#endif
+ 
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+ 
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+ 
+vec4 _oPosition1;
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+ 
+// compatibility #defines
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+ 
+#ifdef PARAMETER_UNIFORM
+uniform COMPAT_PRECISION float MIRROR;
+#else
+#define MIRROR 1.0
+#endif
+ 
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    float offset = 0.5 * InputSize.x / TextureSize.x;
+    TEX0.xy = TexCoord.xy;
+    TEX0.x = (MIRROR > 0.5) ? (((TEX0.x - offset) * -1.0) + offset) : TEX0.x;
+}
+ 
+#elif defined(FRAGMENT)
+ 
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+ 
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out COMPAT_PRECISION vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+ 
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+ 
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+ 
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+ 
+void main()
+{
+    FragColor = COMPAT_TEXTURE(Source, vTexCoord);
+}
+#endif
diff --git a/base/misc/grade.glsl b/base/misc/grade.glsl
new file mode 100644
index 0000000..46c7d59
--- /dev/null
+++ b/base/misc/grade.glsl
@@ -0,0 +1,1005 @@
+/*
+   Grade
+   > Ubershader grouping some monolithic color related shaders:
+    ::color-mangler (hunterk), ntsc color tuning knobs (Doriphor), RA Reshade LUT.
+   > and the addition of:
+    ::analogue color emulation, phosphor gamut, color space + TRC support, vibrance, HUE vs SAT, temperature, vignette (shared by Syh), black level, rolled gain and sigmoidal contrast.
+
+   Author: Dogway
+   License: Public domain
+
+   **Thanks to those that helped me out keep motivated by continuous feedback and bug reports:
+   **Syh, Nesguy, hunterk, and the libretro forum members.
+
+
+    ######################################...PRESETS...#######################################
+    ##########################################################################################
+    ###                                                                                    ###
+    ###    PAL                                                                             ###
+    ###        Phosphor: EBU (#3)            (or an EBU T3213 based CRT phosphor gamut)    ###
+    ###        WP: D65 (6489K)               (in practice more like ~7500K)                ###
+    ###        TRC: 2.8 SMPTE-C Gamma                                                      ###
+    ###        Saturation: -0.02                                                           ###
+    ###                                                                                    ###
+    ###    NTSC-U                                                                          ###
+    ###        Phosphor: P22/SMPTE-C (#1 #-1)(or a SMPTE-C based CRT phosphor gamut)       ###
+    ###        WP: D65 (6504K)               (in practice more like ~7500K)                ###
+    ###        TRC: 2.22 SMPTE-C Gamma       (in practice more like 2.35-2.55)             ###
+    ###                                                                                    ###
+    ###    NTSC-J (Default)                                                                ###
+    ###        Phosphor: NTSC-J (#2)         (or a NTSC-J based CRT phosphor gamut)        ###
+    ###        WP: 9300K+27MPCD (8942K)      (CCT from x:0.281 y:0.311)                    ###
+    ###        TRC: 2.22 SMPTE-C Gamma       (in practice more like 2.35-2.55)             ###
+    ###                                                                                    ###
+    ###    *Despite the standard of 2.22, a more faithful approximation to CRT...          ###
+    ###     ...is to use a gamma (SMPTE-C type) with a value of 2.35-2.55.                 ###
+    ###                                                                                    ###
+    ###                                                                                    ###
+    ##########################################################################################
+    ##########################################################################################
+*/
+
+
+#pragma parameter g_gamma_in     "CRT Gamma"                                               2.40 1.80 3.0 0.05
+#pragma parameter g_signal_type  "Signal Type (0:RGB 1:Composite)"                         1.0 0.0 1.0 1.0
+#pragma parameter g_gamma_type   "Signal Gamma Type (0:sRGB 1:SMPTE-C)"                    1.0 0.0 1.0 1.0
+#pragma parameter g_crtgamut     "Phosphor (1:NTSC-U 2:NTSC-J 3:PAL)"                      2.0 -4.0 3.0 1.0
+#pragma parameter g_space_out    "Diplay Color Space (-1:709 0:sRGB 1:DCI 2:2020 3:Adobe)" 0.0 -1.0 3.0 1.0
+
+#pragma parameter g_hue_degrees  "Hue"                  0.0 -360.0 360.0 1.0
+#pragma parameter g_I_SHIFT      "I/U Shift"            0.0 -0.2 0.2 0.01
+#pragma parameter g_Q_SHIFT      "Q/V Shift"            0.0 -0.2 0.2 0.01
+#pragma parameter g_I_MUL        "I/U Multiplier"       1.0  0.0 2.0 0.01
+#pragma parameter g_Q_MUL        "Q/V Multiplier"       1.0  0.0 2.0 0.01
+#pragma parameter g_lum_fix      "Sega Luma Fix"        0.0  0.0 1.0 1.0
+#pragma parameter g_vignette     "Vignette Toggle"      1.0  0.0 1.0 1.0
+#pragma parameter g_vstr         "Vignette Strength"    40.0 0.0 50.0 1.0
+#pragma parameter g_vpower       "Vignette Power"       0.20 0.0 0.5 0.01
+#pragma parameter g_lum          "Brightness"           0.0 -0.5 1.0 0.01
+#pragma parameter g_cntrst       "Contrast"             0.0 -1.0 1.0 0.05
+#pragma parameter g_mid          "Contrast Pivot"       0.5  0.0 1.0 0.01
+#pragma parameter wp_temperature "White Point"          6504.0 5004.0 12004.0 100.0
+#pragma parameter g_sat          "Saturation"           0.0 -1.0 2.0 0.01
+#pragma parameter g_vibr         "Dullness/Vibrance"    0.0 -1.0 1.0 0.05
+#pragma parameter g_satr         "Hue vs Sat Red"       0.0 -1.0 1.0 0.01
+#pragma parameter g_satg         "Hue vs Sat Green"     0.0 -1.0 1.0 0.01
+#pragma parameter g_satb         "Hue vs Sat Blue"      0.0 -1.0 1.0 0.01
+#pragma parameter g_lift         "Black Level"          0.0 -0.5 0.5 0.01
+#pragma parameter blr            "Black-Red Tint"       0.0  0.0 1.0 0.01
+#pragma parameter blg            "Black-Green Tint"     0.0  0.0 1.0 0.01
+#pragma parameter blb            "Black-Blue Tint"      0.0  0.0 1.0 0.01
+#pragma parameter wlr            "White-Red Tint"       1.0  0.0 2.0 0.01
+#pragma parameter wlg            "White-Green Tint"     1.0  0.0 2.0 0.01
+#pragma parameter wlb            "White-Blue Tint"      1.0  0.0 2.0 0.01
+#pragma parameter rg             "Red-Green Tint"       0.0 -1.0 1.0 0.005
+#pragma parameter rb             "Red-Blue Tint"        0.0 -1.0 1.0 0.005
+#pragma parameter gr             "Green-Red Tint"       0.0 -1.0 1.0 0.005
+#pragma parameter gb             "Green-Blue Tint"      0.0 -1.0 1.0 0.005
+#pragma parameter br             "Blue-Red Tint"        0.0 -1.0 1.0 0.005
+#pragma parameter bg             "Blue-Green Tint"      0.0 -1.0 1.0 0.005
+#pragma parameter LUT_Size1      "LUT Size 1"           16.0 8.0 64.0 16.0
+#pragma parameter LUT1_toggle    "LUT 1 Toggle"         0.0  0.0 1.0 1.0
+#pragma parameter LUT_Size2      "LUT Size 2"           64.0 0.0 64.0 16.0
+#pragma parameter LUT2_toggle    "LUT 2 Toggle"         0.0  0.0 1.0 1.0
+
+#define M_PI            3.1415926535897932384626433832795
+#define SPC             g_space_out
+#define gamma_in        g_gamma_in
+#define gamma_type      g_gamma_type
+#define signal          g_signal_type
+#define crtgamut        g_crtgamut
+#define hue_degrees     g_hue_degrees
+#define I_SHIFT         g_I_SHIFT
+#define Q_SHIFT         g_Q_SHIFT
+#define I_MUL           g_I_MUL
+#define Q_MUL           g_Q_MUL
+#define lum_fix         g_lum_fix
+#define vignette        g_vignette
+#define vstr            g_vstr
+#define satr            g_satr
+#define satg            g_satg
+#define satb            g_satb
+#define vpower          g_vpower
+#define vibr            g_vibr
+#define lum             g_lum
+#define cntrst          g_cntrst
+#define mid             g_mid
+#define lift            g_lift
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying
+#define COMPAT_ATTRIBUTE attribute
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+// compatibility #defines
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+void main()
+{
+   gl_Position = MVPMatrix * VertexCoord;
+   TEX0.xy = TexCoord.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out COMPAT_PRECISION vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+uniform sampler2D SamplerLUT1;
+uniform sampler2D SamplerLUT2;
+COMPAT_VARYING vec4 TEX0;
+
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+#ifdef PARAMETER_UNIFORM
+uniform COMPAT_PRECISION float SPC;
+uniform COMPAT_PRECISION float gamma_in;
+uniform COMPAT_PRECISION float gamma_type;
+uniform COMPAT_PRECISION float signal;
+uniform COMPAT_PRECISION float crtgamut;
+uniform COMPAT_PRECISION float hue_degrees;
+uniform COMPAT_PRECISION float I_SHIFT;
+uniform COMPAT_PRECISION float Q_SHIFT;
+uniform COMPAT_PRECISION float I_MUL;
+uniform COMPAT_PRECISION float Q_MUL;
+uniform COMPAT_PRECISION float wp_temperature;
+uniform COMPAT_PRECISION float lum_fix;
+uniform COMPAT_PRECISION float vignette;
+uniform COMPAT_PRECISION float vstr;
+uniform COMPAT_PRECISION float vpower;
+uniform COMPAT_PRECISION float g_sat;
+uniform COMPAT_PRECISION float vibr;
+uniform COMPAT_PRECISION float satr;
+uniform COMPAT_PRECISION float satg;
+uniform COMPAT_PRECISION float satb;
+uniform COMPAT_PRECISION float lum;
+uniform COMPAT_PRECISION float cntrst;
+uniform COMPAT_PRECISION float mid;
+uniform COMPAT_PRECISION float lift;
+uniform COMPAT_PRECISION float blr;
+uniform COMPAT_PRECISION float blg;
+uniform COMPAT_PRECISION float blb;
+uniform COMPAT_PRECISION float wlr;
+uniform COMPAT_PRECISION float wlg;
+uniform COMPAT_PRECISION float wlb;
+uniform COMPAT_PRECISION float rg;
+uniform COMPAT_PRECISION float rb;
+uniform COMPAT_PRECISION float gr;
+uniform COMPAT_PRECISION float gb;
+uniform COMPAT_PRECISION float br;
+uniform COMPAT_PRECISION float bg;
+uniform COMPAT_PRECISION float LUT_Size1;
+uniform COMPAT_PRECISION float LUT1_toggle;
+uniform COMPAT_PRECISION float LUT_Size2;
+uniform COMPAT_PRECISION float LUT2_toggle;
+#else
+#define SPC 1.00
+#define gamma_in 2.40
+#define signal 1.0
+#define gamma_type 1.0
+#define vignette 1.0
+#define vstr 40.0
+#define vpower 0.2
+#define crtgamut 2.0
+#define hue_degrees 0.0
+#define I_SHIFT 0.0
+#define Q_SHIFT 0.0
+#define I_MUL 1.0
+#define Q_MUL 1.0
+#define wp_temperature 6505.0
+#define lum_fix 0.0
+#define g_sat 0.0
+#define vibr 0.0
+#define satr 0.0
+#define satg 0.0
+#define satb 0.0
+#define lum 0.0
+#define cntrst 0.0
+#define mid 0.5
+#define lift 0.0
+#define blr 0.0
+#define blg 0.0
+#define blb 0.0
+#define wlr 1.0
+#define wlg 1.0
+#define wlb 1.0
+#define rg 0.0
+#define rb 0.0
+#define gr 0.0
+#define gb 0.0
+#define br 0.0
+#define bg 0.0
+#define LUT_Size1 16.0
+#define LUT1_toggle 0.0
+#define LUT_Size2 64.0
+#define LUT2_toggle 0.0
+#endif
+
+///////////////////////// Color Space Transformations //////////////////////////
+
+
+
+vec3 XYZ_to_RGB(vec3 XYZ, float CSPC){
+
+    // to sRGB
+    const mat3x3 sRGB = mat3x3(
+    3.24081254005432130, -0.969243049621582000,  0.055638398975133896,
+   -1.53730857372283940,  1.875966310501098600, -0.204007431864738460,
+   -0.49858659505844116,  0.041555050760507584,  1.057129383087158200);
+
+    // to DCI-P3 -D65-
+    const mat3x3 DCIP3 = mat3x3(
+     2.49339652061462400, -0.82948720455169680,  0.035850685089826584,
+    -0.93134605884552000,  1.76266026496887200, -0.076182708144187930,
+    -0.40269458293914795,  0.023624641820788383, 0.957014024257659900);
+
+    // to Rec.2020
+    const mat3x3 rec2020 = mat3x3(
+     1.71660947799682620, -0.66668272018432620,  0.017642205581068993,
+    -0.35566213726997375,  1.61647748947143550, -0.042776308953762054,
+    -0.25336012244224550,  0.01576850563287735,  0.942228555679321300);
+
+    // from AdobeRGB
+    const mat3x3 Adobe = mat3x3(
+     2.0415899753570557, -0.96924000978469850,  0.013439999893307686,
+    -0.5650100111961365,  1.87597000598907470, -0.118359997868537900,
+    -0.3447299897670746,  0.04156000167131424,  1.015169978141784700);
+
+   return (CSPC == 3.0) ? Adobe * XYZ : (CSPC == 2.0) ? rec2020 * XYZ : (CSPC == 1.0) ? DCIP3 * XYZ : sRGB * XYZ;
+}
+
+vec3 RGB_to_XYZ(vec3 RGB, float CSPC){
+
+    // from sRGB
+    const mat3x3 sRGB = mat3x3(
+    0.41241079568862915, 0.21264933049678802, 0.019331756979227066,
+    0.35758456587791443, 0.71516913175582890, 0.119194857776165010,
+    0.18045382201671600, 0.07218152284622192, 0.950390160083770800);
+
+    // from DCI-P3 -D65-
+    const mat3x3 DCIP3 = mat3x3(
+    0.48659050464630127, 0.22898375988006592, 0.00000000000000000,
+    0.26566821336746216, 0.69173991680145260, 0.04511347413063049,
+    0.19819043576717377, 0.07927616685628891, 1.04380297660827640);
+
+    // from Rec.2020
+    const mat3x3 rec2020 = mat3x3(
+    0.63697350025177000, 0.24840137362480164, 0.00000000000000000,
+    0.15294560790061950, 0.67799961566925050, 0.04253686964511871,
+    0.11785808950662613, 0.03913172334432602, 1.06084382534027100);
+
+    // from AdobeRGB
+    const mat3x3 Adobe = mat3x3(
+    0.57666999101638790, 0.2973400056362152, 0.02703000046312809,
+    0.18556000292301178, 0.6273599863052368, 0.07068999856710434,
+    0.18822999298572540, 0.0752900019288063, 0.9913399815559387);
+
+   return (CSPC == 3.0) ? Adobe * RGB : (CSPC == 2.0) ? rec2020 * RGB : (CSPC == 1.0) ? DCIP3 * RGB : sRGB * RGB;
+}
+
+
+vec3 XYZtoYxy(vec3 XYZ){
+
+    float XYZrgb = XYZ.r+XYZ.g+XYZ.b;
+    float Yxyg = (XYZrgb <= 0.0) ? 0.3805 : XYZ.r / XYZrgb;
+    float Yxyb = (XYZrgb <= 0.0) ? 0.3769 : XYZ.g / XYZrgb;
+    return vec3(XYZ.g, Yxyg, Yxyb);
+}
+
+vec3 YxytoXYZ(vec3 Yxy){
+
+    float Xs = Yxy.r * (Yxy.g/Yxy.b);
+    float Xsz = (Yxy.r <= 0.0) ? 0.0 : 1.0;
+    vec3 XYZ = vec3(Xsz,Xsz,Xsz) * vec3(Xs, Yxy.r, (Xs/Yxy.g)-Xs-Yxy.r);
+    return XYZ;
+}
+
+///////////////////////// White Point Mapping /////////////////////////
+//
+//
+// PAL: D65      NTSC-U: D65      NTSC-J: CCT NTSC-J NTSC-FCC: C
+// PAL: 6489K    NTSC-U: 6504K    NTSC-J: 8942K      NTSC-FCC: 6780K
+// 0.313 0.329   0.3127 0.3290    0.281 0.311        0.310, 0.316
+
+vec3 wp_adjust(float temperature){
+
+    float temp3 = pow(10.,3.) / temperature;
+    float temp6 = pow(10.,6.) / pow(temperature, 2.);
+    float temp9 = pow(10.,9.) / pow(temperature, 3.);
+
+    vec3 wp = vec3(1.);
+
+    wp.x = (temperature <= 7000.) ? 0.244063 + 0.09911 * temp3 + 2.9678 * temp6 - 4.6070 * temp9 : \
+                                    0.237040 + 0.24748 * temp3 + 1.9018 * temp6 - 2.0064 * temp9 ;
+
+    wp.y = -3.000 * pow(wp.x,2.) + 2.870 * wp.x - 0.275;
+    wp.z = 1. - wp.x - wp.y;
+
+    return wp.xyz;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+
+// Monitor Curve Functions: https://github.com/ampas/aces-dev
+//----------------------------------------------------------------------
+
+
+float moncurve_f( float color, float gamma, float offs)
+{
+    // Forward monitor curve
+    color = clamp(color, 0.0, 1.0);
+    float fs = (( gamma - 1.0) / offs) * pow( offs * gamma / ( ( gamma - 1.0) * ( 1.0 + offs)), gamma);
+    float xb = offs / ( gamma - 1.0);
+
+    color = ( color > xb) ? pow( ( color + offs) / ( 1.0 + offs), gamma) : color * fs;
+    return color;
+}
+
+
+vec3 moncurve_f_f3( vec3 color, float gamma, float offs)
+{
+    color.r = moncurve_f( color.r, gamma, offs);
+    color.g = moncurve_f( color.g, gamma, offs);
+    color.b = moncurve_f( color.b, gamma, offs);
+    return color.rgb;
+}
+
+
+float moncurve_r( float color, float gamma, float offs)
+{
+    // Reverse monitor curve
+    color = clamp(color, 0.0, 1.0);
+    float yb = pow( offs * gamma / ( ( gamma - 1.0) * ( 1.0 + offs)), gamma);
+    float rs = pow( ( gamma - 1.0) / offs, gamma - 1.0) * pow( ( 1.0 + offs) / gamma, gamma);
+
+    color = ( color > yb) ? ( 1.0 + offs) * pow( color, 1.0 / gamma) - offs : color * rs;
+    return color;
+}
+
+
+vec3 moncurve_r_f3( vec3 color, float gamma, float offs)
+{
+    color.r = moncurve_r( color.r, gamma, offs);
+    color.g = moncurve_r( color.g, gamma, offs);
+    color.b = moncurve_r( color.b, gamma, offs);
+    return color.rgb;
+}
+
+
+//-------------------------- Luma Functions ----------------------------
+
+
+//  Performs better in gamma encoded space
+float contrast_sigmoid(float color, float cont, float pivot){
+
+    cont = pow(cont + 1., 3.);
+
+    float knee = 1. / (1. + exp(cont * pivot));
+    float shldr = 1. / (1. + exp(cont * (pivot - 1.)));
+
+    color = (1. / (1. + exp(cont * (pivot - color))) - knee) / (shldr - knee);
+
+    return color;
+}
+
+
+//  Performs better in gamma encoded space
+float contrast_sigmoid_inv(float color, float cont, float pivot){
+
+    cont = pow(cont - 1., 3.);
+
+    float knee = 1. / (1. + exp (cont * pivot));
+    float shldr = 1. / (1. + exp (cont * (pivot - 1.)));
+
+    color = pivot - log(1. / (color * (shldr - knee) + knee) - 1.) / cont;
+
+    return color;
+}
+
+
+float rolled_gain(float color, float gain){
+
+    float gx = abs(gain) + 0.001;
+    float anch = (gain > 0.0) ? 0.5 / (gx / 2.0) : 0.5 / gx;
+    color = (gain > 0.0) ? color * ((color - anch) / (1 - anch)) : color * ((1 - anch) / (color - anch)) * (1 - gain);
+
+    return color;
+}
+
+
+vec4 rolled_gain_v4(vec4 color, float gain){
+
+    color.r = rolled_gain(color.r, gain);
+    color.g = rolled_gain(color.g, gain);
+    color.b = rolled_gain(color.b, gain);
+
+    return vec4(color.rgb, 1.0);
+}
+
+
+float SatMask(float color_r, float color_g, float color_b)
+{
+    float max_rgb = max(color_r, max(color_g, color_b));
+    float min_rgb = min(color_r, min(color_g, color_b));
+    float msk = clamp((max_rgb - min_rgb) / (max_rgb + min_rgb), 0.0, 1.0);
+    return msk;
+}
+
+
+//  This shouldn't be necessary but it seems some undefined values can
+//  creep in and each GPU vendor handles that differently. This keeps
+//  all values within a safe range
+vec3 mixfix(vec3 a, vec3 b, float c)
+{
+    return (a.z < 1.0) ? mix(a, b, c) : a;
+}
+
+
+vec4 mixfix_v4(vec4 a, vec4 b, float c)
+{
+    return (a.z < 1.0) ? mix(a, b, c) : a;
+}
+
+
+//---------------------- Range Expansion/Compression -------------------
+
+
+//  to Studio Swing/Broadcast Safe/SMPTE legal/Limited Range
+vec3 PCtoTV(vec3 col, float luma_swing, float Umax, float Vmax, float max_swing, bool rgb_in)
+{
+   col *= 255.;
+   Umax = (max_swing == 1.0) ? Umax * 224. : Umax * 239.;
+   Vmax = (max_swing == 1.0) ? Vmax * 224. : Vmax * 239.;
+
+   col.x = (luma_swing == 1.0) ? ((col.x * 219.) / 255.) + 16. : col.x;
+   col.y = (rgb_in == true) ? ((col.y * 219.) / 255.) + 16. : (((col.y - 128.) * (Umax * 2.)) / 255.) + Umax;
+   col.z = (rgb_in == true) ? ((col.z * 219.) / 255.) + 16. : (((col.z - 128.) * (Vmax * 2.)) / 255.) + Vmax;
+   return col.xyz / 255.;
+}
+
+
+//  to Full Swing/Full Range
+vec3 TVtoPC(vec3 col, float luma_swing, float Umax, float Vmax, float max_swing, bool rgb_in)
+{
+   col *= 255.;
+   Umax = (max_swing == 1.0) ? Umax * 224. : Umax * 239.;
+   Vmax = (max_swing == 1.0) ? Vmax * 224. : Vmax * 239.;
+
+   float colx = (luma_swing == 1.0) ? ((col.x - 16.) / 219.) * 255. : col.x;
+   float coly = (rgb_in == true) ? ((col.y - 16.) / 219.) * 255. : (((col.y - Umax) / (Umax * 2.)) * 255.) + 128.;
+   float colz = (rgb_in == true) ? ((col.z - 16.) / 219.) * 255. : (((col.z - Vmax) / (Vmax * 2.)) * 255.) + 128.;
+   return vec3(colx,coly,colz) / 255.;
+}
+
+
+//*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
+
+
+//--------------------- ITU-R BT.470/601 (M) (1953) --------------------
+
+
+//  FCC (Sanctioned) YIQ matrix
+vec3 RGB_FCC(vec3 col)
+ {
+    const mat3 conv_mat = mat3(
+    0.299996928307425,  0.590001575542717,  0.110001496149858,
+    0.599002392519453, -0.277301256521204, -0.321701135998249,
+    0.213001700342824, -0.525101205289350,  0.312099504946526);
+
+    return col.rgb * conv_mat;
+ }
+
+//  FCC (Sanctioned) YIQ matrix (inverse)
+vec3 FCC_RGB(vec3 col)
+ {
+    const mat3 conv_mat = mat3(
+    1.0000000,  0.946882217090069,  0.623556581986143,
+    1.0000000, -0.274787646298978, -0.635691079187380,
+    1.0000000, -1.108545034642030,  1.709006928406470);
+
+    return col.rgb * conv_mat;
+ }
+
+
+//--------------------- SMPTE RP 145 (C), 170M (1987) ------------------
+
+
+vec3 RGB_YIQ(vec3 col)
+ {
+    const mat3 conv_mat = mat3(
+    0.2990,  0.5870,  0.1140,
+    0.5959, -0.2746, -0.3213,
+    0.2115, -0.5227,  0.3112);
+
+    return col.rgb * conv_mat;
+ }
+
+vec3 YIQ_RGB(vec3 col)
+ {
+    const mat3 conv_mat = mat3(
+    1.0000000,  0.956,  0.619,
+    1.0000000, -0.272, -0.647,
+    1.0000000, -1.106,  1.703);
+
+    return col.rgb * conv_mat;
+ }
+
+//----------------------- ITU-R BT.470/601 (B/G) -----------------------
+
+
+vec3 r601_YUV(vec3 RGB)
+ {
+    const mat3 conv_mat = mat3(
+    0.299000,  0.587000,  0.114000,
+   -0.147407, -0.289391,  0.436798,
+    0.614777, -0.514799, -0.099978);
+
+    return RGB.rgb * conv_mat;
+ }
+
+vec3 YUV_r601(vec3 RGB)
+ {
+    const mat3 conv_mat = mat3(
+    1.0000000,  0.00000000000000000,  1.14025080204010000,
+    1.0000000, -0.39393067359924316, -0.58080917596817020,
+    1.0000000,  2.02839756011962900, -0.00000029356581166);
+
+    return RGB.rgb * conv_mat;
+ }
+
+//  Custom - not Standard
+vec3 YUV_r709(vec3 YUV)
+ {
+    const mat3 conv_mat = mat3(
+    1.0000000,  0.0000000000000000,  1.14025092124938960,
+    1.0000000, -0.2047683298587799, -0.33895039558410645,
+    1.0000001,  2.0283975601196290,  0.00000024094399364);
+
+    return YUV.rgb * conv_mat;
+ }
+
+//  Custom - not Standard
+vec3 r709_YUV(vec3 RGB)
+ {
+    const mat3 conv_mat = mat3(
+    0.2126000,  0.715200,   0.0722000,
+   -0.1048118, -0.3525936,  0.4574054,
+    0.6905498, -0.6272304, -0.0633194);
+
+    return RGB.rgb * conv_mat;
+ }
+
+
+//------------------------- SMPTE-240M Y’PbPr --------------------------
+
+
+//  Umax 0.886
+//  Vmax 0.700
+//  RGB to YPbPr -full to limited range- with Rec.601 primaries
+vec3 r601_YCC(vec3 RGB)
+ {
+    const mat3 conv_mat = mat3(
+    0.299,                   0.587,                   0.114,
+   -0.16873589164785553047, -0.33126410835214446953,  0.500,
+    0.500,                  -0.41868758915834522111, -0.08131241084165477889);
+
+    return RGB.rgb * conv_mat;
+ }
+
+//  YPbPr to RGB  -limited to full range- with Rec.601 primaries
+vec3 YCC_r601(vec3 YUV)
+ {
+    const mat3 conv_mat = mat3(
+    1.0000000,  0.000,                   1.402,
+    1.0000000, -0.34413628620102214651, -0.71413628620102214651,
+    1.0000000,  1.772,                   0.000);
+
+    return YUV.rgb * conv_mat;
+ }
+
+//  Umax 0.53890924768269023496443198965294
+//  Vmax 0.63500127000254000508001016002032
+//  RGB to YPbPr -full range in-gamut- with Rec.709 primaries
+vec3 r709_YCC(vec3 RGB)
+ {
+    const mat3 conv_mat = mat3(
+    0.2126,                  0.7152,                  0.0722,
+   -0.11457210605733994395, -0.38542789394266005605,  0.5000,
+    0.5000,                 -0.45415290830581661163, -0.04584709169418338837);
+
+    return RGB.rgb * conv_mat;
+ }
+
+//  YPbPr to RGB -full range in-gamut- with Rec.709 primaries
+vec3 YCC_r709(vec3 YUV)
+ {
+    const mat3 conv_mat = mat3(
+    1.0000000,  0.00000000000000000000,  1.5748,
+    1.0000000, -0.18732427293064876957, -0.46812427293064876957,
+    1.0000000,  1.8556,                  0.00000000000000000000);
+
+    return YUV.rgb * conv_mat;
+ }
+
+
+//------------------------- IPT --------------------------
+
+
+const mat3 LMS =
+mat3(
+ 0.4002, 0.7076, -0.0808,
+-0.2263, 1.1653,  0.0457,
+ 0.0,       0.0,  0.9182);
+
+const mat3 IPT =
+mat3(
+ 0.4000,  0.4000, 0.2000,
+ 4.4550, -4.8510, 0.3960,
+ 0.8056, 0.3572, -1.1628);
+
+
+
+//*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
+
+
+
+const mat3 C_D65_Brad =
+mat3(
+ 1.0062731504440308000, 0.0028941007331013680, -0.0070838485844433310,
+ 0.0036507491022348404, 0.9992200732231140000, -0.0023814644664525986,
+-0.0013438384048640728, 0.0022154981270432472,  0.9643852710723877000);
+
+const mat3 D93_D65_Brad =
+mat3(
+ 1.074299335479736300, 0.03572637960314751, -0.042645290493965150,
+ 0.050180613994598390, 0.97543668746948240, -0.015837108716368675,
+-0.006000521592795849, 0.00851820595562458,  0.827671706676483200);
+
+const mat3 PAL_D65_Brad =
+mat3(
+ 0.99919301271438600000, -0.00044559128582477570, 0.00027090078219771385,
+-0.00065565120894461870,  1.00049483776092530000, 0.00011852011084556580,
+ 1.3149343430995941e-05,  3.4691765904426575e-06, 1.00069344043731700000);
+
+
+//----------------------------------------------------------------------
+
+
+// ITU-R BT.470/601 (M) (proof of concept, actually never used)
+// SMPTE 170M-1999
+// NTSC-FCC 1953 Standard Phosphor (use with temperature C: 6780K)
+const mat3 NTSC_FCC_transform =
+mat3(
+ 0.60699284076690670, 0.2989666163921356, 0.00000000000000000,
+ 0.17344850301742554, 0.5864211320877075, 0.06607561558485031,
+ 0.20057128369808197, 0.1146121546626091, 1.11746847629547120);
+
+// ITU-R BT.470/601 (M)
+// Conrac 7211N19 CRT Phosphor
+const mat3 Conrac_transform =
+mat3(
+ 0.55842006206512450, 0.28580552339553833, 0.03517606481909752,
+ 0.20613566040992737, 0.63714659214019780, 0.09369802474975586,
+ 0.18589359521865845, 0.07704800367355347, 0.96004259586334230);
+
+// NTSC-J (use with D93 white point)
+// Sony Trinitron KV-20M20
+const mat3 Sony20_20_transform =
+mat3(
+ 0.33989441394805910, 0.18490256369113922, 0.019034087657928467,
+ 0.33497872948646545, 0.71182984113693240, 0.149544075131416320,
+ 0.22866378724575043, 0.10326752066612244, 1.143318891525268600);
+
+// SMPTE-C - Measured Average Phosphor (1979-1994)
+const mat3 P22_transform =
+mat3(
+ 0.4665636420249939, 0.25661000609397890, 0.005832045804709196,
+ 0.3039233088493347, 0.66820019483566280, 0.105618737637996670,
+ 0.1799621731042862, 0.07518967241048813, 0.977465748786926300);
+
+// SMPTE RP 145-1994 (SMPTE-C), 170M-1999
+// SMPTE-C - Standard Phosphor
+const mat3 SMPTE_transform =
+mat3(
+ 0.39354196190834045, 0.21238772571086884, 0.01874009333550930,
+ 0.36525884270668030, 0.70106136798858640, 0.11193416267633438,
+ 0.19164848327636720, 0.08655092865228653, 0.95824241638183590);
+
+// SMPTE RP 145-1994 (SMPTE-C), 170M-1999
+// NTSC-J - Standard Phosphor (use with D93 white point)
+const mat3 NTSC_J_transform =
+mat3(
+ 0.39603787660598755, 0.22429330646991730, 0.02050681784749031,
+ 0.31201449036598206, 0.67417418956756590, 0.12814880907535553,
+ 0.24496731162071228, 0.10153251141309738, 1.26512730121612550);
+
+// ITU-R BT.470/601 (B/G)
+// EBU Tech.3213 PAL - Standard Phosphor for Studio Monitors
+const mat3 EBU_transform =
+mat3(
+ 0.43194326758384705, 0.22272075712680817, 0.020247340202331543,
+ 0.34123489260673523, 0.70600330829620360, 0.129433929920196530,
+ 0.17818950116634370, 0.07127580046653748, 0.938464701175689700);
+
+
+
+
+//*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/
+
+
+
+
+
+void main()
+{
+
+// Retro Sega Systems: Genesis, 32x, CD and Saturn 2D had color palettes designed in TV levels to save on transformations.
+    float lum_exp = (lum_fix ==  1.0) ? (255./239.) : 1.;
+
+    vec3 src = COMPAT_TEXTURE(Source, vTexCoord).rgb;
+         src = (signal == 0.0) ? moncurve_f_f3(src * lum_exp, 2.40, 0.055) : \
+                                 moncurve_f_f3(src,           2.40, 0.055) ;
+
+// CRT Gamma: SMPTE-C gamma at 2.222 approximates to a power law gamma of 2.0
+    vec3 gamma_fix = (gamma_type == 1.0) ? moncurve_r_f3(src, gamma_in + 0.0222, 0.099)  : \
+                                           moncurve_r_f3(src, gamma_in - 0.1222, 0.055)  ;
+
+    vec3 col = gamma_fix;
+
+// make a YUV * NTSC Phosphor option too and a FCC * NTSC phosphor
+    col = (crtgamut ==  3.0) ? r601_YUV(col*lum_exp)   : \
+          (crtgamut ==  2.0) ?  RGB_YIQ(col*lum_exp)   : \
+          (crtgamut == -3.0) ?  RGB_FCC(col*lum_exp)   : \
+          (crtgamut == -4.0) ?  RGB_FCC(col*lum_exp)   : \
+                                RGB_YIQ(col*lum_exp)   ;
+
+
+// Clipping Logic / Gamut Limiting
+    vec2 UVmax = (crtgamut ==  3.0) ? vec2(0.436798,          0.614777)         : \
+                 (crtgamut == -4.0) ? vec2(0.599002392519453, 0.52510120528935) : \
+                 (crtgamut == -3.0) ? vec2(0.599002392519453, 0.52510120528935) : \
+                                      vec2(0.5959,            0.5227)           ;
+
+    col = clamp(col.xyz, vec3(0.0, -UVmax.x, -UVmax.y), vec3(1.0, UVmax.x, UVmax.y));
+
+
+    col = (crtgamut ==  3.0) ?        col                                       : \
+          (crtgamut ==  2.0) ?        col                                       : \
+          (crtgamut == -3.0) ? PCtoTV(col, 1.0, UVmax.x, UVmax.y, 1.0, false)   : \
+          (crtgamut == -4.0) ? PCtoTV(col, 1.0, UVmax.x, UVmax.y, 1.0, false)   : \
+                               PCtoTV(col, 1.0, UVmax.x, UVmax.y, 1.0, false)   ;
+
+
+// YIQ/YUV Analogue Color Controls (HUE + Color Shift + Color Burst)
+    float hue_radians = hue_degrees * (M_PI / 180.0);
+    float hue = atan(col.z, col.y) + hue_radians;
+    float chroma = sqrt(col.z * col.z + col.y * col.y);
+    col = vec3(col.x, chroma * cos(hue), chroma * sin(hue));
+
+    col.y = (mod((col.y + 1.0) + I_SHIFT, 2.0) - 1.0) * I_MUL;
+    col.z = (mod((col.z + 1.0) + Q_SHIFT, 2.0) - 1.0) * Q_MUL;
+
+
+// Back to RGB
+    col = (crtgamut ==  3.0) ?        col                                       : \
+          (crtgamut ==  2.0) ?        col                                       : \
+          (crtgamut == -3.0) ? TVtoPC(col, 1.0, UVmax.x, UVmax.y, 1.0, false)   : \
+          (crtgamut == -4.0) ? TVtoPC(col, 1.0, UVmax.x, UVmax.y, 1.0, false)   : \
+                               TVtoPC(col, 1.0, UVmax.x, UVmax.y, 1.0, false)   ;
+
+    col = (crtgamut ==  3.0) ?     YUV_r601(col)    : \
+          (crtgamut ==  2.0) ?      YIQ_RGB(col)    : \
+          (crtgamut == -3.0) ?      FCC_RGB(col)    : \
+          (crtgamut == -4.0) ?      FCC_RGB(col)    : \
+                                    YIQ_RGB(col)    ;
+
+// Gamut Limiting
+    col = r601_YCC(clamp(col, 0.0, 1.0));
+    col = (signal == 0.0) ? gamma_fix : YCC_r601(clamp(col, vec3(0.0, -.886,-.700), vec3(1.0, .886,.700)));
+
+
+//_   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _   _
+// \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \
+
+
+// Look LUT - (in sRGB space)
+    float red =   (col.r * (LUT_Size1 - 1.0) + 0.4999) / (LUT_Size1 * LUT_Size1);
+    float green = (col.g * (LUT_Size1 - 1.0) + 0.4999) /  LUT_Size1;
+    float blue1 = (floor(col.b * (LUT_Size1 - 1.0)) / LUT_Size1) + red;
+    float blue2 =  (ceil(col.b * (LUT_Size1 - 1.0)) / LUT_Size1) + red;
+    float mixer = clamp(max((col.b - blue1) / (blue2 - blue1), 0.0), 0.0, 32.0);
+    vec3 color1 = COMPAT_TEXTURE(SamplerLUT1, vec2(blue1, green)).rgb;
+    vec3 color2 = COMPAT_TEXTURE(SamplerLUT1, vec2(blue2, green)).rgb;
+    vec3 vcolor = (LUT1_toggle == 0.0) ? col : mixfix(color1, color2, mixer);
+
+
+// OETF - Opto-Electronic Transfer Function (to linear in Digital Terms)
+    vcolor = moncurve_f_f3(vcolor, 2.20 + 0.20, 0.055);
+    vcolor = RGB_to_XYZ(vcolor, 0.);
+
+
+// Sigmoidal Contrast
+    vec3 Yxy = XYZtoYxy(vcolor);
+    float toGamma = clamp(moncurve_r(Yxy.r, 2.40, 0.055), 0.0, 1.0);
+    toGamma = (Yxy.r > 0.5) ? contrast_sigmoid_inv(toGamma, 2.3, 0.5) : toGamma;
+    float sigmoid = (cntrst > 0.0) ? contrast_sigmoid(toGamma, cntrst, mid) : contrast_sigmoid_inv(toGamma, cntrst, mid);
+    vec3 contrast = vec3(moncurve_f(sigmoid, 2.40, 0.055), Yxy.g, Yxy.b);
+    vec3 XYZsrgb = clamp(XYZ_to_RGB(YxytoXYZ(contrast), SPC), 0.0, 1.0);
+    contrast = (cntrst == 0.0) ? XYZ_to_RGB(vcolor, SPC) : XYZsrgb;
+
+
+// Vignetting & Black Level
+    vec2 vpos = vTexCoord * (TextureSize.xy / InputSize.xy);
+
+    vpos *= 1.0 - vpos.xy;
+    float vig = vpos.x * vpos.y * vstr;
+    vig = min(pow(vig, vpower), 1.0);
+    contrast *= (vignette == 1.0) ? vig : 1.0;
+
+    contrast += (lift / 20.0) * (1.0 - contrast);
+
+
+// RGB Related Transforms
+    vec4 screen = vec4(max(contrast, 0.0), 1.0);
+    float sat = g_sat + 1.0;
+
+                   //  r    g    b  alpha ; alpha does nothing for our purposes
+    mat4 color = mat4(wlr, rg,  rb,   0.0,              //red tint
+                      gr,  wlg, gb,   0.0,              //green tint
+                      br,  bg,  wlb,  0.0,              //blue tint
+                      blr/20., blg/20., blb/20., 0.0);  //black tint
+
+
+    vec3 coeff = (SPC == 3.0) ? vec3(0.29734000563621520, 0.62735998630523680,  0.07529000192880630) : \
+                 (SPC == 2.0) ? vec3(0.24840137362480164, 0.67799961566925050,  0.03913172334432602) : \
+                 (SPC == 1.0) ? vec3(0.22898375988006592, 0.69173991680145260,  0.07927616685628891) : \
+                                vec3(0.21264933049678802, 0.71516913175582890,  0.07218152284622192) ;
+
+
+    mat3 adjust = mat3((1.0 - sat) * coeff.x + sat, (1.0 - sat) * coeff.x,       (1.0 - sat) * coeff.x,
+                       (1.0 - sat) * coeff.y,       (1.0 - sat) * coeff.y + sat, (1.0 - sat) * coeff.y,
+                       (1.0 - sat) * coeff.z,       (1.0 - sat) * coeff.z,       (1.0 - sat) * coeff.z + sat);
+
+
+    screen = clamp(rolled_gain_v4(screen, clamp(lum, -0.49,0.99)), 0.0, 1.0);
+    screen = color * screen;
+
+//  HUE vs SAT
+    vec3 src_h = RGB_to_XYZ(screen.rgb, SPC) * LMS;
+    src_h.x = src_h.x >= 0.0 ? pow(src_h.x, 0.43) : -pow(-src_h.x, 0.43);
+    src_h.y = src_h.y >= 0.0 ? pow(src_h.y, 0.43) : -pow(-src_h.y, 0.43);
+    src_h.z = src_h.z >= 0.0 ? pow(src_h.z, 0.43) : -pow(-src_h.z, 0.43);
+
+    src_h.xyz *= IPT;
+
+    float hue_at = atan(src_h.z, src_h.y);
+    chroma = sqrt(src_h.z * src_h.z + src_h.y * src_h.y);
+
+    //  red -40º green 230º blue 100º
+    float hue_radians_r = -40.0 * (M_PI / 180.0);
+    float hue_r = clamp(chroma * cos(hue_at + hue_radians_r) * 2., 0.0, 1.0);
+
+    float hue_radians_g = 230.0 * (M_PI / 180.0);
+    float hue_g = clamp(chroma * cos(hue_at + hue_radians_g) * 2., 0.0, 1.0);
+
+    float hue_radians_b = 100.0 * (M_PI / 180.0);
+    float hue_b = clamp(chroma * cos(hue_at + hue_radians_b) * 2., 0.0, 1.0);
+
+    float msk = dot(vec3(hue_r, hue_g, hue_b), vec3(satr, satg, satb)*(-1.));
+    src_h = mixfix(screen.rgb, vec3(dot(coeff, screen.rgb)), msk);
+
+    float sat_msk = (vibr < 0.0) ? clamp(1.0 - abs(SatMask(src_h.x, src_h.y, src_h.z) - 1.0) * abs(vibr), 0.0, 1.0) : \
+                                   clamp(1.0 -    (SatMask(src_h.x, src_h.y, src_h.z) * vibr),            0.0, 1.0) ;
+
+    src_h = mixfix(src_h, clamp(adjust * src_h, 0.0, 1.0), sat_msk);
+
+
+// CRT Phosphor Gamut
+    mat3 m_in;
+
+    if (crtgamut == -4.0) { m_in = NTSC_FCC_transform;          } else
+    if (crtgamut == -3.0) { m_in = Conrac_transform;            } else
+    if (crtgamut == -2.0) { m_in = Sony20_20_transform;         } else
+    if (crtgamut == -1.0) { m_in = SMPTE_transform;             } else
+    if (crtgamut ==  1.0) { m_in = P22_transform;               } else
+    if (crtgamut ==  2.0) { m_in = NTSC_J_transform;            } else
+    if (crtgamut ==  3.0) { m_in = EBU_transform;               }
+
+    vec3 gamut = (crtgamut == -4.0) ? (m_in*src_h)*C_D65_Brad    : \
+                 (crtgamut == -3.0) ? (m_in*src_h)*C_D65_Brad    : \
+                 (crtgamut == -2.0) ? (m_in*src_h)*D93_D65_Brad  : \
+                 (crtgamut ==  2.0) ? (m_in*src_h)*D93_D65_Brad  : \
+                 (crtgamut ==  3.0) ? (m_in*src_h)*PAL_D65_Brad  : \
+                                       m_in*src_h;
+
+// White Point Mapping
+    vec3 wp       = wp_adjust(wp_temperature - 1000.);
+    vec3 base     = (crtgamut == 0.0) ? RGB_to_XYZ(src_h, SPC)      : gamut;
+         base     = XYZtoYxy(base);
+    vec3 adjusted = (crtgamut == 0.0) ? RGB_to_XYZ(src_h, SPC) * wp : gamut * wp;
+         adjusted = XYZtoYxy(adjusted);
+         adjusted = clamp(XYZ_to_RGB(YxytoXYZ(vec3(base.x , adjusted.y , adjusted.z)), SPC), 0.0, 1.0);
+
+
+// EOTF - Electro-Optical Transfer Function (Rec.709 does a Dim to Dark Surround adaptation)
+    vec3 TRC = (SPC == 3.0) ?     clamp(pow(adjusted,                  vec3(1./(563./256.))),    0., 1.) : \
+               (SPC == 2.0) ? moncurve_r_f3(adjusted,                           2.20 + 0.022222, 0.0993) : \
+               (SPC == 1.0) ?     clamp(pow(adjusted,                  vec3(1./(2.20 + 0.40))),  0., 1.) : \
+               (SPC == 0.0) ? moncurve_r_f3(adjusted,                           2.20 + 0.20,     0.0550) : \
+                              clamp(pow(pow(adjusted, vec3(1.019264)), vec3(1./(2.20 + 0.20))),  0., 1.) ;
+
+
+// Technical LUT - (in SPC space)
+    float red_2 =   (TRC.r * (LUT_Size2 - 1.0) + 0.4999) / (LUT_Size2 * LUT_Size2);
+    float green_2 = (TRC.g * (LUT_Size2 - 1.0) + 0.4999) / LUT_Size2;
+    float blue1_2 = (floor(TRC.b * (LUT_Size2 - 1.0)) / LUT_Size2) + red_2;
+    float blue2_2 =  (ceil(TRC.b * (LUT_Size2 - 1.0)) / LUT_Size2) + red_2;
+    float mixer_2 = clamp(max((TRC.b - blue1_2) / (blue2_2 - blue1_2), 0.0), 0.0, 32.0);
+    vec3 color1_2 = COMPAT_TEXTURE(SamplerLUT2, vec2(blue1_2, green_2)).rgb;
+    vec3 color2_2 = COMPAT_TEXTURE(SamplerLUT2, vec2(blue2_2, green_2)).rgb;
+    vec3 LUT2_output = mixfix(color1_2, color2_2, mixer_2);
+
+    LUT2_output = (LUT2_toggle == 0.0) ? TRC : LUT2_output;
+
+
+    FragColor = vec4(LUT2_output, 1.0);
+}
+#endif
diff --git a/base/misc/image-adjustment.glsl b/base/misc/image-adjustment.glsl
new file mode 100644
index 0000000..318976a
--- /dev/null
+++ b/base/misc/image-adjustment.glsl
@@ -0,0 +1,247 @@
+//   Image Adjustment
+//   Author: hunterk
+//   License: Public domain
+
+#pragma parameter ia_target_gamma "Target Gamma" 2.2 0.1 5.0 0.1
+#pragma parameter ia_monitor_gamma "Monitor Gamma" 2.2 0.1 5.0 0.1
+#pragma parameter ia_overscan_percent_x "Horizontal Overscan %" 0.0 -25.0 25.0 1.0
+#pragma parameter ia_overscan_percent_y "Vertical Overscan %" 0.0 -25.0 25.0 1.0
+#pragma parameter ia_saturation "Saturation" 1.0 0.0 5.0 0.1
+#pragma parameter ia_contrast "Contrast" 1.0 0.0 10.0 0.05
+#pragma parameter ia_luminance "Luminance" 1.0 0.0 2.0 0.1
+#pragma parameter ia_black_level "Black Level" 0.00 -0.30 0.30 0.01
+#pragma parameter ia_bright_boost "Brightness Boost" 0.0 -1.0 1.0 0.05
+#pragma parameter ia_R "Red Channel" 1.0 0.0 2.0 0.05
+#pragma parameter ia_G "Green Channel" 1.0 0.0 2.0 0.05
+#pragma parameter ia_B "Blue Channel" 1.0 0.0 2.0 0.05
+#pragma parameter ia_ZOOM "Zoom Factor" 1.0 0.0 4.0 0.01
+#pragma parameter ia_XPOS "X Modifier" 0.0 -2.0 2.0 0.005
+#pragma parameter ia_YPOS "Y Modifier" 0.0 -2.0 2.0 0.005
+#pragma parameter ia_TOPMASK "Overscan Mask Top" 0.0 0.0 1.0 0.0025
+#pragma parameter ia_BOTMASK "Overscan Mask Bottom" 0.0 0.0 1.0 0.0025
+#pragma parameter ia_LMASK "Overscan Mask Left" 0.0 0.0 1.0 0.0025
+#pragma parameter ia_RMASK "Overscan Mask Right" 0.0 0.0 1.0 0.0025
+#pragma parameter ia_GRAIN_STR "Film Grain" 0.0 0.0 72.0 6.0
+#pragma parameter ia_SHARPEN "Sharpen" 0.0 0.0 1.0 0.05
+#pragma parameter ia_FLIP_HORZ "Flip Horiz Axis" 0.0 0.0 1.0 1.0
+#pragma parameter ia_FLIP_VERT "Flip Vert Axis" 0.0 0.0 1.0 1.0
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying
+#define COMPAT_ATTRIBUTE attribute
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+// out variables go here as COMPAT_VARYING whatever
+
+vec4 _oPosition1;
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+// compatibility #defines
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+#ifdef PARAMETER_UNIFORM
+uniform COMPAT_PRECISION float ia_overscan_percent_x;
+uniform COMPAT_PRECISION float ia_overscan_percent_y;
+uniform COMPAT_PRECISION float ia_ZOOM;
+uniform COMPAT_PRECISION float ia_XPOS;
+uniform COMPAT_PRECISION float ia_YPOS;
+uniform COMPAT_PRECISION float ia_FLIP_HORZ;
+uniform COMPAT_PRECISION float ia_FLIP_VERT;
+#else
+#define ia_overscan_percent_x 0.0  // crop width of image by X%; default is 0.0
+#define ia_overscan_percent_y 0.0  // crop height of image by X%; default is 0.0
+#define ia_ZOOM 0.0                // zoom factor; default is 0.0
+#define ia_XPOS 0.0                // horizontal position modifier; default is 0.0
+#define ia_YPOS 0.0                // vertical position modifier; default is 0.0
+#define ia_FLIP_HORZ 0.0           // horizontal flip toggle; default is 0.0
+#define ia_FLIP_VERT 0.0           // vertical flip toggle; default is 0.0
+#endif
+
+void main()
+{
+   vec4 flip_pos = VertexCoord;
+   if (ia_FLIP_HORZ > 0.5) flip_pos.x = 1.0 - flip_pos.x;
+   if (ia_FLIP_VERT > 0.5) flip_pos.y = 1.0 - flip_pos.y;
+   gl_Position = MVPMatrix * flip_pos;
+   vec2 shift = (vec2(0.5) * InputSize) / TextureSize;
+   vec2 overscan_coord = ((TexCoord.xy - shift) / ia_ZOOM) * (1.0 - vec2(ia_overscan_percent_x / 100.0, ia_overscan_percent_y / 100.0)) + shift;
+   TEX0.xy = overscan_coord + vec2(ia_XPOS, ia_YPOS);
+}
+
+#elif defined(FRAGMENT)
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out COMPAT_PRECISION vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef PARAMETER_UNIFORM
+uniform COMPAT_PRECISION float ia_target_gamma;
+uniform COMPAT_PRECISION float ia_monitor_gamma;
+uniform COMPAT_PRECISION float ia_saturation;
+uniform COMPAT_PRECISION float ia_contrast;
+uniform COMPAT_PRECISION float ia_luminance;
+uniform COMPAT_PRECISION float ia_black_level;
+uniform COMPAT_PRECISION float ia_bright_boost;
+uniform COMPAT_PRECISION float ia_R;
+uniform COMPAT_PRECISION float ia_G;
+uniform COMPAT_PRECISION float ia_B;
+uniform COMPAT_PRECISION float ia_TOPMASK;
+uniform COMPAT_PRECISION float ia_BOTMASK;
+uniform COMPAT_PRECISION float ia_LMASK;
+uniform COMPAT_PRECISION float ia_RMASK;
+uniform COMPAT_PRECISION float ia_GRAIN_STR;
+uniform COMPAT_PRECISION float ia_SHARPEN;
+#else
+#define ia_target_gamma 2.2    // the gamma you want the image to have; CRT TVs typically have a gamma of 2.4
+#define ia_monitor_gamma 2.2   // gamma setting of your current display; LCD monitors typically have a gamma of 2.2
+#define ia_saturation 1.0      // color saturation; default 1.0
+#define ia_contrast 1.0        // image contrast; default 1.0
+#define ia_luminance 1.0       // image luminance; default 1.0
+#define ia_black_level 0.0     // black level; default 0.0
+#define ia_bright_boost 0.0    // adds to the total brightness. Negative values decrease it; Use values between 1.0 (totally white) and -1.0 (totally black); default is 0.0
+#define ia_R 1.0               // red level; default 1.0
+#define ia_G 1.0               // green level; default 1.0
+#define ia_B 1.0               // red level; default 1.0
+#define ia_TOPMASK 0.0         // mask top of image by X%; default is 0.0
+#define ia_BOTMASK 0.0         // mask bottom of image by X%; default is 0.0
+#define ia_LMASK 0.0           // mask left of image by X%; default is 0.0
+#define ia_RMASK 0.0           // mask right of image by X%; default is 0.0
+#define ia_GRAIN_STR 0.0       // grain filter strength; default is 0.0
+#define ia_SHARPEN 0.0         // sharpen filter strength; default is 0.0
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+// in variables go here as COMPAT_VARYING whatever
+
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+// texture(a, b) with COMPAT_TEXTURE(a, b) <-can't macro unfortunately
+
+vec3 rgb2hsv(vec3 c)
+{
+   vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
+   vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy);
+   vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx);
+
+   float d = q.x - min(q.w, q.y);
+   float e = 1.0e-10;
+   return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
+}
+
+vec3 hsv2rgb(vec3 c)
+{
+   vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
+   vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
+   return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
+}
+
+//https://www.shadertoy.com/view/4sXSWs strength= 16.0
+vec3 filmGrain(vec2 uv, float strength )
+{
+   float x = (uv.x + 4.0 ) * (uv.y + 4.0 ) * ((mod(vec2(FrameCount, FrameCount).x, 800.0) + 10.0) * 10.0);
+   return  vec3(mod((mod(x, 13.0) + 1.0) * (mod(x, 123.0) + 1.0), 0.01)-0.005) * strength;
+}
+
+// based on "Improved texture interpolation" by Iñigo Quílez
+// Original description: http://www.iquilezles.org/www/articles/texture/texture.htm
+vec3 sharp(sampler2D tex, vec2 texCoord)
+{
+   vec2 p = texCoord.xy;
+   p = p * SourceSize.xy + vec2(0.5, 0.5);
+   vec2 i = floor(p);
+   vec2 f = p - i;
+   f = f * f * f * (f * (f * 6.0 - vec2(15.0, 15.0)) + vec2(10.0, 10.0));
+   p = i + f;
+   p = (p - vec2(0.5, 0.5)) * SourceSize.zw;
+   return COMPAT_TEXTURE(tex, p).rgb;
+}
+
+
+void main()
+{
+   vec3 film_grain = filmGrain(vTexCoord, ia_GRAIN_STR);
+   vec3 res = COMPAT_TEXTURE(Source, vTexCoord).rgb; // sample the texture
+   res = mix(res, sharp(Source, vTexCoord), ia_SHARPEN) + film_grain; // add film grain and sharpness
+   vec3 gamma = vec3(ia_monitor_gamma / ia_target_gamma); // set up ratio of display's gamma vs desired gamma
+
+//saturation and luminance
+   vec3 satColor = clamp(hsv2rgb(rgb2hsv(res) * vec3(1.0, ia_saturation, ia_luminance)), 0.0, 1.0);
+
+//contrast and brightness
+   vec3 conColor = clamp((satColor - 0.5) * ia_contrast + 0.5 + ia_bright_boost, 0.0, 1.0);
+
+   conColor -= vec3(ia_black_level); // apply black level
+   conColor *= (vec3(1.0) / vec3(1.0-ia_black_level));
+   conColor = pow(conColor, 1.0 / vec3(gamma)); // Apply gamma correction
+   conColor *= vec3(ia_R, ia_G, ia_B);
+
+//overscan mask
+
+   vec2 FragCoord = (vTexCoord * TextureSize.xy / InputSize.xy); //needed for overscan mask to work properly
+
+   if (FragCoord.y > ia_TOPMASK && FragCoord.y < (1.0 - ia_BOTMASK))
+      conColor = conColor;
+   else
+      conColor = vec3(0.0);
+
+   if (FragCoord.x > ia_LMASK && FragCoord.x < (1.0 - ia_RMASK))
+      conColor = conColor;
+   else
+      conColor = vec3(0.0);
+
+   FragColor = vec4(conColor, 1.0);
+}
+#endif
diff --git a/base/misc/interlacing.glsl b/base/misc/interlacing.glsl
new file mode 100644
index 0000000..ae44363
--- /dev/null
+++ b/base/misc/interlacing.glsl
@@ -0,0 +1,122 @@
+/*
+   Interlacing
+   Author: hunterk
+   License: Public domain
+   
+   Note: This shader is designed to work with the typical interlaced output from an emulator, which displays both even and odd fields twice.
+   This shader will un-weave the image, resulting in a standard, alternating-field interlacing.
+*/
+
+#pragma parameter percent "Interlacing Scanline Bright %" 0.0 0.0 1.0 0.05
+#pragma parameter enable_480i "Enable 480i Mode" 1.0 0.0 1.0 1.0
+#pragma parameter top_field_first "Top Field First Enable" 0.0 0.0 1.0 1.0
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+ 
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+// compatibility #defines
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+void main()
+{
+   gl_Position = MVPMatrix * VertexCoord;
+   TEX0.xy = TexCoord.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out COMPAT_PRECISION vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+#ifdef PARAMETER_UNIFORM
+uniform COMPAT_PRECISION float percent;
+uniform COMPAT_PRECISION float enable_480i;
+uniform COMPAT_PRECISION float top_field_first;
+#else
+#define percent 0.0
+#define enable_480i 1.0
+#define top_field_first 0.0
+#endif
+
+void main()
+{
+   vec4 res = COMPAT_TEXTURE(Source, vTexCoord).rgba;
+   float y = 0.0;
+   float tick = float(FrameCount);
+
+   // assume anything with a vertical resolution greater than 400 lines is interlaced
+   if (InputSize.y > 400.0)
+   {y = TextureSize.y * vTexCoord.y + (tick * enable_480i) + top_field_first;}
+   else
+   {y = 2.000001 * TextureSize.y * vTexCoord.y + top_field_first;}
+
+   if (mod(y, 1.99999) > 0.99999)
+   {res = res;}
+   else
+   {res = vec4(percent) * res;}
+   FragColor = res;
+}
+#endif
diff --git a/base/misc/natural-vision.glsl b/base/misc/natural-vision.glsl
new file mode 100644
index 0000000..bdd9cf9
--- /dev/null
+++ b/base/misc/natural-vision.glsl
@@ -0,0 +1,136 @@
+/*
+   ShadX's Natural Vision Shader
+
+   Ported and tweaked by Hyllian - 2016
+   parameterized by Sp00kyFox
+
+*/
+
+#pragma parameter GIN	"NaturalVision Gamma In"	2.2 0.0 10.0 0.05
+#pragma parameter GOUT	"NaturalVision Gamma Out"	2.2 0.0 10.0 0.05
+#pragma parameter Y	"NaturalVision Luminance"	1.1 0.0 10.0 0.01
+#pragma parameter I	"NaturalVision Orange-Cyan"	1.1 0.0 10.0 0.01
+#pragma parameter Q	"NaturalVision Magenta-Green"	1.1 0.0 10.0 0.01
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+
+vec4 _oPosition1; 
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+// compatibility #defines
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    TEX0.xy = TexCoord.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+#ifdef PARAMETER_UNIFORM
+	uniform COMPAT_PRECISION float GIN;
+	uniform COMPAT_PRECISION float GOUT;
+	uniform COMPAT_PRECISION float Y;
+	uniform COMPAT_PRECISION float I;
+	uniform COMPAT_PRECISION float Q;
+#else
+	#define GIN	2.2
+	#define GOUT	2.2
+	#define Y	1.1
+	#define I	1.1
+	#define Q	1.1	
+#endif
+
+#define mul(a,b) (b*a)
+
+const mat3x3 RGBtoYIQ = mat3x3(0.299,     0.587,     0.114,
+					  0.595716, -0.274453, -0.321263,
+					  0.211456, -0.522591,  0.311135);
+
+const mat3x3 YIQtoRGB = mat3x3(1,  0.95629572,  0.62102442,
+					  1, -0.27212210, -0.64738060,
+					  1, -1.10698902,  1.70461500);
+
+const vec3 YIQ_lo = vec3(0, -0.595716, -0.522591);
+const vec3 YIQ_hi = vec3(1,  0.595716,  0.522591);
+
+void main()
+{
+	vec3 c = COMPAT_TEXTURE(Source, vTexCoord).xyz;
+
+	c = pow(c, vec3(GIN, GIN, GIN));
+	c = mul(RGBtoYIQ, c);
+	c = vec3(pow(c.x,Y), c.y*I, c.z*Q);
+	c = clamp(c, YIQ_lo, YIQ_hi);
+	c = mul(YIQtoRGB, c);
+	c = pow(c, vec3(1.0/GOUT, 1.0/GOUT, 1.0/GOUT));
+
+    FragColor = vec4(c, 1.0);
+} 
+#endif
diff --git a/base/misc/ntsc-colors.glsl b/base/misc/ntsc-colors.glsl
new file mode 100644
index 0000000..248c036
--- /dev/null
+++ b/base/misc/ntsc-colors.glsl
@@ -0,0 +1,159 @@
+// Parameter lines go here:
+#pragma parameter intensity "NTSC Intensity" 1.0 0.0 1.0 0.05
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+
+vec4 _oPosition1; 
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    COL0 = COLOR;
+    TEX0.xy = TexCoord.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutputSize vec4(OutputSize, 1.0 / OutputSize)
+
+#ifdef PARAMETER_UNIFORM
+// All parameter floats need to have COMPAT_PRECISION in front of them
+uniform COMPAT_PRECISION float intensity;
+#else
+#define intensity 1.0
+#endif
+
+vec3 DecodeGamma(vec3 color, float gamma)
+{
+    color = clamp(color, 0.0, 1.0);
+    color.r = (color.r <= 0.00313066844250063) ?
+    color.r * 12.92 : 1.055 * pow(color.r, 1.0 / gamma) - 0.055;
+    color.g = (color.g <= 0.00313066844250063) ?
+    color.g * 12.92 : 1.055 * pow(color.g, 1.0 / gamma) - 0.055;
+    color.b = (color.b <= 0.00313066844250063) ?
+    color.b * 12.92 : 1.055 * pow(color.b, 1.0 / gamma) - 0.055;
+
+    return color;
+}
+
+vec3 RGBtoXYZ(vec3 RGB)
+  {
+      mat3 m = mat3(
+      0.6068909, 0.1735011, 0.2003480,
+      0.2989164, 0.5865990, 0.1144845,
+      0.0000000, 0.0660957, 1.1162243);
+  
+    return RGB * m;
+  }
+
+vec3 XYZtoSRGB(vec3 XYZ)
+{
+    mat3 m = mat3(
+    3.2404542,-1.5371385,-0.4985314,
+   -0.9692660, 1.8760108, 0.0415560,
+    0.0556434,-0.2040259, 1.0572252);
+
+    return XYZ * m;
+  }
+
+vec3 XYZtoRGB(vec3 XYZ)
+  {
+      mat3 m = mat3(
+      1.9099961, -0.5324542, -0.2882091,
+     -0.9846663,  1.9991710, -0.0283082,
+      0.0583056, -0.1183781,  0.8975535);
+  
+    return XYZ * m;
+}
+
+// conversion from NTSC RGB Reference White D65 ( color space used by NA/Japan TV's ) to XYZ
+vec3 NTSC(vec3 c)
+ {
+     vec3 v = vec3(pow(c.r, 2.2), pow(c.g, 2.2), pow(c.b, 2.2)); //Inverse Companding
+     return RGBtoXYZ(v);
+ }
+ 
+// conversion from XYZ to sRGB Reference White D65 ( color space used by windows ) 
+vec3 sRGB(vec3 c)
+ {
+     vec3 v = XYZtoSRGB(c);
+     v = DecodeGamma(v, 2.4); //Companding
+ 
+     return v;
+ }
+
+// NTSC RGB to sRGB
+vec3 NTSCtoSRGB( vec3 c )
+ { 
+     return sRGB(NTSC( c )); 
+ }
+
+void main()
+{
+     vec3 color = COMPAT_TEXTURE(Source, vTexCoord).rgb;
+     color = mix(color.rgb, NTSCtoSRGB(color.rgb), intensity);
+   FragColor = vec4(color, 1.0);
+} 
+#endif
diff --git a/base/misc/white_point.glsl b/base/misc/white_point.glsl
new file mode 100644
index 0000000..fb32893
--- /dev/null
+++ b/base/misc/white_point.glsl
@@ -0,0 +1,214 @@
+// White Point Mapping
+//          ported by Dogway
+//
+// From the first comment post (sRGB primaries and linear light compensated)
+//      http://www.zombieprototypes.com/?p=210#comment-4695029660
+// Based on the Neil Bartlett's blog update
+//      http://www.zombieprototypes.com/?p=210
+// Inspired itself by Tanner Helland's work
+//      http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/
+
+
+#pragma parameter temperature "White Point" 9311.0 1031.0 12047.0 72.0
+#pragma parameter luma_preserve "Preserve Luminance" 1.0 0.0 1.0 1.0
+#pragma parameter wp_red "Red Shift" 0.0 -1.0 1.0 0.01
+#pragma parameter wp_green "Green Shift" 0.0 -1.0 1.0 0.01
+#pragma parameter wp_blue "Blue Shift" 0.0 -1.0 1.0 0.01
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying
+#define COMPAT_ATTRIBUTE attribute
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+
+vec4 _oPosition1;
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+// compatibility #defines
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    TEX0.xy = TexCoord.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out COMPAT_PRECISION vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutSize vec4(OutputSize, 1.0 / OutputSize)
+
+#ifdef PARAMETER_UNIFORM
+uniform COMPAT_PRECISION float temperature, luma_preserve, red, green, blue;
+#else
+#define temperature 9311.0
+#define luma_preserve 1.0
+#define wp_red 0.0
+#define wp_green 0.0
+#define wp_blue 0.0
+#endif
+
+
+vec3 wp_adjust(vec3 color){
+
+    float temp = temperature / 100.;
+    float k = temperature / 10000.;
+    float lk = log(k);
+
+    vec3 wp = vec3(1.);
+
+    // calculate RED
+    wp.r = (temp <= 65.) ? 1. : 0.32068362618584273 + (0.19668730877673762 * pow(k - 0.21298613432655075, - 1.5139012907556737)) + (- 0.013883432789258415 * lk);
+
+    // calculate GREEN
+    float mg = 1.226916242502167 + (- 1.3109482654223614 * pow(k - 0.44267061967913873, 3.) * exp(- 5.089297600846147 * (k - 0.44267061967913873))) + (0.6453936305542096 * lk);
+    float pg = 0.4860175851734596 + (0.1802139719519286 * pow(k - 0.14573069517701578, - 1.397716496795082)) + (- 0.00803698899233844 * lk);
+    wp.g = (temp <= 65.5) ? ((temp <= 8.) ? 0. : mg) : pg;
+
+    // calculate BLUE
+    wp.b = (temp <= 19.) ? 0. : (temp >= 66.) ? 1. : 1.677499032830161 + (- 0.02313594016938082 * pow(k - 1.1367244820333684, 3.) * exp(- 4.221279555918655 * (k - 1.1367244820333684))) + (1.6550275798913296 * lk);
+
+    // clamp
+    wp.rgb = clamp(wp.rgb, vec3(0.), vec3(1.));
+
+    // R/G/B independent manual White Point adjustment
+    wp.rgb += vec3(wp_red, wp_green, wp_blue);
+
+    // Linear color input
+    return color * wp;
+}
+
+vec3 sRGB_to_XYZ(vec3 RGB){
+
+    const mat3x3 m = mat3x3(
+    0.4124564,  0.3575761,  0.1804375,
+    0.2126729,  0.7151522,  0.0721750,
+    0.0193339,  0.1191920,  0.9503041);
+    return RGB * m;
+}
+
+
+vec3 XYZtoYxy(vec3 XYZ){
+
+    float XYZrgb = XYZ.r+XYZ.g+XYZ.b;
+    float Yxyr = XYZ.g;
+    float Yxyg = (XYZrgb <= 0.0) ? 0.3805 : XYZ.r / XYZrgb;
+    float Yxyb = (XYZrgb <= 0.0) ? 0.3769 : XYZ.g / XYZrgb;
+    return vec3(Yxyr,Yxyg,Yxyb);
+}
+
+vec3 XYZ_to_sRGB(vec3 XYZ){
+
+    const mat3x3 m = mat3x3(
+    3.2404542, -1.5371385, -0.4985314,
+   -0.9692660,  1.8760108,  0.0415560,
+    0.0556434, -0.2040259,  1.0572252);
+    return XYZ * m;
+}
+
+
+vec3 YxytoXYZ(vec3 Yxy){
+
+    float Xs = Yxy.r * (Yxy.g/Yxy.b);
+    float Xsz = (Yxy.r <= 0.0) ? 0 : 1;
+    vec3 XYZ = vec3(Xsz,Xsz,Xsz) * vec3(Xs, Yxy.r, (Xs/Yxy.g)-Xs-Yxy.r);
+    return XYZ;
+}
+
+
+vec3 linear_to_sRGB(vec3 color, float gamma){
+
+    color = clamp(color, 0.0, 1.0);
+    color.r = (color.r <= 0.00313066844250063) ?
+    color.r * 12.92 : 1.055 * pow(color.r, 1.0 / gamma) - 0.055;
+    color.g = (color.g <= 0.00313066844250063) ?
+    color.g * 12.92 : 1.055 * pow(color.g, 1.0 / gamma) - 0.055;
+    color.b = (color.b <= 0.00313066844250063) ?
+    color.b * 12.92 : 1.055 * pow(color.b, 1.0 / gamma) - 0.055;
+
+    return color.rgb;
+}
+
+
+vec3 sRGB_to_linear(vec3 color, float gamma){
+
+    color = clamp(color, 0.0, 1.0);
+    color.r = (color.r <= 0.04045) ?
+    color.r / 12.92 : pow((color.r + 0.055) / (1.055), gamma);
+    color.g = (color.g <= 0.04045) ?
+    color.g / 12.92 : pow((color.g + 0.055) / (1.055), gamma);
+    color.b = (color.b <= 0.04045) ?
+    color.b / 12.92 : pow((color.b + 0.055) / (1.055), gamma);
+
+    return color.rgb;
+}
+
+
+void main()
+{
+   vec3 original = sRGB_to_linear(COMPAT_TEXTURE(Source, vTexCoord).rgb, 2.40);
+   vec3 adjusted = wp_adjust(original);
+   vec3 base_luma = XYZtoYxy(sRGB_to_XYZ(original));
+   vec3 adjusted_luma = XYZtoYxy(sRGB_to_XYZ(adjusted));
+   adjusted = (luma_preserve == 1.0) ? adjusted_luma + (vec3(base_luma.r,0.,0.) - vec3(adjusted_luma.r,0.,0.)) : adjusted_luma;
+   FragColor = vec4(linear_to_sRGB(XYZ_to_sRGB(YxytoXYZ(adjusted)), 2.40), 1.0);
+}
+#endif
diff --git a/base/xbr/2xBR-lv1-multipass.glslp b/base/xbr/2xBR-lv1-multipass.glslp
new file mode 100644
index 0000000..fda0777
--- /dev/null
+++ b/base/xbr/2xBR-lv1-multipass.glslp
@@ -0,0 +1,8 @@
+shaders = 2
+
+shader0 = "shaders/2xBR-multipass/2xbr-lv1-c-pass0.glsl"
+filter_linear0 = false
+scale_type0 = source
+
+shader1 = "shaders/2xBR-multipass/2xbr-lv1-c-pass1.glsl"
+filter_linear1 = false
\ No newline at end of file
diff --git a/base/xbr/shaders/2xBR-multipass/2xbr-lv1-c-pass0.glsl b/base/xbr/shaders/2xBR-multipass/2xbr-lv1-c-pass0.glsl
new file mode 100644
index 0000000..4543f7f
--- /dev/null
+++ b/base/xbr/shaders/2xBR-multipass/2xbr-lv1-c-pass0.glsl
@@ -0,0 +1,223 @@
+#version 130
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+COMPAT_VARYING vec4 t1;
+COMPAT_VARYING vec4 t2;
+COMPAT_VARYING vec4 t3;
+COMPAT_VARYING vec4 t4;
+COMPAT_VARYING vec4 t5;
+COMPAT_VARYING vec4 t6;
+COMPAT_VARYING vec4 t7;
+
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+// vertex compatibility #defines
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define outsize vec4(OutputSize, 1.0 / OutputSize)
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    COL0 = COLOR;
+    TEX0.xy = TexCoord.xy;
+   //     A1 B1 C1
+   //  A0  A  B  C C4
+   //  D0  D  E  F F4
+   //  G0  G  H  I I4
+   //     G5 H5 I5
+   
+   float dx = SourceSize.z;
+   float dy = SourceSize.w;
+  
+   t1 = TEX0.xxxy + vec4(    -dx,   0,  dx, -2.0*dy);  //  A1 B1 C1
+   t2 = TEX0.xxxy + vec4(    -dx,   0,  dx,     -dy);  //   A  B  C
+   t3 = TEX0.xxxy + vec4(    -dx,   0,  dx,       0);  //   D  E  F
+   t4 = TEX0.xxxy + vec4(    -dx,   0,  dx,      dy);  //   G  H  I
+   t5 = TEX0.xxxy + vec4(    -dx,   0,  dx,  2.0*dy);  //  G5 H5 I5
+   t6 = TEX0.xyyy + vec4(-2.0*dx, -dy,   0,      dy);  //  A0 D0 G0
+   t7 = TEX0.xyyy + vec4( 2.0*dx, -dy,   0,      dy);  //  C4 F4 I4
+}
+
+#elif defined(FRAGMENT)
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out COMPAT_PRECISION vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+COMPAT_VARYING vec4 t1;
+COMPAT_VARYING vec4 t2;
+COMPAT_VARYING vec4 t3;
+COMPAT_VARYING vec4 t4;
+COMPAT_VARYING vec4 t5;
+COMPAT_VARYING vec4 t6;
+COMPAT_VARYING vec4 t7;
+
+// fragment compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define outsize vec4(OutputSize, 1.0 / OutputSize)
+
+float threshold = 15.0;
+
+float y_weight = 48.0;
+float u_weight = 7.0;
+float v_weight = 6.0;
+
+mat3 yuv          = mat3(0.299, 0.587, 0.114, -0.169, -0.331, 0.499, 0.499, -0.418, -0.0813);
+mat3 yuv_weighted = mat3(14.352, 28.176, 5.472, -1.183, -2.317, 3.493, 2.994, 2.508, -0.4878);
+vec4 bin          = vec4(1.0, 2.0, 4.0, 8.0);
+vec4 maximo       = vec4(255.0, 255.0, 255.0, 255.0);
+
+bvec4 _and_(bvec4 A, bvec4 B) {
+   return bvec4(A.x && B.x, A.y && B.y, A.z && B.z, A.w && B.w);
+}
+
+bvec4 _or_(bvec4 A, bvec4 B) {
+   return bvec4(A.x || B.x, A.y || B.y, A.z || B.z, A.w || B.w);
+}
+
+vec4 df(vec4 A, vec4 B) {
+   return vec4(abs(A - B));
+}
+
+bvec4 close(vec4 A, vec4 B) {
+   return (lessThan(df(A, B), vec4(threshold)));
+}
+
+vec4 weighted_distance(vec4 a, vec4 b, vec4 c, vec4 d, vec4 e, vec4 f, vec4 g, vec4 h) {
+   return (df(a, b) + df(a, c) + df(d, e) + df(d, f) + 4.0 * df(g, h));
+}
+
+vec4 remapTo01(vec4 v, vec4 high) {
+   return (v/high);
+}
+
+void main()
+{
+   bvec4 edr, px; // px = pixel, edr = edge detection rule
+   bvec4 interp_restriction_lv1;
+
+   vec3 A1 = COMPAT_TEXTURE(Source, t1.xw).rgb;
+   vec3 B1 = COMPAT_TEXTURE(Source, t1.yw).rgb;
+   vec3 C1 = COMPAT_TEXTURE(Source, t1.zw).rgb;
+
+   vec3 A  = COMPAT_TEXTURE(Source, t2.xw).rgb;
+   vec3 B  = COMPAT_TEXTURE(Source, t2.yw).rgb;
+   vec3 C  = COMPAT_TEXTURE(Source, t2.zw).rgb;
+
+   vec3 D  = COMPAT_TEXTURE(Source, t3.xw).rgb;
+   vec3 E  = COMPAT_TEXTURE(Source, t3.yw).rgb;
+   vec3 F  = COMPAT_TEXTURE(Source, t3.zw).rgb;
+
+   vec3 G  = COMPAT_TEXTURE(Source, t4.xw).rgb;
+   vec3 H  = COMPAT_TEXTURE(Source, t4.yw).rgb;
+   vec3 I  = COMPAT_TEXTURE(Source, t4.zw).rgb;
+
+   vec3 G5 = COMPAT_TEXTURE(Source, t5.xw).rgb;
+   vec3 H5 = COMPAT_TEXTURE(Source, t5.yw).rgb;
+   vec3 I5 = COMPAT_TEXTURE(Source, t5.zw).rgb;
+
+   vec3 A0 = COMPAT_TEXTURE(Source, t6.xy).rgb;
+   vec3 D0 = COMPAT_TEXTURE(Source, t6.xz).rgb;
+   vec3 G0 = COMPAT_TEXTURE(Source, t6.xw).rgb;
+
+   vec3 C4 = COMPAT_TEXTURE(Source, t7.xy).rgb;
+   vec3 F4 = COMPAT_TEXTURE(Source, t7.xz).rgb;
+   vec3 I4 = COMPAT_TEXTURE(Source, t7.xw).rgb;
+
+   vec4 bdhf = yuv_weighted[0]*mat4x3( B,  D,  H,  F);
+   vec4 cagi = yuv_weighted[0]*mat4x3( C,  A,  G,  I);
+   vec4 e    = yuv_weighted[0]*mat4x3( E,  E,  E,  E);
+   vec4 i4   = yuv_weighted[0]*mat4x3(I4, C4, A0, G0);
+   vec4 i5   = yuv_weighted[0]*mat4x3(I5, C1, A1, G5);
+   vec4 h5x  = yuv_weighted[0]*mat4x3(H5, F4, B1, D0);
+
+   vec4 b = bdhf.xzzx;
+   vec4 d = bdhf.yyww;
+   vec4 h = bdhf.zxxz;
+   vec4 f = bdhf.wwyy;
+   vec4 c = cagi.xwzy;
+   vec4 a = cagi.yzwx;
+   vec4 g = cagi.zyxw;
+   vec4 i = cagi.wxyz;
+
+   vec4 f4 = h5x.yyww;
+   vec4 h5 = h5x.xzzx;
+
+   bvec4 r1 = _and_( notEqual(  e,  f ), notEqual( e,  h ) );
+   bvec4 r2 = _and_( not(close( f,  b)), not(close(f,  c)) );
+   bvec4 r3 = _and_( not(close( h,  d)), not(close(h,  g)) );
+   bvec4 r4 = _and_( not(close( f, f4)), not(close(f, i4)) );
+   bvec4 r5 = _and_( not(close( h, h5)), not(close(h, i5)) );
+   bvec4 r6 = _and_( close(e, i),  _or_(r4, r5) );
+   bvec4 r7 =  _or_( close(e, g), close( e,  c) );
+
+   interp_restriction_lv1 = _and_( r1, _or_( _or_( _or_(r2, r3), r6 ), r7 ) );
+
+   edr = _and_( lessThan(weighted_distance(e, c, g, i, h5, f4, h, f), weighted_distance(h, d, i5, f, i4, b, e, i)), interp_restriction_lv1 );
+
+   px  = lessThanEqual(df(e, f), df(e, h));
+
+   vec4 info = bin*mat4(
+                          edr.x, px.x, 0.0, 0.0,
+                          edr.y, px.y, 0.0, 0.0,
+                          edr.z, px.z, 0.0, 0.0,
+                          edr.w, px.w, 0.0, 0.0
+                          );
+   FragColor = vec4(remapTo01(info, maximo));
+} 
+#endif
diff --git a/base/xbr/shaders/2xBR-multipass/2xbr-lv1-c-pass1.glsl b/base/xbr/shaders/2xBR-multipass/2xbr-lv1-c-pass1.glsl
new file mode 100644
index 0000000..4639466
--- /dev/null
+++ b/base/xbr/shaders/2xBR-multipass/2xbr-lv1-c-pass1.glsl
@@ -0,0 +1,146 @@
+#version 130
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+COMPAT_VARYING vec4 t1;
+
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+// vertex compatibility #defines
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define outsize vec4(OutputSize, 1.0 / OutputSize)
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    COL0 = COLOR;
+    TEX0.xy = TexCoord.xy;
+   //     A1 B1 C1
+   //  A0  A  B  C C4
+   //  D0  D  E  F F4
+   //  G0  G  H  I I4
+   //     G5 H5 I5
+
+   float dx = SourceSize.z;
+   float dy = SourceSize.w;
+   
+   t1 = vec4(dx, 0, 0, dy);  // F H
+}
+
+#elif defined(FRAGMENT)
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out COMPAT_PRECISION vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+uniform sampler2D OrigTexture;
+uniform COMPAT_PRECISION vec2 OrigTextureSize;
+COMPAT_VARYING vec4 TEX0;
+COMPAT_VARYING vec4 t1;
+
+// fragment compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define outsize vec4(OutputSize, 1.0 / OutputSize)
+
+#define OriginalSize vec4(OrigTextureSize, 1.0 / OrigTextureSize)
+#define Original OrigTexture
+
+mat4x2 sym_vectors  = mat4x2(1.,  1.,   1., -1.,   -1., -1.,   -1.,  1.);
+
+float remapFrom01(float v, float high)
+{
+   return (high*v + 0.5);
+}
+
+vec2 unpack_info(float i)
+{
+   vec2 info;
+   info.x = round(modf(i/2.0, i));
+   info.y = i;
+
+   return info;
+}
+
+void main()
+{
+//get original texture coordinates relative to the current pass
+   vec2 OriginalCoord = floor(OriginalSize.xy * vTexCoord);
+   OriginalCoord = (OriginalCoord + 0.5) * OriginalSize.zw;
+   
+   float px, edr; // px = pixel to blend, edr = edge detection rule
+
+   vec2 pos = fract(vTexCoord*SourceSize.xy)-vec2(0.5, 0.5); // pos = pixel position
+   vec2 dir = sign(pos); // dir = pixel direction
+
+   vec2 g1  = dir*t1.xy;
+   vec2 g2  = dir*t1.zw;
+
+   vec3 F   = COMPAT_TEXTURE(Original, OriginalCoord +g1).rgb;
+   vec3 H   = COMPAT_TEXTURE(Original, OriginalCoord +g2).rgb;
+   vec3 E   = COMPAT_TEXTURE(Original, OriginalCoord    ).rgb;
+
+   vec4 icomp = round(clamp(dir*sym_vectors, vec4(0.0), vec4(1.0))); // choose info component
+   float  info  = remapFrom01(dot(COMPAT_TEXTURE(Source, vTexCoord), icomp), 255.0f); // retrieve 1st pass info
+   vec2 flags = unpack_info(info); // retrieve 1st pass flags
+
+   edr = flags.x;
+   px  = flags.y;
+
+   vec3 color = mix(E, mix(H, F, px), edr*0.5); // interpolate if there's edge
+   
+   FragColor = vec4(color, 1.0);
+} 
+#endif
diff --git a/base/xbr/shaders/super-xbr/custom-jinc2-sharper.glsl b/base/xbr/shaders/super-xbr/custom-jinc2-sharper.glsl
new file mode 100644
index 0000000..58a56d0
--- /dev/null
+++ b/base/xbr/shaders/super-xbr/custom-jinc2-sharper.glsl
@@ -0,0 +1,240 @@
+#version 130
+
+/*
+   Hyllian's jinc windowed-jinc 2-lobe sharper with anti-ringing Shader
+   
+   Copyright (C) 2011-2014 Hyllian/Jararaca - sergiogdb at gmail.com
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   as published by the Free Software Foundation; either version 2
+   of the License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+// Parameter lines go here:
+#pragma parameter JINC2_WINDOW_SINC "Window Sinc Param" 0.42 0.0 1.0 0.01
+#pragma parameter JINC2_SINC "Sinc Param" 0.92 0.0 1.0 0.01
+#pragma parameter JINC2_AR_STRENGTH "Anti-ringing Strength" 1.0 0.0 1.0 0.1
+
+#define mul(a,b) (b*a)
+
+      /*
+         This is an approximation of Jinc(x)*Jinc(x*r1/r2) for x < 2.5,
+         where r1 and r2 are the first two zeros of jinc function.
+         For a jinc 2-lobe best approximation, use A=0.5 and B=0.825.
+      */  
+
+// A=0.5, B=0.825 is the best jinc approximation for x<2.5. if B=1.0, it's a lanczos filter.
+// Increase A to get more blur. Decrease it to get a sharper picture. 
+// B = 0.825 to get rid of dithering. Increase B to get a fine sharpness, though dithering returns.
+
+#define halfpi  1.5707963267948966192313216916398
+#define pi    3.1415926535897932384626433832795
+#define wa    (JINC2_WINDOW_SINC*pi)
+#define wb    (JINC2_SINC*pi)
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 COLOR;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 COL0;
+COMPAT_VARYING vec4 TEX0;
+
+vec4 _oPosition1; 
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    COL0 = COLOR;
+    TEX0.xy = TexCoord.xy * 1.0001;
+}
+
+#elif defined(FRAGMENT)
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out COMPAT_PRECISION vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutputSize vec4(OutputSize, 1.0 / OutputSize)
+
+#ifdef PARAMETER_UNIFORM
+uniform COMPAT_PRECISION float JINC2_WINDOW_SINC;
+uniform COMPAT_PRECISION float JINC2_SINC;
+uniform COMPAT_PRECISION float JINC2_AR_STRENGTH;
+#else
+#define JINC2_WINDOW_SINC 0.42
+#define JINC2_SINC 0.92
+#define JINC2_AR_STRENGTH 1.0
+#endif
+
+const vec3 Y = vec3(0.299, 0.587, 0.114);
+
+float df(float A, float B)
+{
+	return abs(A-B);
+}
+
+// Calculates the distance between two points
+float d(vec2 pt1, vec2 pt2)
+{
+  vec2 v = pt2 - pt1;
+  return sqrt(dot(v,v));
+}
+
+vec3 min4(vec3 a, vec3 b, vec3 c, vec3 d)
+{
+    return min(a, min(b, min(c, d)));
+}
+vec3 max4(vec3 a, vec3 b, vec3 c, vec3 d)
+{
+    return max(a, max(b, max(c, d)));
+}
+
+vec4 resampler(vec4 x)
+{
+	vec4 res;
+	res.x = (x.x==0.0) ?  wa*wb  :  sin(x.x*wa)*sin(x.x*wb)/(x.x*x.x);
+	res.y = (x.y==0.0) ?  wa*wb  :  sin(x.y*wa)*sin(x.y*wb)/(x.y*x.y);
+	res.z = (x.z==0.0) ?  wa*wb  :  sin(x.z*wa)*sin(x.z*wb)/(x.z*x.z);
+	res.w = (x.w==0.0) ?  wa*wb  :  sin(x.w*wa)*sin(x.w*wb)/(x.w*x.w);
+	return res;
+}
+
+void main()
+{
+      vec3 color;
+      mat4x4 weights;
+
+      vec2 dx = vec2(1.0, 0.0);
+      vec2 dy = vec2(0.0, 1.0);
+
+      vec2 pc = vTexCoord * SourceSize.xy;
+
+      vec2 tc = (floor(pc-vec2(0.5,0.5))+vec2(0.5,0.5));
+     
+      weights[0] = resampler(vec4(d(pc, tc    -dx    -dy), d(pc, tc           -dy), d(pc, tc    +dx    -dy), d(pc, tc+2.0*dx    -dy)));
+      weights[1] = resampler(vec4(d(pc, tc    -dx       ), d(pc, tc              ), d(pc, tc    +dx       ), d(pc, tc+2.0*dx       )));
+      weights[2] = resampler(vec4(d(pc, tc    -dx    +dy), d(pc, tc           +dy), d(pc, tc    +dx    +dy), d(pc, tc+2.0*dx    +dy)));
+      weights[3] = resampler(vec4(d(pc, tc    -dx+2.0*dy), d(pc, tc       +2.0*dy), d(pc, tc    +dx+2.0*dy), d(pc, tc+2.0*dx+2.0*dy)));
+
+      //weights[0][0] = weights[0][3] = weights[3][0] = weights[3][3] = 0.0;
+
+      dx = dx / SourceSize.xy;
+      dy = dy / SourceSize.xy;
+      tc = tc / SourceSize.xy;
+     
+     // reading the texels
+     
+      vec3 c00 = COMPAT_TEXTURE(Source, tc    -dx    -dy).xyz;
+      vec3 c10 = COMPAT_TEXTURE(Source, tc           -dy).xyz;
+      vec3 c20 = COMPAT_TEXTURE(Source, tc    +dx    -dy).xyz;
+      vec3 c30 = COMPAT_TEXTURE(Source, tc+2.0*dx    -dy).xyz;
+      vec3 c01 = COMPAT_TEXTURE(Source, tc    -dx       ).xyz;
+      vec3 c11 = COMPAT_TEXTURE(Source, tc              ).xyz;
+      vec3 c21 = COMPAT_TEXTURE(Source, tc    +dx       ).xyz;
+      vec3 c31 = COMPAT_TEXTURE(Source, tc+2.0*dx       ).xyz;
+      vec3 c02 = COMPAT_TEXTURE(Source, tc    -dx    +dy).xyz;
+      vec3 c12 = COMPAT_TEXTURE(Source, tc           +dy).xyz;
+      vec3 c22 = COMPAT_TEXTURE(Source, tc    +dx    +dy).xyz;
+      vec3 c32 = COMPAT_TEXTURE(Source, tc+2.0*dx    +dy).xyz;
+      vec3 c03 = COMPAT_TEXTURE(Source, tc    -dx+2.0*dy).xyz;
+      vec3 c13 = COMPAT_TEXTURE(Source, tc       +2.0*dy).xyz;
+      vec3 c23 = COMPAT_TEXTURE(Source, tc    +dx+2.0*dy).xyz;
+      vec3 c33 = COMPAT_TEXTURE(Source, tc+2.0*dx+2.0*dy).xyz;
+
+
+
+      color = mul(weights[0], mat4x3(c00, c10, c20, c30));
+      color+= mul(weights[1], mat4x3(c01, c11, c21, c31));
+      color+= mul(weights[2], mat4x3(c02, c12, c22, c32));
+      color+= mul(weights[3], mat4x3(c03, c13, c23, c33));
+      color = color/(dot(mul(weights, vec4(1.)), vec4(1.)));
+
+
+
+      // Anti-ringing
+      //  Get min/max samples
+      pc = vTexCoord;
+      c00 = COMPAT_TEXTURE(Source, pc              ).xyz;
+      c11 = COMPAT_TEXTURE(Source, pc    +dx       ).xyz;
+      c21 = COMPAT_TEXTURE(Source, pc    -dx       ).xyz;
+      c12 = COMPAT_TEXTURE(Source, pc           +dy).xyz;
+      c22 = COMPAT_TEXTURE(Source, pc           -dy).xyz;
+
+
+      vec3 min_sample = min4(c11, c21, c12, c22);
+      vec3 max_sample = max4(c11, c21, c12, c22);
+	min_sample = min(min_sample, c00);
+	max_sample = max(max_sample, c00);
+
+      vec3 aux = color;
+
+        color = clamp(color, min_sample, max_sample);
+        color = mix(aux, color, JINC2_AR_STRENGTH);
+
+   FragColor = vec4(color, 1.);
+} 
+#endif
diff --git a/base/xbr/shaders/super-xbr/super-2xbr-3d-pass0.glsl b/base/xbr/shaders/super-xbr/super-2xbr-3d-pass0.glsl
new file mode 100644
index 0000000..039967c
--- /dev/null
+++ b/base/xbr/shaders/super-xbr/super-2xbr-3d-pass0.glsl
@@ -0,0 +1,305 @@
+#version 130
+
+/*
+   
+  *******  Super XBR 3D Shader - pass0  *******
+   
+  Copyright (c) 2016 Hyllian - sergiogdb at gmail.com
+
+  Permission is hereby granted, free of charge, to any person obtaining a copy
+  of this software and associated documentation files (the "Software"), to deal
+  in the Software without restriction, including without limitation the rights
+  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+  copies of the Software, and to permit persons to whom the Software is
+  furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included in
+  all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+  THE SOFTWARE.
+
+*/
+
+// Parameter lines go here:
+#pragma parameter XBR_EDGE_STR "Xbr - Edge Strength p0" 0.6 0.0 5.0 0.5
+#pragma parameter XBR_WEIGHT "Xbr - Filter Weight" 1.0 0.00 1.50 0.05
+#pragma parameter XBR_ANTI_RINGING "Xbr - Anti-Ringing Level" 1.0 0.0 1.0 1.0
+
+#define mul(a,b) (b*a)
+
+#define XBR_RES 2.0
+
+#define wp1  2.0
+#define wp2  1.0
+#define wp3 -1.0
+#define wp4  4.0
+#define wp5 -1.0
+#define wp6  1.0
+
+#define weight1 (XBR_WEIGHT*1.29633/10.0)
+#define weight2 (XBR_WEIGHT*1.75068/10.0/2.0)
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 TEX0;
+
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    TEX0.xy = TexCoord.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out COMPAT_PRECISION vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutputSize vec4(OutputSize, 1.0 / OutputSize)
+
+#ifdef PARAMETER_UNIFORM
+uniform COMPAT_PRECISION float XBR_EDGE_STR;
+uniform COMPAT_PRECISION float XBR_WEIGHT;
+uniform COMPAT_PRECISION float XBR_ANTI_RINGING;
+#else
+#define XBR_EDGE_STR 0.6
+#define XBR_WEIGHT 1.0
+#define XBR_ANTI_RINGING 1.0
+#endif
+
+const vec3 Y = vec3(.2126, .7152, .0722);
+
+const vec3 dtt = vec3(65536.,255.,1.);
+
+vec4 reduce4(vec3 A, vec3 B, vec3 C, vec3 D)
+{
+  return mul(mat4x3(A, B, C, D), dtt);
+}
+
+float RGBtoYUV(vec3 color)
+{
+  return dot(color, Y);
+}
+
+float df(float A, float B)
+{
+  return abs(A-B);
+}
+
+bool eq(float A, float B)
+{
+	return (df(A, B) < 15.0);
+}
+
+/*
+                              P1
+     |P0|B |C |P1|         C     F4          |a0|b1|c2|d3|
+     |D |E |F |F4|      B     F     I4       |b0|c1|d2|e3|   |e1|i1|i2|e2|
+     |G |H |I |I4|   P0    E  A  I     P3    |c0|d1|e2|f3|   |e3|i3|i4|e4|
+     |P2|H5|I5|P3|      D     H     I5       |d0|e1|f2|g3|
+                           G     H5
+                              P2
+*/
+
+
+float d_wd(float b0, float b1, float c0, float c1, float c2, float d0, float d1, float d2, float d3, float e1, float e2, float e3, float f2, float f3)
+{
+	return (wp1*(df(c1,c2) + df(c1,c0) + df(e2,e1) + df(e2,e3)) + wp2*(df(d2,d3) + df(d0,d1)) + wp3*(df(d1,d3) + df(d0,d2)) + wp4*df(d1,d2) + wp5*(df(c0,c2) + df(e1,e3)) + wp6*(df(b0,b1) + df(f2,f3)));
+}
+
+float hv_wd(float i1, float i2, float i3, float i4, float e1, float e2, float e3, float e4)
+{
+	return ( wp4*(df(i1,i2)+df(i3,i4)) + wp1*(df(i1,e1)+df(i2,e2)+df(i3,e3)+df(i4,e4)) + wp3*(df(i1,e2)+df(i3,e4)+df(e1,i2)+df(e3,i4)));
+}
+
+vec3 min4(vec3 a, vec3 b, vec3 c, vec3 d)
+{
+    return min(a, min(b, min(c, d)));
+}
+vec3 max4(vec3 a, vec3 b, vec3 c, vec3 d)
+{
+    return max(a, max(b, max(c, d)));
+}
+
+void main()
+{
+	//Skip pixels on wrong grid
+ 	if (any(lessThan(fract(vTexCoord.xy*SourceSize.xy/XBR_RES) , vec2(0.5,0.5))))
+		{
+			FragColor = COMPAT_TEXTURE(Source, vTexCoord);
+         return;
+		}
+	else
+		{
+			vec2 tex = (floor(vTexCoord*SourceSize.xy/XBR_RES) + vec2(0.5, 0.5))*XBR_RES/SourceSize.xy;
+
+			vec2 g1 = vec2(XBR_RES/SourceSize.x, 0.0);
+			vec2 g2 = vec2(0.0, XBR_RES/SourceSize.y);
+
+			vec3 P0 = COMPAT_TEXTURE(Source, vTexCoord     -g1    -g2).xyz;
+			vec3 P1 = COMPAT_TEXTURE(Source, vTexCoord +2.0*g1    -g2).xyz;
+			vec3 P2 = COMPAT_TEXTURE(Source, vTexCoord     -g1+2.0*g2).xyz;
+			vec3 P3 = COMPAT_TEXTURE(Source, vTexCoord +2.0*g1+2.0*g2).xyz;
+
+			vec3  B = COMPAT_TEXTURE(Source, vTexCoord    -g2).xyz;
+			vec3  C = COMPAT_TEXTURE(Source, vTexCoord +g1-g2).xyz;
+			vec3  D = COMPAT_TEXTURE(Source, vTexCoord -g1   ).xyz;
+			vec3  E = COMPAT_TEXTURE(Source, vTexCoord       ).xyz;
+			vec3  F = COMPAT_TEXTURE(Source, vTexCoord +g1   ).xyz;
+			vec3  G = COMPAT_TEXTURE(Source, vTexCoord -g1+g2).xyz;
+			vec3  H = COMPAT_TEXTURE(Source, vTexCoord    +g2).xyz;
+			vec3  I = COMPAT_TEXTURE(Source, vTexCoord +g1+g2).xyz;
+
+			vec3 F4 = COMPAT_TEXTURE(Source, vTexCoord    +2.0*g1   ).xyz;
+			vec3 I4 = COMPAT_TEXTURE(Source, vTexCoord +g2+2.0*g1   ).xyz;
+			vec3 H5 = COMPAT_TEXTURE(Source, vTexCoord +2.0*g2      ).xyz;
+			vec3 I5 = COMPAT_TEXTURE(Source, vTexCoord +2.0*g2+g1   ).xyz;
+
+			vec3 F6 = COMPAT_TEXTURE(Source, tex +g1+0.25*g1+0.25*g2).xyz;
+			vec3 F7 = COMPAT_TEXTURE(Source, tex +g1+0.25*g1-0.25*g2).xyz;
+			vec3 F8 = COMPAT_TEXTURE(Source, tex +g1-0.25*g1-0.25*g2).xyz;
+			vec3 F9 = COMPAT_TEXTURE(Source, tex +g1-0.25*g1+0.25*g2).xyz;
+
+			vec3 H6 = COMPAT_TEXTURE(Source, tex +0.25*g1+0.25*g2+g2).xyz;
+			vec3 H7 = COMPAT_TEXTURE(Source, tex +0.25*g1-0.25*g2+g2).xyz;
+			vec3 H8 = COMPAT_TEXTURE(Source, tex -0.25*g1-0.25*g2+g2).xyz;
+			vec3 H9 = COMPAT_TEXTURE(Source, tex -0.25*g1+0.25*g2+g2).xyz;
+
+			vec4 f0 = reduce4(F6, F7, F8, F9);
+			vec4 h0 = reduce4(H6, H7, H8, H9);
+
+			bool block_3d = ((f0.xyz == f0.yzw) && (h0.xyz == h0.yzw));
+
+			float b = RGBtoYUV( B );
+			float c = RGBtoYUV( C );
+			float d = RGBtoYUV( D );
+			float e = RGBtoYUV( E );
+			float f = RGBtoYUV( F );
+			float g = RGBtoYUV( G );
+			float h = RGBtoYUV( H );
+			float i = RGBtoYUV( I );
+
+			float i4 = RGBtoYUV( I4 ); float p0 = RGBtoYUV( P0 );
+			float i5 = RGBtoYUV( I5 ); float p1 = RGBtoYUV( P1 );
+			float h5 = RGBtoYUV( H5 ); float p2 = RGBtoYUV( P2 );
+			float f4 = RGBtoYUV( F4 ); float p3 = RGBtoYUV( P3 );
+
+/*
+                              P1
+     |P0|B |C |P1|         C     F4          |a0|b1|c2|d3|
+     |D |E |F |F4|      B     F     I4       |b0|c1|d2|e3|   |e1|i1|i2|e2|
+     |G |H |I |I4|   P0    E  A  I     P3    |c0|d1|e2|f3|   |e3|i3|i4|e4|
+     |P2|H5|I5|P3|      D     H     I5       |d0|e1|f2|g3|
+                           G     H5
+                              P2
+*/
+
+			/* Calc edgeness in diagonal directions. */
+			float d_edge  = (d_wd( d, b, g, e, c, p2, h, f, p1, h5, i, f4, i5, i4 ) - d_wd( c, f4, b, f, i4, p0, e, i, p3, d, h, i5, g, h5 ));
+
+			/* Calc edgeness in horizontal/vertical directions. */
+			float hv_edge = (hv_wd(f, i, e, h, c, i5, b, h5) - hv_wd(e, f, h, i, d, f4, g, i4));
+
+			float limits = XBR_EDGE_STR + 0.000001;
+			float edge_strength = smoothstep(0.0, limits, abs(d_edge));
+
+			/* Filter weights. Two taps only. */
+			vec4 w1 = vec4(-weight1, weight1+0.5, weight1+0.5, -weight1);
+			vec4 w2 = vec4(-weight2, weight2+0.25, weight2+0.25, -weight2);
+
+			/* Filtering and normalization in four direction generating four colors. */
+			vec3 c1 = mul(w1, mat4x3( P2,   H,   F,   P1 ));
+			vec3 c2 = mul(w1, mat4x3( P0,   E,   I,   P3 ));
+			vec3 c3 = mul(w2, mat4x3(D+G, E+H, F+I, F4+I4));
+			vec3 c4 = mul(w2, mat4x3(C+B, F+E, I+H, I5+H5));
+         
+         // doesn't seem to be used anywhere, so commenting for performance
+//			bool ir_lv1 = (((e!=f) && (e!=h))  && ( !eq(f,b) && !eq(f,c) || !eq(h,d) && !eq(h,g) || eq(e,i) && (!eq(f,f4) && !eq(f,i4) || !eq(h,h5) && !eq(h,i5)) || eq(e,g) || eq(e,c)) );
+
+
+			/* Smoothly blends the two strongest directions (one in diagonal and the other in vert/horiz direction). */
+			vec3 color =  mix(mix(c1, c2, step(0.0, d_edge)), mix(c3, c4, step(0.0, hv_edge)), 1. - edge_strength);
+
+/*
+                              P1
+     |P0|B |C |P1|         C     F4          |a0|b1|c2|d3|
+     |D |E |F |F4|      B     F     I4       |b0|c1|d2|e3|   |e1|i1|i2|e2|
+     |G |H |I |I4|   P0    E  A  I     P3    |c0|d1|e2|f3|   |e3|i3|i4|e4|
+     |P2|H5|I5|P3|      D     H     I5       |d0|e1|f2|g3|
+                           G     H5
+                              P2
+*/
+
+			/* Anti-ringing code. */
+			vec3 min_sample = min4( E, F, H, I ) + (1.-XBR_ANTI_RINGING)*mix((P2-H)*(F-P1), (P0-E)*(I-P3), step(0.0, d_edge));
+			vec3 max_sample = max4( E, F, H, I ) - (1.-XBR_ANTI_RINGING)*mix((P2-H)*(F-P1), (P0-E)*(I-P3), step(0.0, d_edge));
+
+			color = clamp(color, min_sample, max_sample);
+
+			color = (block_3d) ? color : E;
+
+			FragColor = vec4(color, 1.0);
+		}
+} 
+#endif
diff --git a/base/xbr/shaders/super-xbr/super-2xbr-3d-pass1.glsl b/base/xbr/shaders/super-xbr/super-2xbr-3d-pass1.glsl
new file mode 100644
index 0000000..972de4f
--- /dev/null
+++ b/base/xbr/shaders/super-xbr/super-2xbr-3d-pass1.glsl
@@ -0,0 +1,269 @@
+#version 130
+
+/*
+   
+  *******  Super XBR Shader - pass1  *******
+   
+  Copyright (c) 2015 Hyllian - sergiogdb at gmail.com
+
+  Permission is hereby granted, free of charge, to any person obtaining a copy
+  of this software and associated documentation files (the "Software"), to deal
+  in the Software without restriction, including without limitation the rights
+  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+  copies of the Software, and to permit persons to whom the Software is
+  furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included in
+  all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+  THE SOFTWARE.
+
+*/
+
+#define mul(a,b) (b*a)
+
+#define wp1  8.0
+#define wp2  0.0
+#define wp3  0.0
+#define wp4  0.0
+#define wp5  0.0
+#define wp6  0.0
+
+#define XBR_RES 2.0
+
+#define weight1 (XBR_WEIGHT*1.75068/10.0)
+#define weight2 (XBR_WEIGHT*1.29633/10.0/2.0)
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 TEX0;
+
+vec4 _oPosition1; 
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    TEX0.xy = TexCoord.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out COMPAT_PRECISION vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+uniform sampler2D PassPrev2Texture;
+COMPAT_VARYING vec4 TEX0;
+
+// compatibility #defines
+#define Source Texture
+#define Original PassPrev2Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutputSize vec4(OutputSize, 1.0 / OutputSize)
+
+const float XBR_EDGE_STR = 0.6;
+const float XBR_WEIGHT = 1.0;
+const float XBR_ANTI_RINGING = 1.0;
+
+const vec3 Y = vec3(.2126, .7152, .0722);
+
+float RGBtoYUV(vec3 color)
+{
+  return dot(color, Y);
+}
+
+float df(float A, float B)
+{
+  return abs(A-B);
+}
+
+/*
+                              P1
+     |P0|B |C |P1|         C     F4          |a0|b1|c2|d3|
+     |D |E |F |F4|      B     F     I4       |b0|c1|d2|e3|   |e1|i1|i2|e2|
+     |G |H |I |I4|   P0    E  A  I     P3    |c0|d1|e2|f3|   |e3|i3|i4|e4|
+     |P2|H5|I5|P3|      D     H     I5       |d0|e1|f2|g3|
+                           G     H5
+                              P2
+*/
+
+float d_wd(float b0, float b1, float c0, float c1, float c2, float d0, float d1, float d2, float d3, float e1, float e2, float e3, float f2, float f3)
+{
+	return (wp1*(df(c1,c2) + df(c1,c0) + df(e2,e1) + df(e2,e3)) + wp2*(df(d2,d3) + df(d0,d1)) + wp3*(df(d1,d3) + df(d0,d2)) + wp4*df(d1,d2) + wp5*(df(c0,c2) + df(e1,e3)) + wp6*(df(b0,b1) + df(f2,f3)));
+}
+
+float hv_wd(float i1, float i2, float i3, float i4, float e1, float e2, float e3, float e4)
+{
+	return ( wp4*(df(i1,i2)+df(i3,i4)) + wp1*(df(i1,e1)+df(i2,e2)+df(i3,e3)+df(i4,e4)) + wp3*(df(i1,e2)+df(i3,e4)+df(e1,i2)+df(e3,i4)));
+}
+
+vec3 min4(vec3 a, vec3 b, vec3 c, vec3 d)
+{
+    return min(a, min(b, min(c, d)));
+}
+vec3 max4(vec3 a, vec3 b, vec3 c, vec3 d)
+{
+    return max(a, max(b, max(c, d)));
+}
+
+const vec3 dtt = vec3(65536.,255.,1.);
+
+vec4 reduce4(vec3 A, vec3 B, vec3 C, vec3 D)
+{
+  return mul(mat4x3(A, B, C, D), dtt);
+}
+
+void main()
+{
+	//Skip pixels on wrong grid
+	vec2 dir = fract(vTexCoord*TextureSize/XBR_RES) - vec2(0.5,0.5);
+ 	if ((dir.x*dir.y)>0.0){ FragColor = COMPAT_TEXTURE(Source, vTexCoord);
+      return;}
+      else{
+
+	vec2 tex = (floor(vTexCoord*TextureSize/XBR_RES) + vec2(0.5, 0.5))*XBR_RES/TextureSize;
+
+	vec2 g1 = vec2((XBR_RES/2.0)/TextureSize.x, 0.0);
+	vec2 g2 = vec2(0.0, (XBR_RES/2.0)/TextureSize.y);
+
+	vec3 P0 = COMPAT_TEXTURE(Source,	vTexCoord -3.0*g1        ).xyz;
+	vec3 P1 = COMPAT_TEXTURE(Source,	vTexCoord         -3.0*g2).xyz;
+	vec3 P2 = COMPAT_TEXTURE(Source,	vTexCoord         +3.0*g2).xyz;
+	vec3 P3 = COMPAT_TEXTURE(Source,	vTexCoord +3.0*g1        ).xyz;
+
+	vec3  B = COMPAT_TEXTURE(Source,	vTexCoord -2.0*g1     -g2).xyz;
+	vec3  C = COMPAT_TEXTURE(Source,	vTexCoord     -g1 -2.0*g2).xyz;
+	vec3  D = COMPAT_TEXTURE(Source,	vTexCoord -2.0*g1     +g2).xyz;
+	vec3  E = COMPAT_TEXTURE(Source,	vTexCoord     -g1        ).xyz;
+	vec3  F = COMPAT_TEXTURE(Source,	vTexCoord             -g2).xyz;
+	vec3  G = COMPAT_TEXTURE(Source,	vTexCoord     -g1 +2.0*g2).xyz;
+	vec3  H = COMPAT_TEXTURE(Source,	vTexCoord             +g2).xyz;
+	vec3  I = COMPAT_TEXTURE(Source,	vTexCoord     +g1        ).xyz;
+
+	vec3 F4 = COMPAT_TEXTURE(Source,	vTexCoord     +g1 -2.0*g2).xyz;
+	vec3 I4 = COMPAT_TEXTURE(Source,	vTexCoord +2.0*g1     -g2).xyz;
+	vec3 H5 = COMPAT_TEXTURE(Source,	vTexCoord     +g1 +2.0*g2).xyz;
+	vec3 I5 = COMPAT_TEXTURE(Source,	vTexCoord +2.0*g1     +g2).xyz;
+   
+   	vec3 A = COMPAT_TEXTURE(Source, vTexCoord).xyz;
+
+	g1 *= 2.0;
+	g2 *= 2.0;
+
+	vec3 F6 = COMPAT_TEXTURE(Original, tex +g1+0.25*g1+0.25*g2).xyz;
+	vec3 F7 = COMPAT_TEXTURE(Original, tex +g1+0.25*g1-0.25*g2).xyz;
+	vec3 F8 = COMPAT_TEXTURE(Original, tex +g1-0.25*g1-0.25*g2).xyz;
+	vec3 F9 = COMPAT_TEXTURE(Original, tex +g1-0.25*g1+0.25*g2).xyz;
+
+	vec3 H6 = COMPAT_TEXTURE(Original, tex +0.25*g1+0.25*g2+g2).xyz;
+	vec3 H7 = COMPAT_TEXTURE(Original, tex +0.25*g1-0.25*g2+g2).xyz;
+	vec3 H8 = COMPAT_TEXTURE(Original, tex -0.25*g1-0.25*g2+g2).xyz;
+	vec3 H9 = COMPAT_TEXTURE(Original, tex -0.25*g1+0.25*g2+g2).xyz;
+
+	vec4 f0 = reduce4(F6, F7, F8, F9);
+	vec4 h0 = reduce4(H6, H7, H8, H9);
+
+        bool block_3d = ((f0.xyz==f0.yzw) && (h0.xyz==h0.yzw));
+
+	float b = RGBtoYUV( B );
+	float c = RGBtoYUV( C );
+	float d = RGBtoYUV( D );
+	float e = RGBtoYUV( E );
+	float f = RGBtoYUV( F );
+	float g = RGBtoYUV( G );
+	float h = RGBtoYUV( H );
+	float i = RGBtoYUV( I );
+
+	float i4 = RGBtoYUV( I4 ); float p0 = RGBtoYUV( P0 );
+	float i5 = RGBtoYUV( I5 ); float p1 = RGBtoYUV( P1 );
+	float h5 = RGBtoYUV( H5 ); float p2 = RGBtoYUV( P2 );
+	float f4 = RGBtoYUV( F4 ); float p3 = RGBtoYUV( P3 );
+
+	/* Calc edgeness in diagonal directions. */
+	float d_edge  = (d_wd( d, b, g, e, c, p2, h, f, p1, h5, i, f4, i5, i4 ) - d_wd( c, f4, b, f, i4, p0, e, i, p3, d, h, i5, g, h5 ));
+
+	/* Calc edgeness in horizontal/vertical directions. */
+	float hv_edge = (hv_wd(f, i, e, h, c, i5, b, h5) - hv_wd(e, f, h, i, d, f4, g, i4));
+
+	float limits = XBR_EDGE_STR + 0.000001;
+	float edge_strength = smoothstep(0.0, limits, abs(d_edge));
+
+	/* Filter weights. Two taps only. */
+	vec4 w1 = vec4(-weight1, weight1+0.5, weight1+0.5, -weight1);
+	vec4 w2 = vec4(-weight2, weight2+0.25, weight2+0.25, -weight2);
+
+	/* Filtering and normalization in four direction generating four colors. */
+    vec3 c1 = mul(w1, mat4x3( P2,   H,   F,   P1 ));
+    vec3 c2 = mul(w1, mat4x3( P0,   E,   I,   P3 ));
+	 vec3 c3 = mul(w2, mat4x3(D+G, E+H, F+I, F4+I4));
+    vec3 c4 = mul(w2, mat4x3(C+B, F+E, I+H, I5+H5));
+
+	/* Smoothly blends the two strongest directions (one in diagonal and the other in vert/horiz direction). */
+	vec3 color =  mix(mix(c1, c2, step(0.0, d_edge)), mix(c3, c4, step(0.0, hv_edge)), 1. - edge_strength);
+
+	/* Anti-ringing code. */
+	vec3 min_sample = min4( E, F, H, I ) + (1.-XBR_ANTI_RINGING)*mix((P2-H)*(F-P1), (P0-E)*(I-P3), step(0.0, d_edge));
+	vec3 max_sample = max4( E, F, H, I ) - (1.-XBR_ANTI_RINGING)*mix((P2-H)*(F-P1), (P0-E)*(I-P3), step(0.0, d_edge));
+	color = clamp(color, min_sample, max_sample);
+   
+   color = (block_3d) ? color : A;
+	
+   FragColor = vec4(color, 1.0);
+   }
+} 
+#endif
diff --git a/base/xbr/shaders/super-xbr/super-2xbr-3d-pass2.glsl b/base/xbr/shaders/super-xbr/super-2xbr-3d-pass2.glsl
new file mode 100644
index 0000000..55116c9
--- /dev/null
+++ b/base/xbr/shaders/super-xbr/super-2xbr-3d-pass2.glsl
@@ -0,0 +1,284 @@
+#version 130
+
+/*
+   
+  *******  Super XBR Shader - pass2  *******  This pass is optional.
+   
+  Copyright (c) 2015 Hyllian - sergiogdb at gmail.com
+
+  Permission is hereby granted, free of charge, to any person obtaining a copy
+  of this software and associated documentation files (the "Software"), to deal
+  in the Software without restriction, including without limitation the rights
+  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+  copies of the Software, and to permit persons to whom the Software is
+  furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included in
+  all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+  THE SOFTWARE.
+
+*/
+
+#define mul(a,b) (b*a)
+
+#define wp1  1.0
+#define wp2  0.0
+#define wp3  2.0
+#define wp4  3.0
+#define wp5 -2.0
+#define wp6  1.0
+
+#define XBR_RES 2.0
+
+#define weight1 (XBR_WEIGHT*1.29633/10.0)
+#define weight2 (XBR_WEIGHT*1.75068/10.0/2.0)
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 TEX0;
+COMPAT_VARYING vec4 t1;
+COMPAT_VARYING vec4 t2;
+COMPAT_VARYING vec4 t3;
+COMPAT_VARYING vec4 t4;
+
+vec4 _oPosition1; 
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize)
+#define vTexCoord TEX0.xy
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    TEX0.xy = TexCoord.xy;
+   float dx = SourceSize.z;
+   float dy = SourceSize.w;
+   t1 = vTexCoord.xyxy + vec4(-2.0*dx, -2.0*dy, dx, dy);
+   t2 = vTexCoord.xyxy + vec4(    -dx, -2.0*dy,  0, dy);
+   t3 = vTexCoord.xyxy + vec4(-2.0*dx,     -dy, dx,  0);
+   t4 = vTexCoord.xyxy + vec4(    -dx,     -dy,  0,  0);
+}
+
+#elif defined(FRAGMENT)
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out COMPAT_PRECISION vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+uniform sampler2D PassPrev3Texture;
+COMPAT_VARYING vec4 TEX0;
+COMPAT_VARYING vec4 t1;
+COMPAT_VARYING vec4 t2;
+COMPAT_VARYING vec4 t3;
+COMPAT_VARYING vec4 t4;
+
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutputSize vec4(OutputSize, 1.0 / OutputSize)
+
+const float XBR_EDGE_STR = 0.6;
+const float XBR_WEIGHT = 1.0;
+const float XBR_ANTI_RINGING = 1.0;
+
+const vec3 Y = vec3(.2126, .7152, .0722);
+const vec3 dtt = vec3(65536.,255.,1.);
+
+float RGBtoYUV(vec3 color)
+{
+  return dot(color, Y);
+}
+
+float df(float A, float B)
+{
+  return abs(A-B);
+}
+
+/*
+                              P1
+     |P0|B |C |P1|         C     F4          |a0|b1|c2|d3|
+     |D |E |F |F4|      B     F     I4       |b0|c1|d2|e3|   |e1|i1|i2|e2|
+     |G |H |I |I4|   P0    E  A  I     P3    |c0|d1|e2|f3|   |e3|i3|i4|e4|
+     |P2|H5|I5|P3|      D     H     I5       |d0|e1|f2|g3|
+                           G     H5
+                              P2
+*/
+
+float d_wd(float b0, float b1, float c0, float c1, float c2, float d0, float d1, float d2, float d3, float e1, float e2, float e3, float f2, float f3)
+{
+	return (wp1*(df(c1,c2) + df(c1,c0) + df(e2,e1) + df(e2,e3)) + wp2*(df(d2,d3) + df(d0,d1)) + wp3*(df(d1,d3) + df(d0,d2)) + wp4*df(d1,d2) + wp5*(df(c0,c2) + df(e1,e3)) + wp6*(df(b0,b1) + df(f2,f3)));
+}
+
+float hv_wd(float i1, float i2, float i3, float i4, float e1, float e2, float e3, float e4)
+{
+	return ( wp4*(df(i1,i2)+df(i3,i4)) + wp1*(df(i1,e1)+df(i2,e2)+df(i3,e3)+df(i4,e4)) + wp3*(df(i1,e2)+df(i3,e4)+df(e1,i2)+df(e3,i4)));
+}
+
+vec3 min4(vec3 a, vec3 b, vec3 c, vec3 d)
+{
+    return min(a, min(b, min(c, d)));
+}
+vec3 max4(vec3 a, vec3 b, vec3 c, vec3 d)
+{
+    return max(a, max(b, max(c, d)));
+}
+
+vec4 reduce4(vec3 A, vec3 B, vec3 C, vec3 D)
+{
+  return mul(mat4x3(A, B, C, D), dtt);
+}
+
+void main()
+{
+	vec2 tex = (floor(vTexCoord*TextureSize/XBR_RES) + vec2(0.5, 0.5))*XBR_RES/TextureSize;
+
+	vec2 g1 = vec2(XBR_RES/TextureSize.x, 0.0);
+	vec2 g2 = vec2(0.0, XBR_RES/TextureSize.y);
+
+	vec3 P0 = COMPAT_TEXTURE(Source, t1.xy).xyz;
+	vec3 P1 = COMPAT_TEXTURE(Source, t1.zy).xyz;
+	vec3 P2 = COMPAT_TEXTURE(Source, t1.xw).xyz;
+	vec3 P3 = COMPAT_TEXTURE(Source, t1.zw).xyz;
+
+	vec3  B = COMPAT_TEXTURE(Source, t2.xy).xyz;
+	vec3  C = COMPAT_TEXTURE(Source, t2.zy).xyz;
+	vec3 H5 = COMPAT_TEXTURE(Source, t2.xw).xyz;
+	vec3 I5 = COMPAT_TEXTURE(Source, t2.zw).xyz;
+
+	vec3  D = COMPAT_TEXTURE(Source, t3.xy).xyz;
+	vec3 F4 = COMPAT_TEXTURE(Source, t3.zy).xyz;
+	vec3  G = COMPAT_TEXTURE(Source, t3.xw).xyz;
+	vec3 I4 = COMPAT_TEXTURE(Source, t3.zw).xyz;
+
+	vec3  E = COMPAT_TEXTURE(Source, t4.xy).xyz;
+	vec3  F = COMPAT_TEXTURE(Source, t4.zy).xyz;
+	vec3  H = COMPAT_TEXTURE(Source, t4.xw).xyz;
+	vec3  I = COMPAT_TEXTURE(Source, t4.zw).xyz;
+   
+   vec3 A = COMPAT_TEXTURE(Source, vTexCoord).xyz;
+
+	vec3 F6 = COMPAT_TEXTURE(PassPrev3Texture, tex +g1+0.25*g1+0.25*g2).xyz;
+	vec3 F7 = COMPAT_TEXTURE(PassPrev3Texture, tex +g1+0.25*g1-0.25*g2).xyz;
+	vec3 F8 = COMPAT_TEXTURE(PassPrev3Texture, tex +g1-0.25*g1-0.25*g2).xyz;
+	vec3 F9 = COMPAT_TEXTURE(PassPrev3Texture, tex +g1-0.25*g1+0.25*g2).xyz;
+
+	vec3 H6 = COMPAT_TEXTURE(PassPrev3Texture, tex +0.25*g1+0.25*g2+g2).xyz;
+	vec3 H7 = COMPAT_TEXTURE(PassPrev3Texture, tex +0.25*g1-0.25*g2+g2).xyz;
+	vec3 H8 = COMPAT_TEXTURE(PassPrev3Texture, tex -0.25*g1-0.25*g2+g2).xyz;
+	vec3 H9 = COMPAT_TEXTURE(PassPrev3Texture, tex -0.25*g1+0.25*g2+g2).xyz;
+
+	vec4 f0 = reduce4(F6, F7, F8, F9);
+	vec4 h0 = reduce4(H6, H7, H8, H9);
+
+   bool block_3d = ((f0.xyz==f0.yzw) && (h0.xyz==h0.yzw));
+
+	float b = RGBtoYUV( B );
+	float c = RGBtoYUV( C );
+	float d = RGBtoYUV( D );
+	float e = RGBtoYUV( E );
+	float f = RGBtoYUV( F );
+	float g = RGBtoYUV( G );
+	float h = RGBtoYUV( H );
+	float i = RGBtoYUV( I );
+
+	float i4 = RGBtoYUV( I4 ); float p0 = RGBtoYUV( P0 );
+	float i5 = RGBtoYUV( I5 ); float p1 = RGBtoYUV( P1 );
+	float h5 = RGBtoYUV( H5 ); float p2 = RGBtoYUV( P2 );
+	float f4 = RGBtoYUV( F4 ); float p3 = RGBtoYUV( P3 );
+
+/*
+                              P1
+     |P0|B |C |P1|         C     F4          |a0|b1|c2|d3|
+     |D |E |F |F4|      B     F     I4       |b0|c1|d2|e3|   |e1|i1|i2|e2|
+     |G |H |I |I4|   P0    E  A  I     P3    |c0|d1|e2|f3|   |e3|i3|i4|e4|
+     |P2|H5|I5|P3|      D     H     I5       |d0|e1|f2|g3|
+                           G     H5
+                              P2
+*/
+
+	/* Calc edgeness in diagonal directions. */
+	float d_edge  = (d_wd( d, b, g, e, c, p2, h, f, p1, h5, i, f4, i5, i4 ) - d_wd( c, f4, b, f, i4, p0, e, i, p3, d, h, i5, g, h5 ));
+
+	/* Calc edgeness in horizontal/vertical directions. */
+	float hv_edge = (hv_wd(f, i, e, h, c, i5, b, h5) - hv_wd(e, f, h, i, d, f4, g, i4));
+
+	float limits = XBR_EDGE_STR + 0.000001;
+	float edge_strength = smoothstep(0.0, limits, abs(d_edge));
+
+	/* Filter weights. Two taps only. */
+	vec4 w1 = vec4(-weight1, weight1+0.5, weight1+0.5, -weight1);
+	vec4 w2 = vec4(-weight2, weight2+0.25, weight2+0.25, -weight2);
+
+	/* Filtering and normalization in four direction generating four colors. */
+	vec3 c1 = mul(w1, mat4x3( P2,   H,   F,   P1 ));
+	vec3 c2 = mul(w1, mat4x3( P0,   E,   I,   P3 ));
+	vec3 c3 = mul(w2, mat4x3(D+G, E+H, F+I, F4+I4));
+	vec3 c4 = mul(w2, mat4x3(C+B, F+E, I+H, I5+H5));
+
+	/* Smoothly blends the two strongest directions (one in diagonal and the other in vert/horiz direction). */
+	vec3 color =  mix(mix(c1, c2, step(0.0, d_edge)), mix(c3, c4, step(0.0, hv_edge)), 1. - edge_strength);
+
+	/* Anti-ringing code. */
+	vec3 min_sample = min4( E, F, H, I ) + (1.-XBR_ANTI_RINGING)*mix((P2-H)*(F-P1), (P0-E)*(I-P3), step(0.0, d_edge));
+	vec3 max_sample = max4( E, F, H, I ) - (1.-XBR_ANTI_RINGING)*mix((P2-H)*(F-P1), (P0-E)*(I-P3), step(0.0, d_edge));
+	color = clamp(color, min_sample, max_sample);
+   
+   color = (block_3d) ? color : A;
+	
+   FragColor = vec4(color, 1.0);
+} 
+#endif
diff --git a/base/xbr/shaders/super-xbr/super-4xbr-3d-pass0.glsl b/base/xbr/shaders/super-xbr/super-4xbr-3d-pass0.glsl
new file mode 100644
index 0000000..a2a8066
--- /dev/null
+++ b/base/xbr/shaders/super-xbr/super-4xbr-3d-pass0.glsl
@@ -0,0 +1,305 @@
+#version 130
+
+/*
+   
+  *******  Super 4XBR 3D Shader - pass0  *******
+   
+  Copyright (c) 2016 Hyllian - sergiogdb at gmail.com
+
+  Permission is hereby granted, free of charge, to any person obtaining a copy
+  of this software and associated documentation files (the "Software"), to deal
+  in the Software without restriction, including without limitation the rights
+  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+  copies of the Software, and to permit persons to whom the Software is
+  furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included in
+  all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+  THE SOFTWARE.
+
+*/
+
+#pragma parameter XBR_EDGE_STR "Xbr - Edge Strength p0" 2.0 0.0 5.0 0.2
+#pragma parameter XBR_WEIGHT "Xbr - Filter Weight" 1.0 0.00 1.50 0.05
+#pragma parameter XBR_ANTI_RINGING "Xbr - Anti-Ringing Level" 1.0 0.0 1.0 1.0
+
+#define mul(a,b) (b*a)
+
+#define wp1  2.0
+#define wp2  1.0
+#define wp3 -1.0
+#define wp4  4.0
+#define wp5 -1.0
+#define wp6  1.0
+
+#define XBR_RES 4.0
+
+#define weight1 (XBR_WEIGHT*1.29633/10.0)
+#define weight2 (XBR_WEIGHT*1.75068/10.0/2.0)
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 TEX0;
+
+vec4 _oPosition1; 
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    TEX0.xy = TexCoord.xy * 1.0001;
+}
+
+#elif defined(FRAGMENT)
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out COMPAT_PRECISION vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+COMPAT_VARYING vec4 TEX0;
+
+// compatibility #defines
+#define Source Texture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutputSize vec4(OutputSize, 1.0 / OutputSize)
+
+#ifdef PARAMETER_UNIFORM
+uniform COMPAT_PRECISION float XBR_EDGE_STR;
+uniform COMPAT_PRECISION float XBR_WEIGHT;
+uniform COMPAT_PRECISION float XBR_ANTI_RINGING;
+#else
+#define XBR_EDGE_STR 0.6
+#define XBR_WEIGHT 1.0
+#define XBR_ANTI_RINGING 1.0
+#endif
+
+const vec3 Y = vec3(.2126, .7152, .0722);
+
+const vec3 dtt = vec3(65536.,255.,1.);
+
+vec4 reduce4(vec3 A, vec3 B, vec3 C, vec3 D)
+{
+  return mul(mat4x3(A, B, C, D), dtt);
+}
+
+float RGBtoYUV(vec3 color)
+{
+  return dot(color, Y);
+}
+
+float df(float A, float B)
+{
+  return abs(A-B);
+}
+
+bool eq(float A, float B)
+{
+	return (df(A, B) < 15.0);
+}
+
+
+/*
+                              P1
+     |P0|B |C |P1|         C     F4          |a0|b1|c2|d3|
+     |D |E |F |F4|      B     F     I4       |b0|c1|d2|e3|   |e1|i1|i2|e2|
+     |G |H |I |I4|   P0    E  A  I     P3    |c0|d1|e2|f3|   |e3|i3|i4|e4|
+     |P2|H5|I5|P3|      D     H     I5       |d0|e1|f2|g3|
+                           G     H5
+                              P2
+*/
+
+
+float d_wd(float b0, float b1, float c0, float c1, float c2, float d0, float d1, float d2, float d3, float e1, float e2, float e3, float f2, float f3)
+{
+	return (wp1*(df(c1,c2) + df(c1,c0) + df(e2,e1) + df(e2,e3)) + wp2*(df(d2,d3) + df(d0,d1)) + wp3*(df(d1,d3) + df(d0,d2)) + wp4*df(d1,d2) + wp5*(df(c0,c2) + df(e1,e3)) + wp6*(df(b0,b1) + df(f2,f3)));
+}
+
+float hv_wd(float i1, float i2, float i3, float i4, float e1, float e2, float e3, float e4)
+{
+	return ( wp4*(df(i1,i2)+df(i3,i4)) + wp1*(df(i1,e1)+df(i2,e2)+df(i3,e3)+df(i4,e4)) + wp3*(df(i1,e2)+df(i3,e4)+df(e1,i2)+df(e3,i4)));
+}
+
+vec3 min4(vec3 a, vec3 b, vec3 c, vec3 d)
+{
+    return min(a, min(b, min(c, d)));
+}
+vec3 max4(vec3 a, vec3 b, vec3 c, vec3 d)
+{
+    return max(a, max(b, max(c, d)));
+}
+
+void main()
+{
+	//Skip pixels on wrong grid
+ 	if (any(lessThan(fract(vTexCoord*SourceSize.xy/XBR_RES) , vec2(0.5,0.5))))
+		{
+			FragColor = COMPAT_TEXTURE(Source, vTexCoord);
+         return;
+		}
+	else
+		{
+			vec2 tex = (floor(vTexCoord*SourceSize.xy/XBR_RES) + vec2(0.5, 0.5))*XBR_RES/SourceSize.xy;
+
+			vec2 g1 = vec2(XBR_RES/SourceSize.x, 0.0);
+			vec2 g2 = vec2(0.0, XBR_RES/SourceSize.y);
+
+			vec3 P0 = COMPAT_TEXTURE(Source, vTexCoord     -g1    -g2).xyz;
+			vec3 P1 = COMPAT_TEXTURE(Source, vTexCoord +2.0*g1    -g2).xyz;
+			vec3 P2 = COMPAT_TEXTURE(Source, vTexCoord     -g1+2.0*g2).xyz;
+			vec3 P3 = COMPAT_TEXTURE(Source, vTexCoord +2.0*g1+2.0*g2).xyz;
+
+			vec3  B = COMPAT_TEXTURE(Source, vTexCoord    -g2).xyz;
+			vec3  C = COMPAT_TEXTURE(Source, vTexCoord +g1-g2).xyz;
+			vec3  D = COMPAT_TEXTURE(Source, vTexCoord -g1   ).xyz;
+			vec3  E = COMPAT_TEXTURE(Source, vTexCoord       ).xyz;
+			vec3  F = COMPAT_TEXTURE(Source, vTexCoord +g1   ).xyz;
+			vec3  G = COMPAT_TEXTURE(Source, vTexCoord -g1+g2).xyz;
+			vec3  H = COMPAT_TEXTURE(Source, vTexCoord    +g2).xyz;
+			vec3  I = COMPAT_TEXTURE(Source, vTexCoord +g1+g2).xyz;
+
+			vec3 F4 = COMPAT_TEXTURE(Source, vTexCoord    +2.0*g1   ).xyz;
+			vec3 I4 = COMPAT_TEXTURE(Source, vTexCoord +g2+2.0*g1   ).xyz;
+			vec3 H5 = COMPAT_TEXTURE(Source, vTexCoord +2.0*g2      ).xyz;
+			vec3 I5 = COMPAT_TEXTURE(Source, vTexCoord +2.0*g2+g1   ).xyz;
+
+			vec3 F6 = COMPAT_TEXTURE(Source, tex +g1+0.25*g1+0.25*g2).xyz;
+			vec3 F7 = COMPAT_TEXTURE(Source, tex +g1+0.25*g1-0.25*g2).xyz;
+			vec3 F8 = COMPAT_TEXTURE(Source, tex +g1-0.25*g1-0.25*g2).xyz;
+			vec3 F9 = COMPAT_TEXTURE(Source, tex +g1-0.25*g1+0.25*g2).xyz;
+
+			vec3 H6 = COMPAT_TEXTURE(Source, tex +0.25*g1+0.25*g2+g2).xyz;
+			vec3 H7 = COMPAT_TEXTURE(Source, tex +0.25*g1-0.25*g2+g2).xyz;
+			vec3 H8 = COMPAT_TEXTURE(Source, tex -0.25*g1-0.25*g2+g2).xyz;
+			vec3 H9 = COMPAT_TEXTURE(Source, tex -0.25*g1+0.25*g2+g2).xyz;
+
+			vec4 f0 = reduce4(F6, F7, F8, F9);
+			vec4 h0 = reduce4(H6, H7, H8, H9);
+
+			bool block_3d = ((f0.xyz == f0.yzw) && (h0.xyz == h0.yzw));
+
+			float b = RGBtoYUV( B );
+			float c = RGBtoYUV( C );
+			float d = RGBtoYUV( D );
+			float e = RGBtoYUV( E );
+			float f = RGBtoYUV( F );
+			float g = RGBtoYUV( G );
+			float h = RGBtoYUV( H );
+			float i = RGBtoYUV( I );
+
+			float i4 = RGBtoYUV( I4 ); float p0 = RGBtoYUV( P0 );
+			float i5 = RGBtoYUV( I5 ); float p1 = RGBtoYUV( P1 );
+			float h5 = RGBtoYUV( H5 ); float p2 = RGBtoYUV( P2 );
+			float f4 = RGBtoYUV( F4 ); float p3 = RGBtoYUV( P3 );
+
+/*
+                              P1
+     |P0|B |C |P1|         C     F4          |a0|b1|c2|d3|
+     |D |E |F |F4|      B     F     I4       |b0|c1|d2|e3|   |e1|i1|i2|e2|
+     |G |H |I |I4|   P0    E  A  I     P3    |c0|d1|e2|f3|   |e3|i3|i4|e4|
+     |P2|H5|I5|P3|      D     H     I5       |d0|e1|f2|g3|
+                           G     H5
+                              P2
+*/
+
+			/* Calc edgeness in diagonal directions. */
+			float d_edge  = (d_wd( d, b, g, e, c, p2, h, f, p1, h5, i, f4, i5, i4 ) - d_wd( c, f4, b, f, i4, p0, e, i, p3, d, h, i5, g, h5 ));
+
+			/* Calc edgeness in horizontal/vertical directions. */
+			float hv_edge = (hv_wd(f, i, e, h, c, i5, b, h5) - hv_wd(e, f, h, i, d, f4, g, i4));
+
+			float limits = XBR_EDGE_STR + 0.000001;
+			float edge_strength = smoothstep(0.0, limits, abs(d_edge));
+
+			/* Filter weights. Two taps only. */
+			vec4 w1 = vec4(-weight1, weight1+0.5, weight1+0.5, -weight1);
+			vec4 w2 = vec4(-weight2, weight2+0.25, weight2+0.25, -weight2);
+
+			/* Filtering and normalization in four direction generating four colors. */
+			vec3 c1 = mul(w1, mat4x3( P2,   H,   F,   P1 ));
+			vec3 c2 = mul(w1, mat4x3( P0,   E,   I,   P3 ));
+			vec3 c3 = mul(w2, mat4x3(D+G, E+H, F+I, F4+I4));
+			vec3 c4 = mul(w2, mat4x3(C+B, F+E, I+H, I5+H5));
+
+			//bool ir_lv1 = (((e!=f) && (e!=h))  && ( !eq(f,b) && !eq(f,c) || !eq(h,d) && !eq(h,g) || eq(e,i) && (!eq(f,f4) && !eq(f,i4) || !eq(h,h5) && !eq(h,i5)) || eq(e,g) || eq(e,c)) );
+
+
+			/* Smoothly blends the two strongest directions (one in diagonal and the other in vert/horiz direction). */
+			vec3 color =  mix(mix(c1, c2, step(0.0, d_edge)), mix(c3, c4, step(0.0, hv_edge)), 1. - edge_strength);
+
+/*
+                              P1
+     |P0|B |C |P1|         C     F4          |a0|b1|c2|d3|
+     |D |E |F |F4|      B     F     I4       |b0|c1|d2|e3|   |e1|i1|i2|e2|
+     |G |H |I |I4|   P0    E  A  I     P3    |c0|d1|e2|f3|   |e3|i3|i4|e4|
+     |P2|H5|I5|P3|      D     H     I5       |d0|e1|f2|g3|
+                           G     H5
+                              P2
+*/
+
+			/* Anti-ringing code. */
+			vec3 min_sample = min4( E, F, H, I ) + (1.-XBR_ANTI_RINGING)*mix((P2-H)*(F-P1), (P0-E)*(I-P3), step(0.0, d_edge));
+			vec3 max_sample = max4( E, F, H, I ) - (1.-XBR_ANTI_RINGING)*mix((P2-H)*(F-P1), (P0-E)*(I-P3), step(0.0, d_edge));
+
+			color = clamp(color, min_sample, max_sample);
+
+			color = (block_3d) ? color : E;
+
+			FragColor = vec4(color, 1.0);
+		}
+} 
+#endif
diff --git a/base/xbr/shaders/super-xbr/super-4xbr-3d-pass1.glsl b/base/xbr/shaders/super-xbr/super-4xbr-3d-pass1.glsl
new file mode 100644
index 0000000..18a7e6e
--- /dev/null
+++ b/base/xbr/shaders/super-xbr/super-4xbr-3d-pass1.glsl
@@ -0,0 +1,304 @@
+#version 130
+
+/*
+   
+  *******  Super 4XBR 3D Shader - pass1  *******
+   
+  Copyright (c) 2016 Hyllian - sergiogdb at gmail.com
+
+  Permission is hereby granted, free of charge, to any person obtaining a copy
+  of this software and associated documentation files (the "Software"), to deal
+  in the Software without restriction, including without limitation the rights
+  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+  copies of the Software, and to permit persons to whom the Software is
+  furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included in
+  all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+  THE SOFTWARE.
+
+*/
+
+#define mul(a,b) (b*a)
+
+#define wp1  8.0
+#define wp2  0.0
+#define wp3  0.0
+#define wp4  0.0
+#define wp5  0.0
+#define wp6  0.0
+
+#define XBR_RES 4.0
+
+#define weight1 (XBR_WEIGHT*1.75068/10.0)
+#define weight2 (XBR_WEIGHT*1.29633/10.0/2.0)
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 TEX0;
+COMPAT_VARYING vec4 t1;
+COMPAT_VARYING vec4 t2;
+COMPAT_VARYING vec4 t3;
+COMPAT_VARYING vec4 t4;
+
+vec4 _oPosition1; 
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize)
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    TEX0.xy = TexCoord.xy * 1.0001;
+   float dx = SourceSize.z;
+   float dy = SourceSize.w;
+   t1 = vTexCoord.xyxy + vec4(-2.0*dx, -2.0*dy, dx, dy);
+   t2 = vTexCoord.xyxy + vec4(    -dx, -2.0*dy,  0, dy);
+   t3 = vTexCoord.xyxy + vec4(-2.0*dx,     -dy, dx,  0);
+   t4 = vTexCoord.xyxy + vec4(    -dx,     -dy,  0,  0);
+}
+
+#elif defined(FRAGMENT)
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out COMPAT_PRECISION vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+uniform sampler2D OrigTexture;
+COMPAT_VARYING vec4 TEX0;
+COMPAT_VARYING vec4 t1;
+COMPAT_VARYING vec4 t2;
+COMPAT_VARYING vec4 t3;
+COMPAT_VARYING vec4 t4;
+
+// compatibility #defines
+#define Source Texture
+#define Original OrigTexture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutputSize vec4(OutputSize, 1.0 / OutputSize)
+
+const float XBR_EDGE_STR = 0.0;
+const float XBR_WEIGHT = 0.0;
+const float XBR_ANTI_RINGING = 0.0;
+
+const vec3 Y = vec3(.2126, .7152, .0722);
+
+const vec3 dtt = vec3(65536.,255.,1.);
+
+vec4 reduce4(vec3 A, vec3 B, vec3 C, vec3 D)
+{
+  return mul(mat4x3(A, B, C, D), dtt);
+}
+
+float RGBtoYUV(vec3 color)
+{
+  return dot(color, Y);
+}
+
+float df(float A, float B)
+{
+  return abs(A-B);
+}
+
+bool eq(float A, float B)
+{
+	return (df(A, B) < 15.0);
+}
+
+/*
+                              P1
+     |P0|B |C |P1|         C     F4          |a0|b1|c2|d3|
+     |D |E |F |F4|      B     F     I4       |b0|c1|d2|e3|   |e1|i1|i2|e2|
+     |G |H |I |I4|   P0    E  A  I     P3    |c0|d1|e2|f3|   |e3|i3|i4|e4|
+     |P2|H5|I5|P3|      D     H     I5       |d0|e1|f2|g3|
+                           G     H5
+                              P2
+*/
+
+float d_wd(float b0, float b1, float c0, float c1, float c2, float d0, float d1, float d2, float d3, float e1, float e2, float e3, float f2, float f3)
+{
+	return (wp1*(df(c1,c2) + df(c1,c0) + df(e2,e1) + df(e2,e3)) + wp2*(df(d2,d3) + df(d0,d1)) + wp3*(df(d1,d3) + df(d0,d2)) + wp4*df(d1,d2) + wp5*(df(c0,c2) + df(e1,e3)) + wp6*(df(b0,b1) + df(f2,f3)));
+}
+
+float hv_wd(float i1, float i2, float i3, float i4, float e1, float e2, float e3, float e4)
+{
+	return ( wp4*(df(i1,i2)+df(i3,i4)) + wp1*(df(i1,e1)+df(i2,e2)+df(i3,e3)+df(i4,e4)) + wp3*(df(i1,e2)+df(i3,e4)+df(e1,i2)+df(e3,i4)));
+}
+
+vec3 min4(vec3 a, vec3 b, vec3 c, vec3 d)
+{
+    return min(a, min(b, min(c, d)));
+}
+vec3 max4(vec3 a, vec3 b, vec3 c, vec3 d)
+{
+    return max(a, max(b, max(c, d)));
+}
+
+void main()
+{
+	//Skip pixels on wrong grid
+	vec2 dir = fract(vTexCoord*TextureSize/XBR_RES) - vec2(0.5,0.5);
+ 	if ((dir.x*dir.y)>0.0){ FragColor = COMPAT_TEXTURE(Source, vTexCoord);
+      return;}
+      else{
+
+	vec2 tex = (floor(vTexCoord*TextureSize/XBR_RES) + vec2(0.5, 0.5))*XBR_RES/TextureSize;
+
+	vec2 g1 = vec2((XBR_RES/2.0)/TextureSize.x, 0.0);
+	vec2 g2 = vec2(0.0, (XBR_RES/2.0)/TextureSize.y);
+
+	vec3 P0 = COMPAT_TEXTURE(Source, vTexCoord -3.0*g1       ).xyz;
+	vec3 P1 = COMPAT_TEXTURE(Source, vTexCoord        -3.0*g2).xyz;
+	vec3 P2 = COMPAT_TEXTURE(Source, vTexCoord        +3.0*g2).xyz;
+	vec3 P3 = COMPAT_TEXTURE(Source, vTexCoord +3.0*g1       ).xyz;
+
+	vec3 B = COMPAT_TEXTURE(Source, vTexCoord -2.0*g1     -g2).xyz;
+	vec3 C = COMPAT_TEXTURE(Source, vTexCoord     -g1 -2.0*g2).xyz;
+	vec3 D = COMPAT_TEXTURE(Source, vTexCoord -2.0*g1     +g2).xyz;
+	vec3 E = COMPAT_TEXTURE(Source, vTexCoord     -g1        ).xyz;
+	vec3 F = COMPAT_TEXTURE(Source, vTexCoord             -g2).xyz;
+	vec3 G = COMPAT_TEXTURE(Source, vTexCoord     -g1 +2.0*g2).xyz;
+	vec3 H = COMPAT_TEXTURE(Source, vTexCoord             +g2).xyz;
+	vec3 I = COMPAT_TEXTURE(Source, vTexCoord     +g1        ).xyz;
+
+	vec3 F4 = COMPAT_TEXTURE(Source, vTexCoord     +g1 -2.0*g2).xyz;
+	vec3 I4 = COMPAT_TEXTURE(Source, vTexCoord +2.0*g1     -g2).xyz;
+	vec3 H5 = COMPAT_TEXTURE(Source, vTexCoord     +g1 +2.0*g2).xyz;
+	vec3 I5 = COMPAT_TEXTURE(Source, vTexCoord +2.0*g1     +g2).xyz;
+
+	vec3 A = COMPAT_TEXTURE(Source, vTexCoord).xyz;
+
+	g1 *= 2.0;
+	g2 *= 2.0;
+
+	vec3 F6 = COMPAT_TEXTURE(Original, tex +g1+0.25*g1+0.25*g2).xyz;
+	vec3 F7 = COMPAT_TEXTURE(Original, tex +g1+0.25*g1-0.25*g2).xyz;
+	vec3 F8 = COMPAT_TEXTURE(Original, tex +g1-0.25*g1-0.25*g2).xyz;
+	vec3 F9 = COMPAT_TEXTURE(Original, tex +g1-0.25*g1+0.25*g2).xyz;
+
+	vec3 H6 = COMPAT_TEXTURE(Original, tex +0.25*g1+0.25*g2+g2).xyz;
+	vec3 H7 = COMPAT_TEXTURE(Original, tex +0.25*g1-0.25*g2+g2).xyz;
+	vec3 H8 = COMPAT_TEXTURE(Original, tex -0.25*g1-0.25*g2+g2).xyz;
+	vec3 H9 = COMPAT_TEXTURE(Original, tex -0.25*g1+0.25*g2+g2).xyz;
+
+	vec4 f0 = reduce4(F6, F7, F8, F9);
+	vec4 h0 = reduce4(H6, H7, H8, H9);
+
+   bool block_3d = ((f0.xyz==f0.yzw) && (h0.xyz==h0.yzw));
+
+	float b = RGBtoYUV( B );
+	float c = RGBtoYUV( C );
+	float d = RGBtoYUV( D );
+	float e = RGBtoYUV( E );
+	float f = RGBtoYUV( F );
+	float g = RGBtoYUV( G );
+	float h = RGBtoYUV( H );
+	float i = RGBtoYUV( I );
+
+	float i4 = RGBtoYUV( I4 ); float p0 = RGBtoYUV( P0 );
+	float i5 = RGBtoYUV( I5 ); float p1 = RGBtoYUV( P1 );
+	float h5 = RGBtoYUV( H5 ); float p2 = RGBtoYUV( P2 );
+	float f4 = RGBtoYUV( F4 ); float p3 = RGBtoYUV( P3 );
+	
+/*
+                              P1
+     |P0|B |C |P1|         C     F4          |a0|b1|c2|d3|
+     |D |E |F |F4|      B     F     I4       |b0|c1|d2|e3|   |e1|i1|i2|e2|
+     |G |H |I |I4|   P0    E  A  I     P3    |c0|d1|e2|f3|   |e3|i3|i4|e4|
+     |P2|H5|I5|P3|      D     H     I5       |d0|e1|f2|g3|
+                           G     H5
+                              P2
+*/
+
+	/* Calc edgeness in diagonal directions. */
+	float d_edge  = (d_wd( d, b, g, e, c, p2, h, f, p1, h5, i, f4, i5, i4 ) - d_wd( c, f4, b, f, i4, p0, e, i, p3, d, h, i5, g, h5 ));
+
+	/* Calc edgeness in horizontal/vertical directions. */
+	float hv_edge = (hv_wd(f, i, e, h, c, i5, b, h5) - hv_wd(e, f, h, i, d, f4, g, i4));
+
+	float limits = XBR_EDGE_STR + 0.000001;
+	float edge_strength = smoothstep(0.0, limits, abs(d_edge));
+
+	/* Filter weights. Two taps only. */
+	vec4 w1 = vec4(-weight1, weight1+0.5, weight1+0.5, -weight1);
+	vec4 w2 = vec4(-weight2, weight2+0.25, weight2+0.25, -weight2);
+
+	/* Filtering and normalization in four direction generating four colors. */
+   vec3 c1 = mul(w1, mat4x3( P2,   H,   F,   P1 ));
+   vec3 c2 = mul(w1, mat4x3( P0,   E,   I,   P3 ));
+	vec3 c3 = mul(w2, mat4x3(D+G, E+H, F+I, F4+I4));
+   vec3 c4 = mul(w2, mat4x3(C+B, F+E, I+H, I5+H5));
+
+	//bool ir_lv1 = (((e!=f) && (e!=h))  && ( !eq(f,b) && !eq(f,c) || !eq(h,d) && !eq(h,g) || eq(e,i) && (!eq(f,f4) && !eq(f,i4) || !eq(h,h5) && !eq(h,i5)) || eq(e,g) || eq(e,c)) );
+
+	/* Smoothly blends the two strongest directions (one in diagonal and the other in vert/horiz direction). */
+	vec3 color =  mix(mix(c1, c2, step(0.0, d_edge)), mix(c3, c4, step(0.0, hv_edge)), 1. - edge_strength);
+
+	/* Anti-ringing code. */
+	vec3 min_sample = min4( E, F, H, I ) + (1.-XBR_ANTI_RINGING)*mix((P2-H)*(F-P1), (P0-E)*(I-P3), step(0.0, d_edge));
+	vec3 max_sample = max4( E, F, H, I ) - (1.-XBR_ANTI_RINGING)*mix((P2-H)*(F-P1), (P0-E)*(I-P3), step(0.0, d_edge));
+
+	color = clamp(color, min_sample, max_sample);
+
+	color = (block_3d) ? color : A;
+
+	FragColor = vec4(color, 1.0);
+   }
+} 
+#endif
diff --git a/base/xbr/shaders/super-xbr/super-4xbr-3d-pass1f.glsl b/base/xbr/shaders/super-xbr/super-4xbr-3d-pass1f.glsl
new file mode 100644
index 0000000..d4841e5
--- /dev/null
+++ b/base/xbr/shaders/super-xbr/super-4xbr-3d-pass1f.glsl
@@ -0,0 +1,297 @@
+#version 130
+
+/*
+   
+  *******  Super 4XBR 3D Shader - pass1  *******
+   
+  Copyright (c) 2016 Hyllian - sergiogdb at gmail.com
+
+  Permission is hereby granted, free of charge, to any person obtaining a copy
+  of this software and associated documentation files (the "Software"), to deal
+  in the Software without restriction, including without limitation the rights
+  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+  copies of the Software, and to permit persons to whom the Software is
+  furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included in
+  all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+  THE SOFTWARE.
+
+*/
+
+#define mul(a,b) (b*a)
+
+#define XBR_RES 4.0
+
+#define wp1  1.0
+#define wp2  0.0
+#define wp3  2.0
+#define wp4  3.0
+#define wp5 -2.0
+#define wp6  1.0
+
+#define weight1 (XBR_WEIGHT*1.29633/10.0)
+#define weight2 (XBR_WEIGHT*1.75068/10.0/2.0)
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 TEX0;
+COMPAT_VARYING vec4 t1;
+COMPAT_VARYING vec4 t2;
+COMPAT_VARYING vec4 t3;
+COMPAT_VARYING vec4 t4;
+
+vec4 _oPosition1; 
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize)
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    TEX0.xy = TexCoord.xy * 1.0001;
+   float dx = SourceSize.z;
+   float dy = SourceSize.w;
+   t1 = vTexCoord.xyxy + vec4(-2.0*dx, -2.0*dy, dx, dy);
+   t2 = vTexCoord.xyxy + vec4(    -dx, -2.0*dy,  0, dy);
+   t3 = vTexCoord.xyxy + vec4(-2.0*dx,     -dy, dx,  0);
+   t4 = vTexCoord.xyxy + vec4(    -dx,     -dy,  0,  0);
+}
+
+#elif defined(FRAGMENT)
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out COMPAT_PRECISION vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+uniform sampler2D OrigTexture;
+COMPAT_VARYING vec4 TEX0;
+COMPAT_VARYING vec4 t1;
+COMPAT_VARYING vec4 t2;
+COMPAT_VARYING vec4 t3;
+COMPAT_VARYING vec4 t4;
+
+// compatibility #defines
+#define Source Texture
+#define Original OrigTexture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutputSize vec4(OutputSize, 1.0 / OutputSize)
+
+const float XBR_EDGE_STR = 0.0;
+const float XBR_WEIGHT = 0.0;
+const float XBR_ANTI_RINGING = 0.0;
+
+const vec3 Y = vec3(.2126, .7152, .0722);
+
+const vec3 dtt = vec3(65536.,255.,1.);
+
+vec4 reduce4(vec3 A, vec3 B, vec3 C, vec3 D)
+{
+  return mul(mat4x3(A, B, C, D), dtt);
+}
+
+float RGBtoYUV(vec3 color)
+{
+  return dot(color, Y);
+}
+
+float df(float A, float B)
+{
+  return abs(A-B);
+}
+
+bool eq(float A, float B)
+{
+	return (df(A, B) < 15.0);
+}
+
+/*
+                              P1
+     |P0|B |C |P1|         C     F4          |a0|b1|c2|d3|
+     |D |E |F |F4|      B     F     I4       |b0|c1|d2|e3|   |e1|i1|i2|e2|
+     |G |H |I |I4|   P0    E  A  I     P3    |c0|d1|e2|f3|   |e3|i3|i4|e4|
+     |P2|H5|I5|P3|      D     H     I5       |d0|e1|f2|g3|
+                           G     H5
+                              P2
+*/
+
+float d_wd(float b0, float b1, float c0, float c1, float c2, float d0, float d1, float d2, float d3, float e1, float e2, float e3, float f2, float f3)
+{
+	return (wp1*(df(c1,c2) + df(c1,c0) + df(e2,e1) + df(e2,e3)) + wp2*(df(d2,d3) + df(d0,d1)) + wp3*(df(d1,d3) + df(d0,d2)) + wp4*df(d1,d2) + wp5*(df(c0,c2) + df(e1,e3)) + wp6*(df(b0,b1) + df(f2,f3)));
+}
+
+float hv_wd(float i1, float i2, float i3, float i4, float e1, float e2, float e3, float e4)
+{
+	return ( wp4*(df(i1,i2)+df(i3,i4)) + wp1*(df(i1,e1)+df(i2,e2)+df(i3,e3)+df(i4,e4)) + wp3*(df(i1,e2)+df(i3,e4)+df(e1,i2)+df(e3,i4)));
+}
+
+vec3 min4(vec3 a, vec3 b, vec3 c, vec3 d)
+{
+    return min(a, min(b, min(c, d)));
+}
+vec3 max4(vec3 a, vec3 b, vec3 c, vec3 d)
+{
+    return max(a, max(b, max(c, d)));
+}
+
+void main()
+{
+	vec2 tex = (floor(vTexCoord*TextureSize/XBR_RES) + vec2(0.5, 0.5))*XBR_RES/TextureSize;
+
+	vec2 g1 = vec2(XBR_RES/TextureSize.x, 0.0);
+	vec2 g2 = vec2(0.0, XBR_RES/TextureSize.y);
+
+	vec3 P0 = COMPAT_TEXTURE(Source, t1.xy).xyz;
+	vec3 P1 = COMPAT_TEXTURE(Source, t1.zy).xyz;
+	vec3 P2 = COMPAT_TEXTURE(Source, t1.xw).xyz;
+	vec3 P3 = COMPAT_TEXTURE(Source, t1.zw).xyz;
+
+	vec3  B = COMPAT_TEXTURE(Source, t2.xy).xyz;
+	vec3  C = COMPAT_TEXTURE(Source, t2.zy).xyz;
+	vec3 H5 = COMPAT_TEXTURE(Source, t2.xw).xyz;
+	vec3 I5 = COMPAT_TEXTURE(Source, t2.zw).xyz;
+
+	vec3  D = COMPAT_TEXTURE(Source, t3.xy).xyz;
+	vec3 F4 = COMPAT_TEXTURE(Source, t3.zy).xyz;
+	vec3  G = COMPAT_TEXTURE(Source, t3.xw).xyz;
+	vec3 I4 = COMPAT_TEXTURE(Source, t3.zw).xyz;
+
+	vec3  E = COMPAT_TEXTURE(Source, t4.xy).xyz;
+	vec3  F = COMPAT_TEXTURE(Source, t4.zy).xyz;
+	vec3  H = COMPAT_TEXTURE(Source, t4.xw).xyz;
+	vec3  I = COMPAT_TEXTURE(Source, t4.zw).xyz;
+
+	vec3 A = COMPAT_TEXTURE(Source, vTexCoord).xyz;
+
+	vec3 F6 = COMPAT_TEXTURE(Original, tex +g1+0.25*g1+0.25*g2).xyz;
+	vec3 F7 = COMPAT_TEXTURE(Original, tex +g1+0.25*g1-0.25*g2).xyz;
+	vec3 F8 = COMPAT_TEXTURE(Original, tex +g1-0.25*g1-0.25*g2).xyz;
+	vec3 F9 = COMPAT_TEXTURE(Original, tex +g1-0.25*g1+0.25*g2).xyz;
+
+	vec3 H6 = COMPAT_TEXTURE(Original, tex +0.25*g1+0.25*g2+g2).xyz;
+	vec3 H7 = COMPAT_TEXTURE(Original, tex +0.25*g1-0.25*g2+g2).xyz;
+	vec3 H8 = COMPAT_TEXTURE(Original, tex -0.25*g1-0.25*g2+g2).xyz;
+	vec3 H9 = COMPAT_TEXTURE(Original, tex -0.25*g1+0.25*g2+g2).xyz;
+
+	vec4 f0 = reduce4(F6, F7, F8, F9);
+	vec4 h0 = reduce4(H6, H7, H8, H9);
+
+   bool block_3d = ((f0.xyz==f0.yzw) && (h0.xyz==h0.yzw));
+
+	float b = RGBtoYUV( B );
+	float c = RGBtoYUV( C );
+	float d = RGBtoYUV( D );
+	float e = RGBtoYUV( E );
+	float f = RGBtoYUV( F );
+	float g = RGBtoYUV( G );
+	float h = RGBtoYUV( H );
+	float i = RGBtoYUV( I );
+
+	float i4 = RGBtoYUV( I4 ); float p0 = RGBtoYUV( P0 );
+	float i5 = RGBtoYUV( I5 ); float p1 = RGBtoYUV( P1 );
+	float h5 = RGBtoYUV( H5 ); float p2 = RGBtoYUV( P2 );
+	float f4 = RGBtoYUV( F4 ); float p3 = RGBtoYUV( P3 );
+
+/*
+                              P1
+     |P0|B |C |P1|         C     F4          |a0|b1|c2|d3|
+     |D |E |F |F4|      B     F     I4       |b0|c1|d2|e3|   |e1|i1|i2|e2|
+     |G |H |I |I4|   P0    E  A  I     P3    |c0|d1|e2|f3|   |e3|i3|i4|e4|
+     |P2|H5|I5|P3|      D     H     I5       |d0|e1|f2|g3|
+                           G     H5
+                              P2
+*/
+
+
+	/* Calc edgeness in diagonal directions. */
+	float d_edge  = (d_wd( d, b, g, e, c, p2, h, f, p1, h5, i, f4, i5, i4 ) - d_wd( c, f4, b, f, i4, p0, e, i, p3, d, h, i5, g, h5 ));
+
+	/* Calc edgeness in horizontal/vertical directions. */
+	float hv_edge = (hv_wd(f, i, e, h, c, i5, b, h5) - hv_wd(e, f, h, i, d, f4, g, i4));
+
+	float limits = XBR_EDGE_STR + 0.000001;
+	float edge_strength = smoothstep(0.0, limits, abs(d_edge));
+
+	/* Filter weights. Two taps only. */
+	vec4 w1 = vec4(-weight1, weight1+0.5, weight1+0.5, -weight1);
+	vec4 w2 = vec4(-weight2, weight2+0.25, weight2+0.25, -weight2);
+
+	/* Filtering and normalization in four direction generating four colors. */
+   vec3 c1 = mul(w1, mat4x3( P2,   H,   F,   P1 ));
+   vec3 c2 = mul(w1, mat4x3( P0,   E,   I,   P3 ));
+	vec3 c3 = mul(w2, mat4x3(D+G, E+H, F+I, F4+I4));
+   vec3 c4 = mul(w2, mat4x3(C+B, F+E, I+H, I5+H5));
+
+	//bool ir_lv1 = (((e!=f) && (e!=h))  && ( !eq(f,b) && !eq(f,c) || !eq(h,d) && !eq(h,g) || eq(e,i) && (!eq(f,f4) && !eq(f,i4) || !eq(h,h5) && !eq(h,i5)) || eq(e,g) || eq(e,c)) );
+
+
+	/* Smoothly blends the two strongest directions (one in diagonal and the other in vert/horiz direction). */
+	vec3 color =  mix(mix(c1, c2, step(0.0, d_edge)), mix(c3, c4, step(0.0, hv_edge)), 1. - edge_strength);
+
+	/* Anti-ringing code. */
+	vec3 min_sample = min4( E, F, H, I ) + (1-XBR_ANTI_RINGING)*mix((P2-H)*(F-P1), (P0-E)*(I-P3), step(0.0, d_edge));
+	vec3 max_sample = max4( E, F, H, I ) - (1-XBR_ANTI_RINGING)*mix((P2-H)*(F-P1), (P0-E)*(I-P3), step(0.0, d_edge));
+
+	color = clamp(color, min_sample, max_sample);
+
+	color = (block_3d) ? color : A;
+
+	FragColor = vec4(color, 1.0);	
+} 
+#endif
diff --git a/base/xbr/shaders/super-xbr/super-4xbr-3d-pass2.glsl b/base/xbr/shaders/super-xbr/super-4xbr-3d-pass2.glsl
new file mode 100644
index 0000000..cc5d545
--- /dev/null
+++ b/base/xbr/shaders/super-xbr/super-4xbr-3d-pass2.glsl
@@ -0,0 +1,299 @@
+#version 130
+
+/*
+   
+  *******  Super 4XBR Shader - pass2  ******* 
+   
+  Copyright (c) 2015 Hyllian - sergiogdb at gmail.com
+
+  Permission is hereby granted, free of charge, to any person obtaining a copy
+  of this software and associated documentation files (the "Software"), to deal
+  in the Software without restriction, including without limitation the rights
+  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+  copies of the Software, and to permit persons to whom the Software is
+  furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included in
+  all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+  THE SOFTWARE.
+
+*/
+
+#define mul(a,b) (b*a)
+
+#define wp1  2.0
+#define wp2  1.0
+#define wp3 -1.0
+#define wp4  4.0
+#define wp5 -1.0
+#define wp6  1.0
+
+#define XBR_RES2  2.0
+
+#define weight1 (XBR_WEIGHT*1.29633/10.0)
+#define weight2 (XBR_WEIGHT*1.75068/10.0/2.0)
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 TEX0;
+
+vec4 _oPosition1; 
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    TEX0.xy = TexCoord.xy * 1.0001;
+}
+
+#elif defined(FRAGMENT)
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out COMPAT_PRECISION vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+uniform sampler2D OrigTexture;
+COMPAT_VARYING vec4 TEX0;
+
+// compatibility #defines
+#define Source Texture
+#define Original OrigTexture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutputSize vec4(OutputSize, 1.0 / OutputSize)
+
+#ifdef PARAMETER_UNIFORM
+uniform COMPAT_PRECISION float XBR_EDGE_STR;
+uniform COMPAT_PRECISION float XBR_WEIGHT;
+uniform COMPAT_PRECISION float XBR_ANTI_RINGING;
+#else
+#define XBR_EDGE_STR 0.0
+#define XBR_WEIGHT 0.0
+#define XBR_ANTI_RINGING 0.0
+#endif
+
+const vec3 Y = vec3(.2126, .7152, .0722);
+
+const vec3 dtt = vec3(65536.,255.,1.);
+
+vec4 reduce4(vec3 A, vec3 B, vec3 C, vec3 D)
+{
+  return mul(mat4x3(A, B, C, D), dtt);
+}
+
+float RGBtoYUV(vec3 color)
+{
+  return dot(color, Y);
+}
+
+float df(float A, float B)
+{
+  return abs(A-B);
+}
+
+bool eq(float A, float B)
+{
+	return (df(A, B) < 15.0);
+}
+
+/*
+                              P1
+     |P0|B |C |P1|         C     F4          |a0|b1|c2|d3|
+     |D |E |F |F4|      B     F     I4       |b0|c1|d2|e3|   |e1|i1|i2|e2|
+     |G |H |I |I4|   P0    E  A  I     P3    |c0|d1|e2|f3|   |e3|i3|i4|e4|
+     |P2|H5|I5|P3|      D     H     I5       |d0|e1|f2|g3|
+                           G     H5
+                              P2
+*/
+
+float d_wd(float b0, float b1, float c0, float c1, float c2, float d0, float d1, float d2, float d3, float e1, float e2, float e3, float f2, float f3)
+{
+	return (wp1*(df(c1,c2) + df(c1,c0) + df(e2,e1) + df(e2,e3)) + wp2*(df(d2,d3) + df(d0,d1)) + wp3*(df(d1,d3) + df(d0,d2)) + wp4*df(d1,d2) + wp5*(df(c0,c2) + df(e1,e3)) + wp6*(df(b0,b1) + df(f2,f3)));
+}
+
+float hv_wd(float i1, float i2, float i3, float i4, float e1, float e2, float e3, float e4)
+{
+	return ( wp4*(df(i1,i2)+df(i3,i4)) + wp1*(df(i1,e1)+df(i2,e2)+df(i3,e3)+df(i4,e4)) + wp3*(df(i1,e2)+df(i3,e4)+df(e1,i2)+df(e3,i4)));
+}
+
+vec3 min4(vec3 a, vec3 b, vec3 c, vec3 d)
+{
+    return min(a, min(b, min(c, d)));
+}
+vec3 max4(vec3 a, vec3 b, vec3 c, vec3 d)
+{
+    return max(a, max(b, max(c, d)));
+}
+
+void main()
+{
+	//Skip pixels on wrong grid
+ 	if (any(lessThan(fract(vTexCoord*TextureSize/XBR_RES2),vec2(0.5,0.5)))){ FragColor = COMPAT_TEXTURE(Source, vTexCoord); return;}
+
+	vec2 tex = (floor(vTexCoord*TextureSize/XBR_RES2) + vec2(0.5, 0.5))*XBR_RES2/TextureSize;
+
+	vec2 g1 = vec2(XBR_RES2/TextureSize.x, 0.0);
+	vec2 g2 = vec2(0.0, XBR_RES2/TextureSize.y);
+
+	vec3 P0 = COMPAT_TEXTURE(Source, vTexCoord     -g1    -g2).xyz;
+	vec3 P1 = COMPAT_TEXTURE(Source, vTexCoord +2.0*g1    -g2).xyz;
+	vec3 P2 = COMPAT_TEXTURE(Source, vTexCoord     -g1+2.0*g2).xyz;
+	vec3 P3 = COMPAT_TEXTURE(Source, vTexCoord +2.0*g1+2.0*g2).xyz;
+
+	vec3  B = COMPAT_TEXTURE(Source, vTexCoord    -g2).xyz;
+	vec3  C = COMPAT_TEXTURE(Source, vTexCoord +g1-g2).xyz;
+	vec3  D = COMPAT_TEXTURE(Source, vTexCoord -g1   ).xyz;
+	vec3  E = COMPAT_TEXTURE(Source, vTexCoord       ).xyz;
+	vec3  F = COMPAT_TEXTURE(Source, vTexCoord +g1   ).xyz;
+	vec3  G = COMPAT_TEXTURE(Source, vTexCoord -g1+g2).xyz;
+	vec3  H = COMPAT_TEXTURE(Source, vTexCoord    +g2).xyz;
+	vec3  I = COMPAT_TEXTURE(Source, vTexCoord +g1+g2).xyz;
+
+	vec3 F4 = COMPAT_TEXTURE(Source,vTexCoord    +2.0*g1   ).xyz;
+	vec3 I4 = COMPAT_TEXTURE(Source,vTexCoord +g2+2.0*g1   ).xyz;
+	vec3 H5 = COMPAT_TEXTURE(Source,vTexCoord +2.0*g2      ).xyz;
+	vec3 I5 = COMPAT_TEXTURE(Source,vTexCoord +2.0*g2+g1   ).xyz;
+
+	vec3 F6 = COMPAT_TEXTURE(Source, tex +g1+0.25*g1+0.25*g2).xyz;
+	vec3 F7 = COMPAT_TEXTURE(Source, tex +g1+0.25*g1-0.25*g2).xyz;
+	vec3 F8 = COMPAT_TEXTURE(Source, tex +g1-0.25*g1-0.25*g2).xyz;
+	vec3 F9 = COMPAT_TEXTURE(Source, tex +g1-0.25*g1+0.25*g2).xyz;
+
+	vec3 H6 = COMPAT_TEXTURE(Source, tex +0.25*g1+0.25*g2+g2).xyz;
+	vec3 H7 = COMPAT_TEXTURE(Source, tex +0.25*g1-0.25*g2+g2).xyz;
+	vec3 H8 = COMPAT_TEXTURE(Source, tex -0.25*g1-0.25*g2+g2).xyz;
+	vec3 H9 = COMPAT_TEXTURE(Source, tex -0.25*g1+0.25*g2+g2).xyz;
+
+	vec4 f0 = reduce4(F6, F7, F8, F9);
+	vec4 h0 = reduce4(H6, H7, H8, H9);
+
+   bool block_3d = ((f0.xyz==f0.yzw) && (h0.xyz==h0.yzw));
+
+
+	float b = RGBtoYUV( B );
+	float c = RGBtoYUV( C );
+	float d = RGBtoYUV( D );
+	float e = RGBtoYUV( E );
+	float f = RGBtoYUV( F );
+	float g = RGBtoYUV( G );
+	float h = RGBtoYUV( H );
+	float i = RGBtoYUV( I );
+
+	float i4 = RGBtoYUV( I4 ); float p0 = RGBtoYUV( P0 );
+	float i5 = RGBtoYUV( I5 ); float p1 = RGBtoYUV( P1 );
+	float h5 = RGBtoYUV( H5 ); float p2 = RGBtoYUV( P2 );
+	float f4 = RGBtoYUV( F4 ); float p3 = RGBtoYUV( P3 );
+
+/*
+                              P1
+     |P0|B |C |P1|         C     F4          |a0|b1|c2|d3|
+     |D |E |F |F4|      B     F     I4       |b0|c1|d2|e3|   |e1|i1|i2|e2|
+     |G |H |I |I4|   P0    E  A  I     P3    |c0|d1|e2|f3|   |e3|i3|i4|e4|
+     |P2|H5|I5|P3|      D     H     I5       |d0|e1|f2|g3|
+                           G     H5
+                              P2
+*/
+
+
+	/* Calc edgeness in diagonal directions. */
+	float d_edge  = (d_wd( d, b, g, e, c, p2, h, f, p1, h5, i, f4, i5, i4 ) - d_wd( c, f4, b, f, i4, p0, e, i, p3, d, h, i5, g, h5 ));
+
+	/* Calc edgeness in horizontal/vertical directions. */
+	float hv_edge = (hv_wd(f, i, e, h, c, i5, b, h5) - hv_wd(e, f, h, i, d, f4, g, i4));
+
+	float limits = XBR_EDGE_STR + 0.000001;
+	float edge_strength = smoothstep(0.0, limits, abs(d_edge));
+
+	/* Filter weights. Two taps only. */
+	vec4 w1 = vec4(-weight1, weight1+0.5, weight1+0.5, -weight1);
+	vec4 w2 = vec4(-weight2, weight2+0.25, weight2+0.25, -weight2);
+
+	/* Filtering and normalization in four direction generating four colors. */
+   vec3 c1 = mul(w1, mat4x3( P2,   H,   F,   P1 ));
+   vec3 c2 = mul(w1, mat4x3( P0,   E,   I,   P3 ));
+	vec3 c3 = mul(w2, mat4x3(D+G, E+H, F+I, F4+I4));
+   vec3 c4 = mul(w2, mat4x3(C+B, F+E, I+H, I5+H5));
+
+	//bool ir_lv1 = (((e!=f) && (e!=h))  && ( !eq(f,b) && !eq(f,c) || !eq(h,d) && !eq(h,g) || eq(e,i) && (!eq(f,f4) && !eq(f,i4) || !eq(h,h5) && !eq(h,i5)) || eq(e,g) || eq(e,c)) );
+
+
+	/* Smoothly blends the two strongest directions (one in diagonal and the other in vert/horiz direction). */
+	vec3 color =  mix(mix(c1, c2, step(0.0, d_edge)), mix(c3, c4, step(0.0, hv_edge)), 1. - edge_strength);
+
+/*
+                              P1
+     |P0|B |C |P1|         C     F4          |a0|b1|c2|d3|
+     |D |E |F |F4|      B     F     I4       |b0|c1|d2|e3|   |e1|i1|i2|e2|
+     |G |H |I |I4|   P0    E  A  I     P3    |c0|d1|e2|f3|   |e3|i3|i4|e4|
+     |P2|H5|I5|P3|      D     H     I5       |d0|e1|f2|g3|
+                           G     H5
+                              P2
+*/
+
+
+
+	/* Anti-ringing code. */
+	vec3 min_sample = min4( E, F, H, I ) + (1-XBR_ANTI_RINGING)*mix((P2-H)*(F-P1), (P0-E)*(I-P3), step(0.0, d_edge));
+	vec3 max_sample = max4( E, F, H, I ) - (1-XBR_ANTI_RINGING)*mix((P2-H)*(F-P1), (P0-E)*(I-P3), step(0.0, d_edge));
+
+	color = clamp(color, min_sample, max_sample);
+
+	color = (block_3d) ? color : E;
+
+	FragColor = vec4(color, 1.0);	
+} 
+#endif
diff --git a/base/xbr/shaders/super-xbr/super-4xbr-3d-pass3.glsl b/base/xbr/shaders/super-xbr/super-4xbr-3d-pass3.glsl
new file mode 100644
index 0000000..18fb9a5
--- /dev/null
+++ b/base/xbr/shaders/super-xbr/super-4xbr-3d-pass3.glsl
@@ -0,0 +1,297 @@
+#version 130
+
+/*
+   
+  *******  Super 4XBR Shader - pass3  ******* 
+   
+  Copyright (c) 2015 Hyllian - sergiogdb at gmail.com
+
+  Permission is hereby granted, free of charge, to any person obtaining a copy
+  of this software and associated documentation files (the "Software"), to deal
+  in the Software without restriction, including without limitation the rights
+  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+  copies of the Software, and to permit persons to whom the Software is
+  furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included in
+  all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+  THE SOFTWARE.
+
+*/
+
+#define mul(a,b) (b*a)
+
+#define wp1  8.0
+#define wp2  0.0
+#define wp3  0.0
+#define wp4  0.0
+#define wp5  0.0
+#define wp6  0.0
+
+#define XBR_RES2  2.0
+
+#define weight1 (XBR_WEIGHT*1.75068/10.0)
+#define weight2 (XBR_WEIGHT*1.29633/10.0/2.0)
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 TEX0;
+
+vec4 _oPosition1; 
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    TEX0.xy = TexCoord.xy;
+}
+
+#elif defined(FRAGMENT)
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out COMPAT_PRECISION vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+uniform sampler2D OrigTexture;
+COMPAT_VARYING vec4 TEX0;
+
+// compatibility #defines
+#define Source Texture
+#define Original OrigTexture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutputSize vec4(OutputSize, 1.0 / OutputSize)
+
+const float XBR_EDGE_STR = 0.0;
+const float XBR_WEIGHT = 0.0;
+const float XBR_ANTI_RINGING = 0.0;
+
+const vec3 Y = vec3(.2126, .7152, .0722);
+
+const vec3 dtt = vec3(65536.,255.,1.);
+
+vec4 reduce4(vec3 A, vec3 B, vec3 C, vec3 D)
+{
+  return mul(mat4x3(A, B, C, D), dtt);
+}
+
+float RGBtoYUV(vec3 color)
+{
+  return dot(color, Y);
+}
+
+float df(float A, float B)
+{
+  return abs(A-B);
+}
+
+bool eq(float A, float B)
+{
+	return (df(A, B) < 15.0);
+}
+
+/*
+                              P1
+     |P0|B |C |P1|         C     F4          |a0|b1|c2|d3|
+     |D |E |F |F4|      B     F     I4       |b0|c1|d2|e3|   |e1|i1|i2|e2|
+     |G |H |I |I4|   P0    E  A  I     P3    |c0|d1|e2|f3|   |e3|i3|i4|e4|
+     |P2|H5|I5|P3|      D     H     I5       |d0|e1|f2|g3|
+                           G     H5
+                              P2
+*/
+
+float d_wd(float b0, float b1, float c0, float c1, float c2, float d0, float d1, float d2, float d3, float e1, float e2, float e3, float f2, float f3)
+{
+	return (wp1*(df(c1,c2) + df(c1,c0) + df(e2,e1) + df(e2,e3)) + wp2*(df(d2,d3) + df(d0,d1)) + wp3*(df(d1,d3) + df(d0,d2)) + wp4*df(d1,d2) + wp5*(df(c0,c2) + df(e1,e3)) + wp6*(df(b0,b1) + df(f2,f3)));
+}
+
+float hv_wd(float i1, float i2, float i3, float i4, float e1, float e2, float e3, float e4)
+{
+	return ( wp4*(df(i1,i2)+df(i3,i4)) + wp1*(df(i1,e1)+df(i2,e2)+df(i3,e3)+df(i4,e4)) + wp3*(df(i1,e2)+df(i3,e4)+df(e1,i2)+df(e3,i4)));
+}
+
+vec3 min4(vec3 a, vec3 b, vec3 c, vec3 d)
+{
+    return min(a, min(b, min(c, d)));
+}
+vec3 max4(vec3 a, vec3 b, vec3 c, vec3 d)
+{
+    return max(a, max(b, max(c, d)));
+}
+
+void main()
+{
+	//Skip pixels on wrong grid
+	vec2 dir = fract(vTexCoord*TextureSize/XBR_RES2) - vec2(0.5,0.5);
+ 	if ((dir.x*dir.y)>0.0){ FragColor = COMPAT_TEXTURE(Source, vTexCoord);
+      return;}
+      else{
+
+	vec2 tex = (floor(vTexCoord*TextureSize/XBR_RES2) + vec2(0.5, 0.5))*XBR_RES2/TextureSize;
+
+	vec2 g1 = vec2((XBR_RES2/2.0)/TextureSize.x, 0.0);
+	vec2 g2 = vec2(0.0, (XBR_RES2/2.0)/TextureSize.y);
+
+	vec3 P0 = COMPAT_TEXTURE(Source, vTexCoord -3.0*g1       ).xyz;
+	vec3 P1 = COMPAT_TEXTURE(Source, vTexCoord        -3.0*g2).xyz;
+	vec3 P2 = COMPAT_TEXTURE(Source, vTexCoord        +3.0*g2).xyz;
+	vec3 P3 = COMPAT_TEXTURE(Source, vTexCoord +3.0*g1       ).xyz;
+
+	vec3  B = COMPAT_TEXTURE(Source, vTexCoord -2.0*g1     -g2).xyz;
+	vec3  C = COMPAT_TEXTURE(Source, vTexCoord     -g1 -2.0*g2).xyz;
+	vec3  D = COMPAT_TEXTURE(Source, vTexCoord -2.0*g1     +g2).xyz;
+	vec3  E = COMPAT_TEXTURE(Source, vTexCoord     -g1        ).xyz;
+	vec3  F = COMPAT_TEXTURE(Source, vTexCoord             -g2).xyz;
+	vec3  G = COMPAT_TEXTURE(Source, vTexCoord     -g1 +2.0*g2).xyz;
+	vec3  H = COMPAT_TEXTURE(Source, vTexCoord             +g2).xyz;
+	vec3  I = COMPAT_TEXTURE(Source, vTexCoord     +g1        ).xyz;
+
+	vec3 F4 = COMPAT_TEXTURE(Source, vTexCoord     +g1 -2.0*g2).xyz;
+	vec3 I4 = COMPAT_TEXTURE(Source, vTexCoord +2.0*g1     -g2).xyz;
+	vec3 H5 = COMPAT_TEXTURE(Source, vTexCoord     +g1 +2.0*g2).xyz;
+	vec3 I5 = COMPAT_TEXTURE(Source, vTexCoord +2.0*g1     +g2).xyz;
+
+	vec3  A = COMPAT_TEXTURE(Source, vTexCoord).xyz;
+
+	g1 *= 2.0;
+	g2 *= 2.0;
+
+	vec3 F6 = COMPAT_TEXTURE(Original, tex +g1+0.25*g1+0.25*g2).xyz;
+	vec3 F7 = COMPAT_TEXTURE(Original, tex +g1+0.25*g1-0.25*g2).xyz;
+	vec3 F8 = COMPAT_TEXTURE(Original, tex +g1-0.25*g1-0.25*g2).xyz;
+	vec3 F9 = COMPAT_TEXTURE(Original, tex +g1-0.25*g1+0.25*g2).xyz;
+
+	vec3 H6 = COMPAT_TEXTURE(Original, tex +0.25*g1+0.25*g2+g2).xyz;
+	vec3 H7 = COMPAT_TEXTURE(Original, tex +0.25*g1-0.25*g2+g2).xyz;
+	vec3 H8 = COMPAT_TEXTURE(Original, tex -0.25*g1-0.25*g2+g2).xyz;
+	vec3 H9 = COMPAT_TEXTURE(Original, tex -0.25*g1+0.25*g2+g2).xyz;
+
+	vec4 f0 = reduce4(F6, F7, F8, F9);
+	vec4 h0 = reduce4(H6, H7, H8, H9);
+
+	bool block_3d = ((f0.xyz == f0.yzw) && (h0.xyz == h0.yzw));
+
+	float b = RGBtoYUV( B );
+	float c = RGBtoYUV( C );
+	float d = RGBtoYUV( D );
+	float e = RGBtoYUV( E );
+	float f = RGBtoYUV( F );
+	float g = RGBtoYUV( G );
+	float h = RGBtoYUV( H );
+	float i = RGBtoYUV( I );
+
+	float i4 = RGBtoYUV( I4 ); float p0 = RGBtoYUV( P0 );
+	float i5 = RGBtoYUV( I5 ); float p1 = RGBtoYUV( P1 );
+	float h5 = RGBtoYUV( H5 ); float p2 = RGBtoYUV( P2 );
+	float f4 = RGBtoYUV( F4 ); float p3 = RGBtoYUV( P3 );
+
+/*
+                              P1
+     |P0|B |C |P1|         C     F4          |a0|b1|c2|d3|
+     |D |E |F |F4|      B     F     I4       |b0|c1|d2|e3|   |e1|i1|i2|e2|
+     |G |H |I |I4|   P0    E  A  I     P3    |c0|d1|e2|f3|   |e3|i3|i4|e4|
+     |P2|H5|I5|P3|      D     H     I5       |d0|e1|f2|g3|
+                           G     H5
+                              P2
+*/
+
+	/* Calc edgeness in diagonal directions. */
+	float d_edge  = (d_wd( d, b, g, e, c, p2, h, f, p1, h5, i, f4, i5, i4 ) - d_wd( c, f4, b, f, i4, p0, e, i, p3, d, h, i5, g, h5 ));
+
+	/* Calc edgeness in horizontal/vertical directions. */
+	float hv_edge = (hv_wd(f, i, e, h, c, i5, b, h5) - hv_wd(e, f, h, i, d, f4, g, i4));
+
+	float limits = XBR_EDGE_STR + 0.000001;
+	float edge_strength = smoothstep(0.0, limits, abs(d_edge));
+
+	/* Filter weights. Two taps only. */
+	vec4 w1 = vec4(-weight1, weight1+0.5, weight1+0.5, -weight1);
+	vec4 w2 = vec4(-weight2, weight2+0.25, weight2+0.25, -weight2);
+
+	/* Filtering and normalization in four direction generating four colors. */
+	vec3 c1 = mul(w1, mat4x3( P2,   H,   F,   P1 ));
+	vec3 c2 = mul(w1, mat4x3( P0,   E,   I,   P3 ));
+	vec3 c3 = mul(w2, mat4x3(D+G, E+H, F+I, F4+I4));
+	vec3 c4 = mul(w2, mat4x3(C+B, F+E, I+H, I5+H5));
+
+	//bool ir_lv1 = (((e!=f) && (e!=h))  && ( !eq(f,b) && !eq(f,c) || !eq(h,d) && !eq(h,g) || eq(e,i) && (!eq(f,f4) && !eq(f,i4) || !eq(h,h5) && !eq(h,i5)) || eq(e,g) || eq(e,c)) );
+
+	/* Smoothly blends the two strongest directions (one in diagonal and the other in vert/horiz direction). */
+	vec3 color =  mix(mix(c1, c2, step(0.0, d_edge)), mix(c3, c4, step(0.0, hv_edge)), 1. - edge_strength);
+
+/*
+                              P1
+     |P0|B |C |P1|         C     F4          |a0|b1|c2|d3|
+     |D |E |F |F4|      B     F     I4       |b0|c1|d2|e3|   |e1|i1|i2|e2|
+     |G |H |I |I4|   P0    E  A  I     P3    |c0|d1|e2|f3|   |e3|i3|i4|e4|
+     |P2|H5|I5|P3|      D     H     I5       |d0|e1|f2|g3|
+                           G     H5
+                              P2
+*/
+	
+	/* Anti-ringing code. */
+	vec3 min_sample = min4( E, F, H, I ) + (1.-XBR_ANTI_RINGING)*mix((P2-H)*(F-P1), (P0-E)*(I-P3), step(0.0, d_edge));
+	vec3 max_sample = max4( E, F, H, I ) - (1.-XBR_ANTI_RINGING)*mix((P2-H)*(F-P1), (P0-E)*(I-P3), step(0.0, d_edge));
+
+	color = clamp(color, min_sample, max_sample);
+
+	color = (block_3d) ? color : A;
+
+	FragColor = vec4(color, 1.0);
+	}
+} 
+#endif
diff --git a/base/xbr/shaders/super-xbr/super-4xbr-3d-pass3f.glsl b/base/xbr/shaders/super-xbr/super-4xbr-3d-pass3f.glsl
new file mode 100644
index 0000000..0d8c0c5
--- /dev/null
+++ b/base/xbr/shaders/super-xbr/super-4xbr-3d-pass3f.glsl
@@ -0,0 +1,296 @@
+#version 130
+
+/*
+   
+  *******  Super 4XBR Shader - pass3f  *******  This pass is optional.
+   
+  Copyright (c) 2015 Hyllian - sergiogdb at gmail.com
+
+  Permission is hereby granted, free of charge, to any person obtaining a copy
+  of this software and associated documentation files (the "Software"), to deal
+  in the Software without restriction, including without limitation the rights
+  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+  copies of the Software, and to permit persons to whom the Software is
+  furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included in
+  all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+  THE SOFTWARE.
+
+*/
+
+#define mul(a,b) (b*a)
+
+#define XBR_RES 2.0
+
+#define wp1  1.0
+#define wp2  0.0
+#define wp3  2.0
+#define wp4  3.0
+#define wp5 -2.0
+#define wp6  1.0
+
+#define weight1 (XBR_WEIGHT*1.29633/10.0)
+#define weight2 (XBR_WEIGHT*1.75068/10.0/2.0)
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 TEX0;
+COMPAT_VARYING vec4 t1;
+COMPAT_VARYING vec4 t2;
+COMPAT_VARYING vec4 t3;
+COMPAT_VARYING vec4 t4;
+
+vec4 _oPosition1; 
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+
+#define vTexCoord TEX0.xy
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize)
+
+void main()
+{
+    gl_Position = MVPMatrix * VertexCoord;
+    TEX0.xy = TexCoord.xy * 1.0001;
+   float dx = SourceSize.z;
+   float dy = SourceSize.w;
+   t1 = vTexCoord.xyxy + vec4(-2.0*dx, -2.0*dy, dx, dy);
+   t2 = vTexCoord.xyxy + vec4(    -dx, -2.0*dy,  0, dy);
+   t3 = vTexCoord.xyxy + vec4(-2.0*dx,     -dy, dx,  0);
+   t4 = vTexCoord.xyxy + vec4(    -dx,     -dy,  0,  0);
+}
+
+#elif defined(FRAGMENT)
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out COMPAT_PRECISION vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+uniform sampler2D Texture;
+uniform sampler2D OrigTexture;
+COMPAT_VARYING vec4 TEX0;
+COMPAT_VARYING vec4 t1;
+COMPAT_VARYING vec4 t2;
+COMPAT_VARYING vec4 t3;
+COMPAT_VARYING vec4 t4;
+
+// compatibility #defines
+#define Source Texture
+#define Original OrigTexture
+#define vTexCoord TEX0.xy
+
+#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
+#define OutputSize vec4(OutputSize, 1.0 / OutputSize)
+
+const float XBR_EDGE_STR = 0.0;
+const float XBR_WEIGHT = 0.0;
+const float XBR_ANTI_RINGING = 0.0;
+
+const vec3 Y = vec3(.2126, .7152, .0722);
+
+const vec3 dtt = vec3(65536.,255.,1.);
+
+vec4 reduce4(vec3 A, vec3 B, vec3 C, vec3 D)
+{
+  return mul(mat4x3(A, B, C, D), dtt);
+}
+
+float RGBtoYUV(vec3 color)
+{
+  return dot(color, Y);
+}
+
+float df(float A, float B)
+{
+  return abs(A-B);
+}
+
+bool eq(float A, float B)
+{
+	return (df(A, B) < 15.0);
+}
+
+/*
+                              P1
+     |P0|B |C |P1|         C     F4          |a0|b1|c2|d3|
+     |D |E |F |F4|      B     F     I4       |b0|c1|d2|e3|   |e1|i1|i2|e2|
+     |G |H |I |I4|   P0    E  A  I     P3    |c0|d1|e2|f3|   |e3|i3|i4|e4|
+     |P2|H5|I5|P3|      D     H     I5       |d0|e1|f2|g3|
+                           G     H5
+                              P2
+*/
+
+float d_wd(float b0, float b1, float c0, float c1, float c2, float d0, float d1, float d2, float d3, float e1, float e2, float e3, float f2, float f3)
+{
+	return (wp1*(df(c1,c2) + df(c1,c0) + df(e2,e1) + df(e2,e3)) + wp2*(df(d2,d3) + df(d0,d1)) + wp3*(df(d1,d3) + df(d0,d2)) + wp4*df(d1,d2) + wp5*(df(c0,c2) + df(e1,e3)) + wp6*(df(b0,b1) + df(f2,f3)));
+}
+
+float hv_wd(float i1, float i2, float i3, float i4, float e1, float e2, float e3, float e4)
+{
+	return ( wp4*(df(i1,i2)+df(i3,i4)) + wp1*(df(i1,e1)+df(i2,e2)+df(i3,e3)+df(i4,e4)) + wp3*(df(i1,e2)+df(i3,e4)+df(e1,i2)+df(e3,i4)));
+}
+
+vec3 min4(vec3 a, vec3 b, vec3 c, vec3 d)
+{
+    return min(a, min(b, min(c, d)));
+}
+vec3 max4(vec3 a, vec3 b, vec3 c, vec3 d)
+{
+    return max(a, max(b, max(c, d)));
+}
+
+void main()
+{
+	vec2 tex = (floor(vTexCoord*SourceSize.xy/XBR_RES) + vec2(0.5, 0.5))*XBR_RES/SourceSize.xy;
+
+	vec2 g1 = vec2(XBR_RES/SourceSize.x, 0.0);
+	vec2 g2 = vec2(0.0, XBR_RES/SourceSize.y);
+
+	vec3 P0 = COMPAT_TEXTURE(Source, t1.xy).xyz;
+	vec3 P1 = COMPAT_TEXTURE(Source, t1.zy).xyz;
+	vec3 P2 = COMPAT_TEXTURE(Source, t1.xw).xyz;
+	vec3 P3 = COMPAT_TEXTURE(Source, t1.zw).xyz;
+
+	vec3  B = COMPAT_TEXTURE(Source, t2.xy).xyz;
+	vec3  C = COMPAT_TEXTURE(Source, t2.zy).xyz;
+	vec3 H5 = COMPAT_TEXTURE(Source, t2.xw).xyz;
+	vec3 I5 = COMPAT_TEXTURE(Source, t2.zw).xyz;
+
+	vec3  D = COMPAT_TEXTURE(Source, t3.xy).xyz;
+	vec3 F4 = COMPAT_TEXTURE(Source, t3.zy).xyz;
+	vec3  G = COMPAT_TEXTURE(Source, t3.xw).xyz;
+	vec3 I4 = COMPAT_TEXTURE(Source, t3.zw).xyz;
+
+	vec3  E = COMPAT_TEXTURE(Source, t4.xy).xyz;
+	vec3  F = COMPAT_TEXTURE(Source, t4.zy).xyz;
+	vec3  H = COMPAT_TEXTURE(Source, t4.xw).xyz;
+	vec3  I = COMPAT_TEXTURE(Source, t4.zw).xyz;
+
+	vec3  A = COMPAT_TEXTURE(Source, vTexCoord).xyz;
+
+	vec3 F6 = COMPAT_TEXTURE(Original, tex +g1+0.25*g1+0.25*g2).xyz;
+	vec3 F7 = COMPAT_TEXTURE(Original, tex +g1+0.25*g1-0.25*g2).xyz;
+	vec3 F8 = COMPAT_TEXTURE(Original, tex +g1-0.25*g1-0.25*g2).xyz;
+	vec3 F9 = COMPAT_TEXTURE(Original, tex +g1-0.25*g1+0.25*g2).xyz;
+
+	vec3 H6 = COMPAT_TEXTURE(Original, tex +0.25*g1+0.25*g2+g2).xyz;
+	vec3 H7 = COMPAT_TEXTURE(Original, tex +0.25*g1-0.25*g2+g2).xyz;
+	vec3 H8 = COMPAT_TEXTURE(Original, tex -0.25*g1-0.25*g2+g2).xyz;
+	vec3 H9 = COMPAT_TEXTURE(Original, tex -0.25*g1+0.25*g2+g2).xyz;
+
+	vec4 f0 = reduce4(F6, F7, F8, F9);
+	vec4 h0 = reduce4(H6, H7, H8, H9);
+
+   bool block_3d = ((f0.xyz==f0.yzw) && (h0.xyz==h0.yzw));
+
+	float b = RGBtoYUV( B );
+	float c = RGBtoYUV( C );
+	float d = RGBtoYUV( D );
+	float e = RGBtoYUV( E );
+	float f = RGBtoYUV( F );
+	float g = RGBtoYUV( G );
+	float h = RGBtoYUV( H );
+	float i = RGBtoYUV( I );
+
+	float i4 = RGBtoYUV( I4 ); float p0 = RGBtoYUV( P0 );
+	float i5 = RGBtoYUV( I5 ); float p1 = RGBtoYUV( P1 );
+	float h5 = RGBtoYUV( H5 ); float p2 = RGBtoYUV( P2 );
+	float f4 = RGBtoYUV( F4 ); float p3 = RGBtoYUV( P3 );
+
+/*
+                              P1
+     |P0|B |C |P1|         C     F4          |a0|b1|c2|d3|
+     |D |E |F |F4|      B     F     I4       |b0|c1|d2|e3|   |e1|i1|i2|e2|
+     |G |H |I |I4|   P0    E  A  I     P3    |c0|d1|e2|f3|   |e3|i3|i4|e4|
+     |P2|H5|I5|P3|      D     H     I5       |d0|e1|f2|g3|
+                           G     H5
+                              P2
+*/
+
+	/* Calc edgeness in diagonal directions. */
+	float d_edge  = (d_wd( d, b, g, e, c, p2, h, f, p1, h5, i, f4, i5, i4 ) - d_wd( c, f4, b, f, i4, p0, e, i, p3, d, h, i5, g, h5 ));
+
+	/* Calc edgeness in horizontal/vertical directions. */
+	float hv_edge = (hv_wd(f, i, e, h, c, i5, b, h5) - hv_wd(e, f, h, i, d, f4, g, i4));
+
+	float limits = XBR_EDGE_STR + 0.000001;
+	float edge_strength = smoothstep(0.0, limits, abs(d_edge));
+
+	/* Filter weights. Two taps only. */
+	vec4 w1 = vec4(-weight1, weight1+0.5, weight1+0.5, -weight1);
+	vec4 w2 = vec4(-weight2, weight2+0.25, weight2+0.25, -weight2);
+
+	/* Filtering and normalization in four direction generating four colors. */
+	vec3 c1 = mul(w1, mat4x3( P2,   H,   F,   P1 ));
+	vec3 c2 = mul(w1, mat4x3( P0,   E,   I,   P3 ));
+	vec3 c3 = mul(w2, mat4x3(D+G, E+H, F+I, F4+I4));
+	vec3 c4 = mul(w2, mat4x3(C+B, F+E, I+H, I5+H5));
+
+	//bool ir_lv1 = (((e!=f) && (e!=h))  && ( !eq(f,b) && !eq(f,c) || !eq(h,d) && !eq(h,g) || eq(e,i) && (!eq(f,f4) && !eq(f,i4) || !eq(h,h5) && !eq(h,i5)) || eq(e,g) || eq(e,c)) );
+
+
+	/* Smoothly blends the two strongest directions (one in diagonal and the other in vert/horiz direction). */
+	vec3 color =  mix(mix(c1, c2, step(0.0, d_edge)), mix(c3, c4, step(0.0, hv_edge)), 1. - edge_strength);
+
+	/* Anti-ringing code. */
+	vec3 min_sample = min4( E, F, H, I ) + (1.-XBR_ANTI_RINGING)*mix((P2-H)*(F-P1), (P0-E)*(I-P3), step(0.0, d_edge));
+	vec3 max_sample = max4( E, F, H, I ) - (1.-XBR_ANTI_RINGING)*mix((P2-H)*(F-P1), (P0-E)*(I-P3), step(0.0, d_edge));
+
+	color = clamp(color, min_sample, max_sample);
+
+	color = (block_3d) ? color : A;
+
+   FragColor = vec4(color, 1.0);
+} 
+#endif
diff --git a/base/xbr/shaders/super-xbr/super-8xbr-3d-pass0.glsl b/base/xbr/shaders/super-xbr/super-8xbr-3d-pass0.glsl
new file mode 100644
index 0000000..c861560
--- /dev/null
+++ b/base/xbr/shaders/super-xbr/super-8xbr-3d-pass0.glsl
@@ -0,0 +1,294 @@
+#version 130
+
+/*
+   
+  *******  Super 8XBR 3D Shader - pass0  *******
+   
+  Copyright (c) 2017 Hyllian - sergiogdb at gmail.com
+
+  Permission is hereby granted, free of charge, to any person obtaining a copy
+  of this software and associated documentation files (the "Software"), to deal
+  in the Software without restriction, including without limitation the rights
+  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+  copies of the Software, and to permit persons to whom the Software is
+  furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included in
+  all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+  THE SOFTWARE.
+
+*/
+
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying 
+#define COMPAT_ATTRIBUTE attribute 
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+COMPAT_VARYING vec4 TEX0;
+
+vec4 _oPosition1; 
+uniform mat4 MVPMatrix;
+uniform COMPAT_PRECISION int FrameDirection;
+uniform COMPAT_PRECISION int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;




More information about the Scummvm-git-logs mailing list