#pragma language glsl3
#ifdef VERTEX
vec4 position(mat4 transform_projection, vec4 vertex_position) {return transform_projection*vertex_position;}
#endif

#ifdef PIXEL

uniform sampler2D gbuffer_position;
uniform sampler2D gbuffer_normal;

uniform sampler2D probeMap;
// uniform sampler2D probeDepth;
uniform int probeGridSize=4;
uniform vec3 probeMin;
uniform vec3 probeSpacing;
uniform float probeResolution;
uniform float probeDimensions;
uniform float probeAmount=0;
uniform float probeTesting=0;

float sumProbes = 0;

uniform float zNear = 0.1;
uniform float zFar = 10000.0;

float linearDepth(float depthSample)
{
    depthSample = 2.0 * depthSample - 1.0;
    float zLinear = 2.0 * zNear * zFar / (zFar + zNear - depthSample * (zFar - zNear));
    return zLinear;
}
vec3 sampleProbe(vec3 pos,vec3 dir,vec3 probe,float add){
  vec3 sample = vec3(0);
  float index = probe.x*probeGridSize*probeGridSize +  probe.y*probeGridSize + probe.z;
  float n = floor(probeDimensions/(probeResolution*6));
  vec2 base = vec2((mod(index,n)*probeResolution*6)/probeDimensions,(floor(index/n)*probeResolution)/probeDimensions);
  float faceIndex = 0;
  float ma;
  vec2 uv=vec2(1);
  
  vec3 probepos = probe*probeSpacing+probeMin;
  vec3 v = probepos-pos;
  v.y*=-1;
  vec3 vAbs = abs(v);

  // if (vAbs.z >= vAbs.x && vAbs.z >= vAbs.y) {
  //  faceIndex = v.z < 0.0 ? 5.0 : 4.0;
  //  ma = 0.5 / vAbs.z;
  //  uv = vec2(v.z < 0.0 ? -v.x : v.x, -v.y);
  // } else if (vAbs.y >= vAbs.x) {
  //  faceIndex = v.y < 0.0 ? 3.0 : 2.0;
  //  ma = 0.5 / vAbs.y;
  //  uv = vec2(v.x, v.y < 0.0 ? -v.z : v.z);
  // } else {
  //  faceIndex = v.x < 0.0 ? 1.0 : 0.0;
  //  ma = 0.5 / vAbs.x;
  //  uv = vec2(v.x < 0.0 ? v.z : -v.z, -v.y);
  // }
 //  uv = uv* ma + 0.5;
 
  // float depth = linearDepth(Texel(probeDepth,(uv/probeDimensions)*probeResolution+base+vec2(faceIndex*probeResolution,0)/probeDimensions).r);


  // if (probeTesting==0){
    sumProbes+=add;
    // sample=add*vec3(1/distance(pos,probepos));
    v =  dir;
    vAbs = abs(v);

    if (vAbs.z >= vAbs.x && vAbs.z >= vAbs.y) {
      faceIndex = v.z < 0.0 ? 5.0 : 4.0;
      ma = 0.5 / vAbs.z;
      uv = vec2(v.z < 0.0 ? -v.x : v.x, -v.y);
    } else if (vAbs.y >= vAbs.x) {
      faceIndex = v.y < 0.0 ? 3.0 : 2.0;
      ma = 0.5 / vAbs.y;
      uv = vec2(v.x, v.y < 0.0 ? -v.z : v.z);
    } else {
      faceIndex = v.x < 0.0 ? 1.0 : 0.0;
      ma = 0.5 / vAbs.x;
      uv = vec2(v.x < 0.0 ? v.z : -v.z, -v.y);
    }
    uv = uv* ma + 0.5;

    vec3  samp = add*Texel(probeMap,(uv/probeDimensions)*probeResolution+base+vec2(faceIndex*probeResolution,0)/probeDimensions).rgb; 
    return samp;
  // }
  return sample;
}

vec4 effect(vec4 color, sampler2D tex, vec2 textureCoords, vec2 screen_coords) {
  vec3 normal   = Texel(gbuffer_normal,    textureCoords).xyz*2-vec3(1);
  vec3 pos      = Texel(gbuffer_position,   textureCoords).xyz;
  vec3 ppos     = (pos-probeMin)/probeSpacing;
  vec3 lower    = floor(ppos);
  vec3 upper    = ceil(ppos);
  vec3 v        = (ppos-lower);

  float x = v.x;
  float y = v.y;
  float z = v.z;

  sumProbes = 0;
  vec4 sampled = vec4((
    sampleProbe(pos,normal,vec3(lower.x,lower.y,lower.z),(1 - x)*(1 - y)*(1 - z)) +
    sampleProbe(pos,normal,vec3(upper.x,lower.y,lower.z),x*(1 - y)*(1 - z) )+ 
    sampleProbe(pos,normal,vec3(lower.x,upper.y,lower.z),(1 - x)*y*(1 - z)  )+ 
    sampleProbe(pos,normal,vec3(lower.x,lower.y,upper.z),(1 - x)*(1 - y)*z )+ 
    sampleProbe(pos,normal,vec3(upper.x,lower.y,upper.z),x*(1 - y)*z )+ 
    sampleProbe(pos,normal,vec3(lower.x,upper.y,upper.z),(1 - x)*y*z  )+ 
    sampleProbe(pos,normal,vec3(upper.x,upper.y,lower.z),x*y*(1 - z) )+ 
    sampleProbe(pos,normal,vec3(upper.x,upper.y,upper.z),x*y*z) 
  )/sumProbes,1);

  return sampled*(probeAmount);
}

  #endif