#version 430

layout(binding=0) uniform sampler2D tex;
layout(binding=1) uniform sampler2D tex2;
layout(binding=2) uniform sampler2D tex3;
layout(binding=3) uniform sampler2D tex4;
layout(binding=4) uniform sampler2D texPrevBlurFrame;
layout(binding=5) uniform sampler2D texPrevNorm;


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

in float triangleIdG;

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_uvScaleY = 1.0;
uniform float g_uvOfsY = 0.0;

uniform float g_texBrightness = 1.0;
uniform float g_texAmbient = 0.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;

uniform float g_windowWidth = 1280.0;
uniform float g_windowHeight = 720.0;

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, g_windowWidth, g_windowHeight);
    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);
}


float atanSafe(float y, float x) {
    float ret=0.0;
    if (x!=0.0) {
        if (x>0.0) {
            ret=atan(y/x);
        } else	{
            ret=atan(y/x)+3.141592;
        }
    } else {
        if (y>=0.0) {
            ret=0.5*3.141592;
        } else {
            ret=-0.5*3.141592;
        }
    }
    return ret;
}

// from pouet raymarching thread by las of mercury
float perlin(vec3 p) {
    vec3 i = floor(p);
    vec4 a = dot(i, vec3(1., 57., 21.)) + vec4(0., 57., 21., 78.);
    vec3 f = cos((p-i)*3.14159265)*(-.5)+.5;
    a = mix(sin(cos(a)*a),sin(cos(1.+a)*(1.+a)), f.x);
    a.xy = mix(a.xz, a.yw, f.y);
    return mix(a.x, a.y, f.z);
}

float turb(vec3 c) {
        float r=0.0;
        float s=0.5;
        c*=1.0;
        for (int i=0;i<8;i++) {
                //if (i<2) continue;
                r+=s*(perlin(c)*1.0+0.0);
                c*=3.0;
                s*=0.55;
        }
        return r;
}

vec3 texStripes(vec3 p) {
    float sw = 0.20;
    float sf = 40.0;
    float res = clamp((sin(p.z*sf+p.x*sf)-1.0+sw)/sw, -1.0, 1.0)+clamp((sin((p.z*sf+p.x*sf)*0.1)-1.0+sw)/sw, 0.0, 1.0);
    return -vec3(res*1.25, res*1.1, res*1.05)+vec3(2.0);
}

vec3 spreadSpec3(vec3 c, float sp) {
    sp = fract(sp);
    c.r *= smoothstep(1.0, 0.0, (1.0-sp)*1.0);
    c.g *= smoothstep(1.0, 0.0, abs((sp-0.5)*2.0));
    c.b *= smoothstep(1.0, 0.0, sp*1.0);
    return c;
}

vec3 texStripesRad(vec3 p) {
    float sw = 0.50;
    float sf = 43.0;
    float pk = sqrt(dot(p.xy, p.xy))+atanSafe(p.y, p.x)/sf;
    float res = clamp((sin(pk*sf)-0.0+sw)/sw, -1.0, 1.0);
    vec3 r = (vec3(res*1.3, res*1.1, res*1.0)*1.0+vec3(0.0));
    vec3 rr = vec3(0.0);
    float kp = 64.0;
    for (int i=0; i<kp; i++) {
        rr += spreadSpec3(r, pk*i*0.1+i/16.0);
    }
    r = rr/kp;
    r *= r*2.0;
    return r;
}


vec4 getCol(float freq, vec2 ofs) {
    vec4 d;
    vec4 diffuse;
    float kalkutta, kalkuttas, kf;
    float pi = 3.141592;
    vec2 uv;


    float overlaps = g_uvScale;
    float dots = dot(vec3(0.0, 1.0, 0.0),normalize(posW.xyz));
    float dotter = (0.50+0.45*dots)*g_uvScaleY+g_uvOfsY*freq;
    kalkutta = (atanSafe(posW.x, posW.z)+0.5*pi)/(2.0*pi)*overlaps*2.0;
    overlaps = fract((overlaps-0.01)*2.0)*0.5;
    kf = fract(kalkutta);
    uv = vec2(kalkutta, dotter)*1.0;
    d = texture2D(tex, uv*freq+ofs);
    d *= d;
    diffuse = d*(smoothstep(0.0, overlaps, kf))*(1.0-smoothstep(overlaps, overlaps*2.0, kf));

    overlaps = g_uvScale*1.5;
    kalkutta = ((atanSafe(posW.z, posW.x)+0.50*pi)/(2.0*pi)+0.0)*overlaps*2.0;
    overlaps = fract((overlaps-0.01)*2.0)*0.5;
    kf = fract(kalkutta);
    uv = vec2(kalkutta, dotter)*1.0;
    d = texture2D(tex, uv*freq+ofs);
    d *= d;
    diffuse += d*(smoothstep(0.0, overlaps, kf))*(1.0-smoothstep(overlaps, overlaps*2.0, kf));

    return diffuse*brightG;
}

vec3 tonemapUC2(vec3 x) {
    x = clamp(x, 0.0, 10000.0);
    float A = 0.15;
    float B = 0.50;
    float C = 0.10;
    float D = 0.20;
    float E = 0.02;
    float F = 0.30;
    return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;
}




void main() {

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


  vec4 diffuse = vec4(1.0);
//  vec4 diffuse = getCol(1.0, vec2(0.0, 0.0));
//  diffuse *= (getCol(1.5, vec2(0.07, 0.069))+vec4(0.450));
//  diffuse *= (getCol(0.50, vec2(0.02, -0.069))+vec4(0.450));
//  diffuse *= g_texBrightness*1.0;


// diffuse.rgb = posW.rgb;
// diffuse.rgb *= color.rgb;
 vec3 p = posW.rgb+vec3(1.0, 1.3, 0.4)*g_time*0.0;

 float nAmp = 0.1;

 p.y += turb(p*0.050+vec3(0.2, 0.3, 0.72)*g_time*0.00)*nAmp;
 p.x += turb(p.yzx*0.747+vec3(0.2, 0.3, 0.72)*g_time*0.00)*nAmp;

 diffuse.rgb = 4.0*vec3(texStripesRad(p));


 // diffuse.rgb *=diffuse.rgb*g_texBrightness;
 // diffuse.rgb += vec3(g_texAmbient);
// diffuse.rgb *= color.rgb;
//  diffuse.rgb = vec3(0.2);

 frag.rgb = diffuse.rgb*diffuse.rgb;
// frag.rgb = tonemapUC2(diffuse.rgb);
// frag.rgb = pow(frag.rgb, vec3(0.5));
  frag.a = triangleIdG;

//  frag.rgb = vec3(sin(frag.a*0.001)*0.5+0.5);

  frag2.rgb = normalize(normalWSG).xyz;
  frag2 = clamp(frag2, -1.0, 1.0);
  frag2.a = 1.0;


}

