kuwahara_filter
#define BOX 8
precision mediump float;
uniform vec2 res;
uniform sampler2D tex;
#define s(x,y) texture2D(tex,(gl_FragCoord.xy+vec2(x,y))/res).rgb
vec3 avg(int x,int y){
vec3 s = vec3(0);
for(int i=0;i<BOX;i++)for(int j=0;j<BOX;j++)s+=s(i*x,j*y);
return s/float(BOX*BOX);
}
float var(vec3 avg,int x,int y){
vec3 s = vec3(0),tmp;
for(int i=0;i<BOX;i++)for(int j=0;j<BOX;j++){tmp=s(i*x,j*y)-avg;s+=tmp*tmp;}
return dot(s/float(BOX*BOX),vec3(1));
}
void main(){
vec3 app = avg(1,1);
vec3 apm = avg(1,-1);
vec3 amp = avg(-1,1);
vec3 amm = avg(-1,-1);
float vpp = var(app,1,1);
float vpm = var(app,1,-1);
float vmp = var(app,-1,1);
float vmm = var(app,-1,-1);
float vmin = min(min(vpp,vpm),min(vmp,vmm));
vec4 diffuse = texture2D(tex,gl_FragCoord.xy/res);
diffuse.rgb = mix(diffuse.rgb,app,step(vpp,vmin));
diffuse.rgb = mix(diffuse.rgb,apm,step(vpm,vmin));
diffuse.rgb = mix(diffuse.rgb,amp,step(vmp,vmin));
diffuse.rgb = mix(diffuse.rgb,amm,step(vmm,vmin));
gl_FragColor = diffuse;
}