#version 430

layout(binding=0) uniform sampler2D tex;
layout(binding=1) uniform sampler2D texNoise;
layout(binding=2) uniform sampler2D texEmitShape;
layout(binding=3) uniform sampler2D texEnv;

in vec4 posG;
in vec2 uvG;
in float perG;
in vec3 normG;
in int gl_PrimitiveID;


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

//layout(binding=0, offset=0) uniform atomic_uint ac;
//layout(binding=0, r32ui) uniform uimage2D headPointers;
//layout(binding=1, r32ui) uniform uimage2D nextPointers;
//layout(binding=2, rgba16f) uniform image2D pixelListColors;
//layout(binding=3, rgba32f) uniform image2D pixelListDepthNorm;

uniform float g_time;
uniform float g_partSize = 0.15;

uniform float zNear = 0.1;
uniform float zFar = 1000.0;
// convert from 0.0 to 1.0 depth sample ds to linear depth
float linearDepth(float ds) {
    ds = 2.0*ds-1.0;
    float zLinear = 2.0*zNear*zFar/(zFar+zNear-ds*(zFar-zNear));
    return zLinear;
}
// result suitable for assigning to gl_FragDepth
float depthSample(float linearDepth) {
    float nonLinearDepth = (zFar+zNear-2.0*zNear*zFar/linearDepth)/(zFar-zNear);
    nonLinearDepth = (nonLinearDepth+1.0)/2.0;
    return nonLinearDepth;
}


#define PI 3.1415926

vec2 latlong(vec3 v) {
  v = normalize(v);
  float theta = acos(v.z); // +z is up
  float phi = atan(v.y, v.x) + PI;
  return vec2(phi, theta)*vec2(.1591549, .6366198);
}


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


uniform float g_partMapX = 0;
uniform float g_partMapY = 0;

uniform float g_windowWidth;
uniform float g_windowHeight;

uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;


uniform float near = 0.1;
uniform float far = 1000.0;

uniform float g_texBrightness = 1.0;

void main() {
    vec2 myUv = uvG;
    myUv.y *= -1.0;
    myUv *= 1.0/8.0;
    myUv.x += g_partMapX*1.0/8.0;
    myUv.y += g_partMapY*1.0/8.0;

    vec4 result;
    vec2 uvm = (uvG-vec2(0.5,0.5))*2.0;
    float dist = (dot(uvm,uvm));
    float circle = clamp(1.0-dist*1.0, 0.0, 1.0);
    float sharpness = 1.0;
    float powe = 1.0;
    circle = clamp(pow(circle*sharpness, powe), 0.0, 1.0);

    vec3 normal;
    normal.x = uvm.x;
    normal.y = uvm.y;
    normal.z = sqrt(1.0-dot(normal.xy, normal.xy));
    normal.z *= normal.z;
    normal = normalize(normal);
    normal *= circle;

    result.rgb = vec3(circle);
    result.a = clamp(result.r*1.0, 0.0, 1.0);

    vec3 nn = normalize(normG);

    float dp = dot(normalize(vec3(0.70, -0.30, 0.40)), nn);
    dp = clamp(dp, 0.0, 10000.0);
    float normDot = (pow(dp*1.0,64.0));
    float normDot2 = (pow(dp*1.0,1.0));

    result.rgb = vec3(1.30*normDot+0.5*normDot2)*1.0;

    mat4 mvp = projectionMatrix*modelViewMatrix;

    vec3 normSS = (mvp*vec4(nn, 1.0)).xyz;

    vec2 envPos = vec2(gl_FragCoord.x/g_windowWidth, gl_FragCoord.y/g_windowHeight)*0.050;
    vec4 envi = texture2D(texEnv, envPos+normSS.xy*0.05);

    result.rgb *= envi.rgb;

    result.rgb *= g_texBrightness;

    result.a = 1.0;

//    if (frag.r < 0.01) {
//        discard;
//        return;
//    }

////    float depthi = (posG.z/posG.w);

////    float ld = linearDepth(depthi);

//    frag2.r = ld+result.a*5.0;
//    frag2.gb = vec2(0.0);
//    frag2.g = ld;
//    frag2.b = 4.0+frag.a*3.0;
//    frag2.a = 1.0;

//    float b = -posG.z/posG.w*1.0 + 1.0;

//    depthi = linearDepth(depthi)-result.r*0.50;
//    if (depthi < zNear) depthi = zNear;
//    depthi = depthSample(depthi);
//    float dd = (depthi+1.0)*0.5;

//    if (result.a < 0.01) {
//        discard;
//    }

    int primID = gl_PrimitiveID;
    vec3 color;
//    if ((primID&3)==0) {
//        color.rgb = vec3(1.0);
//    } else if ((primID&3)==1) {
//        color.rgb = vec3(0.0, 0.0, 1.15);
//    } else if ((primID&3)==2) {
//        color.rgb = vec3(0.90, 0.0, 0.0);
//    } else {
//        color.rgb = vec3(0.2);
//    }

//    float age = 1.85;

 //   color = vec3(0.4+1.70*cos(age*3.1), 0.40*cos(age*1.32), 0.75+cos(age*3.2+sin(age*1.2)))+vec3(0.0);

   // result.rgb *= color;

   // result.rgb = vec3(0.35);
    result.a = 1.0;

    frag = result;
 //   frag2 = vec4(0.0);
    frag2.rgb = nn.xyz;
    frag2 = clamp(frag2, -1.0, 1.0);
    frag2.a = 1.0;

}

