#version 410
in vec2 TexCoords;
out vec4 FragColor;
 
uniform sampler2D gNormal;
uniform sampler2D depthTex;
uniform sampler2D gPositionDepth;
uniform sampler2D texNoise;
uniform vec3 samples[64];
uniform int winWidth;
uniform int winHeight;
 
int kernelSize = 64;
float radius = 1;
 
//const vec2 noiseScale = vec2(640.0 / 4.0, 480.0 / 4.0);
 
//uniform mat4 projection;
uniform mat4 projection;
uniform mat4 uModelView;
 
void main(void)
{
  //FragColor = 1;
  vec2 noiseScale = vec2(winWidth / 4.0, winHeight / 4.0);
 
  vec3 fragPos = texture(gPositionDepth, TexCoords).xyz;
  vec3 normal = texture(gNormal, TexCoords).rgb;
  vec3 randomVec = texture(texNoise, TexCoords * noiseScale).xyz;
  vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal));
  vec3 bitangent = cross(normal, tangent);
  mat3 TBN = mat3(tangent, bitangent, normal);
  
  
  //corrections
  ///normal = (transpose(inverse(uModelView)) * vec4(normal, 0.0)).xyz;
  
  //gl_FragColor = vec4(vec3(texture(gPositionDepth, TexCoords).rgb), 1.0); return;
  //gl_FragColor = vec4(vec3(texture(gPositionDepth, TexCoords).a), 1.0); return;
 
  FragColor = vec4(fragPos, 1.0);
 
  float occlusion = 0.0;
  for (int i = 0; i < kernelSize; ++i)
  {
    vec3 posSample = TBN * samples[i];
    posSample = fragPos + posSample * radius;
 
    vec4 offset = vec4(posSample, 1.0);
    offset = projection * offset;
    offset.xyz /= offset.w;
    offset.xyz = offset.xyz * 0.5 + 0.5;
 
    //float sampleDepth = -texture(gPositionDepth, offset.xy).w;
    float sampleDepth = texture(gPositionDepth, offset.xy).z;
    float rangeCheck = smoothstep(0.0, 1.0, radius / abs(fragPos.z - sampleDepth));
    occlusion += (sampleDepth >= posSample.z ? 1.0 : 0.0) * rangeCheck;
    //occlusion += (sampleDepth < posSample.z ? 1.0 : 0.0) * rangeCheck;
  }
  occlusion = 1.0 - (occlusion / kernelSize);
  //occlusion = 0.5;
  FragColor = vec4(occlusion, occlusion, occlusion, 1.0);
  
  //FragColor = vec4(1,1,1,1.0);
}