Here is a single pass ntsc like blastem with comb filter and all, runs 800 fps on hd630 on 1x scale.
#version 110
#pragma parameter comb_filter "Comb Filter Strength" 0.6 0.0 1.0 0.05
#pragma parameter lpass "Low Pass" 0.25 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;
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 WHATEVER;
#else
#define WHATEVER 0.0
#endif
void main()
{
gl_Position = MVPMatrix * VertexCoord;
TEX0.xy = TexCoord.xy*1.0001;
}
#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 vTexCoord TEX0.xy
#define Source Texture
#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 comb_filter;
uniform COMPAT_PRECISION float lpass;
#else
#define comb_filter 0.0
#define lpass 0.0
#endif
#define PI 3.14159265358979323846
const mat3 RGBYUV = mat3(0.299, 0.587, 0.114,
-0.299, -0.587, 0.886,
0.701, -0.587, -0.114);
const mat3 YUV2RGB = mat3(1.0, 0.0, 1.13983,
1.0, -0.39465, -0.58060,
1.0, 2.03211, 0.0);
vec2 dx,dy;
float compo0 ( float p, vec3 phase)
{
vec3 yiq = COMPAT_TEXTURE(Source,vTexCoord+p*dx).rgb*RGBYUV;
return dot(vec3(1.0),yiq*phase);
}
float compo1 ( float p, vec3 phase)
{
vec3 yiq = COMPAT_TEXTURE(Source,vTexCoord+p*dx-dy).rgb*RGBYUV;
return dot(vec3(1.0),yiq*phase);
}
void main() {
dx = vec2(SourceSize.z*0.5,0.0);
dy = vec2(0.0,SourceSize.w*0.25);
vec3 final = vec3(0.0);
float sum = 0.0;
for (int n=-3; n<4; n++)
{
float p = float(n);
float w = exp(-lpass*p*p);
float carrier = (vTexCoord.x * SourceSize.x / 170.667 * InputSize.x + p)*PI*0.5;
float carrier_up = (vTexCoord.x * SourceSize.x / 170.667 * InputSize.x + p)*PI*0.5 + PI;
vec3 phase = vec3(1.0,cos(carrier) ,sin(carrier));
vec3 phase_up = vec3(1.0,cos(carrier_up),sin(carrier_up));
float line_cur = compo0(p,phase);
float line_up = compo1(p,phase_up);
vec3 rgb = vec3(0.0);
// luma
rgb.r = (line_up+line_cur)/2.0;
// chroma
rgb.gb = vec2(line_cur-(line_up+line_cur)/2.0*comb_filter);
final += w*rgb*phase;
sum += w;
}
final /= sum;
FragColor.rgb = final*YUV2RGB;
}
#endif