struct data
{
   float2 tex;
   float pix_no;
   float one;
};

struct input
{
   float2 video_size;
   float2 texture_size;
   float2 output_size;
};

void main_vertex
(
   float4 position : POSITION,
   out float4 oPosition : POSITION,
   uniform float4x4 modelViewProj,
   float2 tex : TEXCOORD,
   uniform input IN,
   out data oData
)
{
   oPosition = mul(modelViewProj, position);
   oData.tex = tex;
   oData.pix_no = tex.x * IN.texture_size.x;
   oData.one = 1.0 / IN.texture_size.x;
}

#define INV_SQRT_2_PI 0.38 // Doesn't have to be accurate.

#pragma parameter HORIZ_GAUSS_WIDTH "Gaussian Width" 0.5 0.4 0.6 0.02
#ifdef PARAMETER_UNIFORM
uniform float HORIZ_GAUSS_WIDTH;
#else
#define HORIZ_GAUSS_WIDTH 0.5
#endif

float4 main_fragment (uniform input IN, in data vertex, uniform sampler2D s0 : TEXUNIT0) : COLOR
{
#define TEX(off_x) tex2D(s0, tex + float2(float(off_x) * vertex.one, 0.0)).rgb

   float texel = floor(vertex.pix_no);
   float phase = vertex.pix_no - texel;
   float base_phase = phase.x - 0.5;
   float2 tex = float2((texel + 0.5) / IN.texture_size.x, vertex.tex.y);

   float3 col = float3(0.0);
   for (int i = -2; i <= 2; i++)
   {
      float phase = base_phase - float(i);
      float g = INV_SQRT_2_PI * exp(-0.5 * phase * phase / (HORIZ_GAUSS_WIDTH * HORIZ_GAUSS_WIDTH)) / HORIZ_GAUSS_WIDTH;
      col += TEX(i) * g;
   }

   return float4(col, 1.0);
}

