/*
   Shock Filter Shader v 1.0

   idea from GPU Gems 2 : 27.3 Shock Filtering: A Method for Deblurring Images

   Copyright (C) 2016 SimoneT - simone1tarditi@gmail.com

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License
   as published by the Free Software Foundation; either version 2
   of the License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    
*/

uniform sampler2D OGL2Texture;
uniform vec4 OGL2Size;
uniform vec4 OGL2InvSize;
uniform vec4 OGL2Param;

vec3 smart2D( vec2 pos ){

	vec2 Tsize = vec2( 2048.0, 1024.0);
	vec2 coord1 = (floor(pos*Tsize))/Tsize;

        vec2 temp1 = 1.0/Tsize;

	//vec2 frac = smoothstep( 0.0, 1.0, fract(pos*Tsize));

	vec2 frac = fract(pos*Tsize);

	vec3 C0 = texture2D(OGL2Texture, coord1 + temp1 * vec2( 0.0, 0.0)).rgb;

	vec3 C1 = texture2D(OGL2Texture, coord1 + temp1 * vec2( 1.0, 0.0)).rgb;

	vec3 C2 = texture2D(OGL2Texture, coord1 + temp1 * vec2( 0.0, 1.0)).rgb;

	vec3 C3 = texture2D(OGL2Texture, coord1 + temp1 * vec2( 1.0, 1.0)).rgb;

	return mix( mix( C0, C1, frac.x ), mix( C2, C3, frac.x ), frac.y );  

}

vec3 ShockFilter( vec2 pos ){

	vec2 Tsize = vec2( 1024.0, 512.0);

	vec3 shift = vec3(1.0/Tsize, 0.0); 

	vec3 c = smart2D( pos );

	vec3 u = smart2D( pos + shift.zy );

	vec3 d = smart2D( pos - shift.zy );

	vec3 r = smart2D( pos + shift.xz );

	vec3 l = smart2D( pos - shift.xz );

	vec3 Convexity = 4.0 * c - r - l - u - d;

	vec2 diffusion = vec2(dot(( r - l ) * Convexity, vec3(1.0)),

                              dot(( u - d ) * Convexity, vec3(1.0)));

	diffusion *= 1.0/(length(diffusion) + 0.00001);

	c += (diffusion.x > 0 ? diffusion.x * r : -diffusion.x * l ) + 
	     (diffusion.y > 0 ? diffusion.y * u : -diffusion.y * d );

	return c/(1 + dot(abs(diffusion), vec2(1.0)));

}

void main()
{	

	vec3 X = ShockFilter( gl_TexCoord[0].xy );

	gl_FragColor.rgb = X ;

}
