/*
   Advanced Cartoon shader 2015 WiP - upgrade 1
   
   by 2015 guest(r) - guest.r@gmail.com

*/


/*

   Use shader level 1&2 on 3D games, shader level 3&4 for stronger AA on sprites.

*/


uniform sampler2D OGL2Texture;
uniform vec4 OGL2Param;

// cartoon parameters
const float th   =  0.15;  // treshold for outlines
const float pp   =  0.80;  // darkening grade
const float bb   =  0.65;  // darkening strength
const float maxb =  0.50;  // max outline darkening limit
const float cl   = 15.00;  // coloring levels, set to 255 or more for "normal" effect

const vec3 dt = vec3(1.0,1.0,1.0);

float offset = 0.25 + (int(OGL2Param.z)/2)*0.75;

float x = offset/2048.0;
float y = offset/1024.0;


vec4 yx = vec4(1.0/4096,1.0/2048,-1.0/4096,-1.0/2048)*offset;

vec3 texture2d (vec2 texcoord) {

	vec3 c11 = texture2D(OGL2Texture, texcoord).xyz;
	vec3 s00 = texture2D(OGL2Texture, texcoord + yx.zw).xyz; 
	vec3 s20 = texture2D(OGL2Texture, texcoord + yx.xw).xyz; 
	vec3 s22 = texture2D(OGL2Texture, texcoord + yx.xy).xyz; 
	vec3 s02 = texture2D(OGL2Texture, texcoord + yx.zy).xyz; 
	vec3 c00 = texture2D(OGL2Texture, texcoord + vec2( -x, -y)).xyz; 
	vec3 c22 = texture2D(OGL2Texture, texcoord + vec2(  x,  y)).xyz; 
	vec3 c20 = texture2D(OGL2Texture, texcoord + vec2(  x, -y)).xyz;
	vec3 c02 = texture2D(OGL2Texture, texcoord + vec2( -x,  y)).xyz;
	vec3 c10 = texture2D(OGL2Texture, texcoord + vec2(0.0, -y)).xyz; 
	vec3 c21 = texture2D(OGL2Texture, texcoord + vec2(  x,0.0)).xyz; 
	vec3 c12 = texture2D(OGL2Texture, texcoord + vec2(0.0,  y)).xyz; 
	vec3 c01 = texture2D(OGL2Texture, texcoord + vec2( -x,0.0)).xyz;     

	float d1=dot(abs(c00-c22),dt)+0.001;
	float d2=dot(abs(c20-c02),dt)+0.001;
	float hl=dot(abs(c01-c21),dt)+0.001;
	float vl=dot(abs(c10-c12),dt)+0.001;
	float m1=dot(abs(s00-s22),dt)+0.001;
	float m2=dot(abs(s02-s20),dt)+0.001;

	vec3 t1=(hl*(c10+c12)+vl*(c01+c21)+(hl+vl)*c11)/(3.0*(hl+vl));
	vec3 t2=(d1*(c20+c02)+d2*(c00+c22)+(d1+d2)*c11)/(3.0*(d1+d2));
	
	c11 =.25*(t1+t2+(m2*(s00+s22)+m1*(s02+s20))/(m1+m2));

	return c11; 
}


void main()
{
    vec3 c00 = texture2d(gl_TexCoord[5].xy); 
    vec3 c10 = texture2d(gl_TexCoord[1].xy); 
    vec3 c20 = texture2d(gl_TexCoord[2].zw); 
    vec3 c01 = texture2d(gl_TexCoord[3].xy); 
    vec3 c11 = texture2d(gl_TexCoord[0].xy); 
    vec3 c21 = texture2d(gl_TexCoord[4].xy); 
    vec3 c02 = texture2d(gl_TexCoord[1].zw); 
    vec3 c12 = texture2d(gl_TexCoord[2].xy); 
    vec3 c22 = texture2d(gl_TexCoord[6].xy);       

    float d1=dot(abs(c00-c22),dt)+0.001;
    float d2=dot(abs(c20-c02),dt)+0.001;
    float hl=dot(abs(c01-c21),dt)+0.001;
    float vl=dot(abs(c10-c12),dt)+0.001;

    float d =min(bb*pow(max(d1+d2+hl+vl-th,0.0)/(0.25*dot(c01+c10+c12+c21,dt)+0.5),pp),maxb);
	
    float l = cl*sqrt(length(c11)/1.73205);
    float k = floor(l); float v = fract(l); float t = 0.33;
    v = 0.60*(max(v-1.0+t,0.0))/t; v = (k+v)/cl + (cl-k)/cl*0.075; v*=1.73205*v;

    c11 = v*(1.0-d)*normalize(c11);
 
    gl_FragColor.xyz=c11;
}