#version 430

layout(binding=0) uniform sampler2D tex;

in vec4 posG;
in vec3 normalG;
in vec3 normalWSG;
in vec2 uvG;
in vec3 tangentG;
in vec3 colorG;
in vec4 posW;

layout(location = 0) out vec4 frag;
layout(location = 1) out vec4 frag2;


#define PI 3.1415926

uniform float g_time;

uniform float g_uvOfsX = 0.0;
uniform float g_uvScale = 1.0;

uniform float g_texBrightness = 1.0;
uniform float g_prevAmount = 0.0;
uniform float g_prevBlurAmount = 0.0;
uniform float g_bump = 0.0;

uniform vec4 g_color = vec4(1.0);


uniform mat4 modelViewMatrix;
uniform mat4 modelViewInvMatrix;
uniform mat4 viewInvMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
uniform mat4 projectionInvMatrix;


vec4 rotateXY(vec4 p, float a) {
  vec4 r = p;
  r.x = cos(a)*p.x - sin(a)*p.y;
  r.y = sin(a)*p.x + cos(a)*p.y;
  return r;
}

vec3 rotateXY3(vec3 p, float a) {
  return rotateXY(vec4(p, 0.0), a).xyz;
}

// google glsl rand gave this, thanks and credit flies to
// http://stackoverflow.com/questions/4200224/random-noise-functions-for-glsl
float rand(vec2 co){
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}

const float zFar = 1.0;
const float zNear = 0.0;

float getPointDist(float z) {
    float clipA = zFar / (zFar - zNear);
    float clipB = zFar*zNear / (zNear - zFar);
    return clipB/(z-clipA);
}
float getPointZ(float d) {
    float clipA = zFar / (zFar - zNear);
    float clipB = zFar*zNear / (zNear - zFar);
    return (clipB + d*clipA)/d;
}

vec4 CalcEyeFromWindow(in vec3 windowSpace) {
    vec3 ndcPos;
    vec4 viewport = vec4(0.0, 0.0, 1280.0, 720.0);
    ndcPos.xy = ((2.0 * windowSpace.xy) - (2.0 * viewport.xy)) / (viewport.zw) - 1;
//    ndcPos.z = (2.0 * windowSpace.z - zNear - zFar) / (zFar - zNear);
    ndcPos.z = (2.0 * windowSpace.z - zNear - zFar) / (zFar - zNear);
    vec4 clipPos;
    clipPos.w = projectionMatrix[3][2]/(ndcPos.z-(projectionMatrix[2][2]/projectionMatrix[2][3]));
    clipPos.xyz = ndcPos * clipPos.w;
    return projectionInvMatrix * clipPos;
}

vec2 getBump(vec2 uv) {
    vec2 d = vec2(0.01, 0.0);
    return vec2(texture2D(tex, uv+d.xy).g-texture2D(tex, uv-d.xy).g,
                texture2D(tex, uv+d.yx).g-texture2D(tex, uv-d.yx).g);
}

void main() {

  vec3 normal = normalG;
  vec2 uv = uvG;
  vec3 tangent = tangentG;
  vec3 color = colorG;
  float sk = 0.2;

//  vec2 myUv = vec2(posW.x*1.1+posW.z*0.05, posW.x*0.1+posW.z*1.07+posW.y*0.23)*g_uvScale*1.0+vec2(0.5, 0.5);
//  myUv.y *= -1.0;
//  myUv.x += g_uvOfsX;

//  vec2 myUv2 = vec2(posW.z*1.4+posW.y*2.2, posW.x+posW.y*2.3)*g_uvScale*1.0+vec2(0.5, 0.5);
//  myUv2.y *= -1.0;
//  myUv2.x += g_uvOfsX;

// vec4 diffuse = texture2D(tex, myUv.xy*sk)*(1.0+0.0*texture2D(tex, myUv2.xy*sk*1.1));


  vec4 diffuse = texture2D(tex, uv*g_uvScale);

 //diffuse.rgb =  (vec3(1.0)-diffuse.rgb);
//  diffuse.rgb = clamp((diffuse.rgb-vec3(0.0))*1.0, 0.0, 1.0);
 diffuse.rgb *=diffuse.rgb*g_texBrightness;
 diffuse.rgb += vec3(0.50);
 diffuse.rgb *= g_color.rgb;

 vec2 b = g_bump*getBump(uv.xy*g_uvScale*sk);
 vec3 bt = cross(normalWSG,tangent);
 vec3 normResult = normalWSG.xyz+tangent*b.x+bt*b.y;
 normResult = normalize(normResult);

 float vk =clamp(dot((normResult), normalize(vec3(1.0, 1.0, 0.0))), 0.0, 1.0);
 vk *= 1.0/(dot(posW,posW)*0.01+1.0)*1.0;
 vk *= vk;
// vk *= vk;
 diffuse.rgb *= (0.10+vk);


// diffuse.rgb = pow(diffuse.rgb, vec3(0.5));
 frag.rgb = diffuse.rgb;
 frag.a = 1.0;

//  float depthi = (posG.z/posG.w);
  //frag2.r = gl_FragCoord.z; //depthi;

  frag2.rgb = (normResult).xyz;
  frag2.a = 1.0;


}

