/*
   SimoneT Bump Map v.1.4

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

   4xGLSoft lite - Copyright (C) 2016 guest(r) - guest.r@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;

const   vec2 InvSize2D = vec2( 0.00048828125, 0.0009765625);
const	vec4 yx = vec4( 0.000244140625, 0.00048828125,-0.000244140625,-0.00048828125);
const	vec4 xy = vec4( 0.00048828125 , 0.0009765625 ,-0.00048828125 ,-0.0009765625 );

const   vec3 light_dir = vec3(0.25, 0.5, 0.75);

float CLength(vec3 c1){

	float rmean = c1.r*0.5;

	c1*= c1;

	return sqrt((2.0+rmean)*c1.r+4.0*c1.g+(3.0-rmean)*c1.b);
}

float Cdistance(vec3 c1, vec3 c2){

	float rmean = (c1.r+c2.r)*0.5;

	c1 = pow(c1-c2,vec3(2.0));

	return sqrt((2.0+rmean)*c1.r+4.0*c1.g+(3.0-rmean)*c1.b);
}

//	4xGLSoft lite code

vec3 lite4xGLSoft(vec2 texcoord) {

	vec3 c11 = texture2D(OGL2Texture, texcoord        ).rgb; 
	vec3 c00 = texture2D(OGL2Texture, texcoord + xy.zw).rgb; 
	vec3 c20 = texture2D(OGL2Texture, texcoord + xy.xw).rgb; 
	vec3 c22 = texture2D(OGL2Texture, texcoord + xy.xy).rgb; 
	vec3 c02 = texture2D(OGL2Texture, texcoord + xy.zy).rgb; 
	vec3 s00 = texture2D(OGL2Texture, texcoord + yx.zw).rgb; 
	vec3 s20 = texture2D(OGL2Texture, texcoord + yx.xw).rgb; 
	vec3 s22 = texture2D(OGL2Texture, texcoord + yx.xy).rgb; 
	vec3 s02 = texture2D(OGL2Texture, texcoord + yx.zy).rgb; 

	vec4 d1=vec4(
	Cdistance(c00,c22),
	Cdistance(c20,c02),
	Cdistance(s00,s22),
	Cdistance(s02,s20))+0.0001;

	d1 = pow(d1,vec4(7.0));// my idea...

	vec3 t2=(d1.x*(c20+c02)+d1.y*(c00+c22))/(2.0*(d1.x+d1.y));
	
	return .25*(c11+t2+(d1.w*(s00+s22)+d1.z*(s02+s20))/(d1.z+d1.w));

}

vec3 Bump( vec2 texCoords, vec2 InvSize, float normalStrength ){     

	float tl = CLength(lite4xGLSoft( texCoords - InvSize                    ));// top left   
	float t  = CLength(lite4xGLSoft( texCoords + vec2(       0.0,-InvSize.y)));// top  
	float tr = CLength(lite4xGLSoft( texCoords + vec2( InvSize.x,-InvSize.y)));// top right   

	float l  = CLength(lite4xGLSoft( texCoords + vec2(-InvSize.x,       0.0)));// left   
	vec3  c  =         lite4xGLSoft( texCoords                               );// center
	float r  = CLength(lite4xGLSoft( texCoords + vec2( InvSize.x,       0.0)));// right   

	float bl = CLength(lite4xGLSoft( texCoords + vec2(-InvSize.x, InvSize.y)));// bottom left   
	float b  = CLength(lite4xGLSoft( texCoords + vec2(       0.0, InvSize.y)));// bottom  
	float br = CLength(lite4xGLSoft( texCoords + InvSize                    ));// bottom right   

	float dX = (tr + 2.0 * ( r - l ) + br - tl - bl);

	float dY = (bl + 2.0 * ( b - t ) + br - tl - tr);

	float diffuse = dot( normalize(vec3(dX, 1.0/normalStrength, dY))*0.5+0.5, normalize(light_dir));

	return diffuse * c;

}

void main()
{

	gl_FragColor.rgb = Bump( gl_TexCoord[0].xy, InvSize2D, 1.0 + 1.5 * OGL2Param.z );

}
