uniform sampler2D tex0;
uniform vec4 OGL2Param;
uniform vec4 OGL2Size;
uniform vec4 OGL2InvSize;

vec3 Var(vec3 c0, vec3 c1, vec3 c2)
{
	vec3 a1 = c0-c1;
	vec3 a2 = c2-c0;
	vec3 a3 = min(abs(a1),abs(a2));
	vec3 a4 = (sign(a1)+sign(a2))*0.5;
	return a3*a4;
}

void main (void)
{
	vec2 Size = OGL2Size.xy;
	vec2 InvSize = OGL2InvSize.xy;

	vec2 position = (gl_TexCoord[0].xy-0.5*InvSize)*Size;
	vec2 coord = fract(position);
    position = floor(position)*InvSize+0.5*InvSize;

	//   c0 c1
	//c2 c3 c4 c5
	//c6 c7 c8 c9
	//   ca cb

	vec2 sx1 = vec2(1.0,0.0)*InvSize;
	vec2 sy1 = vec2(0.0,1.0)*InvSize;
	vec2 sx2 = 2.0*sx1;
	vec2 sy2 = 2.0*sy1;

	vec3 c0 = texture2D(tex0,position    -sy1).rgb;
	vec3 c1 = texture2D(tex0,position+sx1-sy1).rgb;
	vec3 c2 = texture2D(tex0,position-sx1    ).rgb;
	vec3 c3 = texture2D(tex0,position        ).rgb;
	vec3 c4 = texture2D(tex0,position+sx1    ).rgb;
	vec3 c5 = texture2D(tex0,position+sx2    ).rgb;
	vec3 c6 = texture2D(tex0,position-sx1+sy1).rgb;
	vec3 c7 = texture2D(tex0,position    +sy1).rgb;
	vec3 c8 = texture2D(tex0,position+sx1+sy1).rgb;
	vec3 c9 = texture2D(tex0,position+sx2+sy1).rgb;
	vec3 ca = texture2D(tex0,position    +sy2).rgb;
	vec3 cb = texture2D(tex0,position+sx1+sy2).rgb;

	vec3 Varc3 = c3+Var(c3,c2,c4)* coord.x     +Var(c3,c0,c7)* coord.y     ;
	vec3 Varc4 = c4+Var(c4,c3,c5)*(coord.x-1.0)+Var(c4,c1,c8)* coord.y     ;
	vec3 Varc7 = c7+Var(c7,c6,c8)* coord.x     +Var(c7,c3,ca)*(coord.y-1.0);
	vec3 Varc8 = c8+Var(c8,c7,c9)*(coord.x-1.0)+Var(c8,c4,cb)*(coord.y-1.0);

	vec3 Varc34 = mix(Varc3,Varc4,coord.x);
	vec3 Varc78 = mix(Varc7,Varc8,coord.x);

	gl_FragColor.rgb = mix(Varc34,Varc78,coord.y);
}
