@vs vs
vec4 position(mat4 transformProjection, vec4 vertexPosition) {return transformProjection*vertexPosition; }
@end
@fs fs
#define voxelIndex(x, y, z) ((((z * 2) + y) * 2) + x)
layout (location = 0) out vec4 out0;
layout (location = 1) out vec4 out1;
layout (location = 2) out vec4 out2;
layout (location = 3) out vec4 out3;
layout (location = 4) out vec4 out4;
layout (location = 5) out vec4 out5;

uniform sampler3D volume;
uniform int mip;
uniform float z;
uniform sampler3D volume1;
uniform sampler3D volume2;
uniform sampler3D volume3;
uniform sampler3D volume4;
uniform sampler3D volume5;
uniform sampler3D volume6;

void fetchVoxels(out vec4 voxels[8], const in sampler3D t, ivec3 pos, int level){
 voxels = vec4[8](
 texelFetch(t, pos + ivec3(0, 0, 0), level), // 0
 texelFetch(t, pos + ivec3(1, 0, 0), level), // 1
 texelFetch(t, pos + ivec3(0, 1, 0), level), // 2
 texelFetch(t, pos + ivec3(1, 1, 0), level), // 3
 texelFetch(t, pos + ivec3(0, 0, 1), level), // 4
 texelFetch(t, pos + ivec3(1, 0, 1), level), // 5
 texelFetch(t, pos + ivec3(0, 1, 1), level), // 6
 texelFetch(t, pos + ivec3(1, 1, 1), level) // 7
 );
}



void main() {

  int level = max(0,mip-2);
  ivec3 uvw = ivec3(ivec2(gl_FragCoord.xy), z) << 1;
  vec4 voxels[8];
  vec4 vx;
  {
  // +x
  fetchVoxels(voxels, volume1, uvw, level);
  vx=(
    (voxels[voxelIndex(0, 0, 0)] + (voxels[voxelIndex(1, 0, 0)] * (1.0 - voxels[voxelIndex(0, 0, 0)].w))) +
    (voxels[voxelIndex(0, 1, 0)] + (voxels[voxelIndex(1, 1, 0)] * (1.0 - voxels[voxelIndex(0, 1, 0)].w))) +
    (voxels[voxelIndex(0, 0, 1)] + (voxels[voxelIndex(1, 0, 1)] * (1.0 - voxels[voxelIndex(0, 0, 1)].w))) +
    (voxels[voxelIndex(0, 1, 1)] + (voxels[voxelIndex(1, 1, 1)] * (1.0 - voxels[voxelIndex(0, 1, 1)].w)))) ;
  }
  out0 = vx*0.25;
  {
  // +y
  fetchVoxels(voxels, volume2, uvw, level);
  vx=(
    (voxels[voxelIndex(0, 0, 0)] + (voxels[voxelIndex(0, 1, 0)] * (1.0 - voxels[voxelIndex(0, 0, 0)].w))) +
    (voxels[voxelIndex(1, 0, 0)] + (voxels[voxelIndex(1, 1, 0)] * (1.0 - voxels[voxelIndex(1, 0, 0)].w))) +
    (voxels[voxelIndex(0, 0, 1)] + (voxels[voxelIndex(0, 1, 1)] * (1.0 - voxels[voxelIndex(0, 0, 1)].w))) +
    (voxels[voxelIndex(1, 0, 1)] + (voxels[voxelIndex(1, 1, 1)] * (1.0 - voxels[voxelIndex(1, 0, 1)].w)))) ;
  }
  out1 = vx*0.25;
  {
  // +z
  fetchVoxels(voxels, volume3, uvw, level);
  vx=(
    (voxels[voxelIndex(0, 0, 0)] + (voxels[voxelIndex(0, 0, 1)] * (1.0 - voxels[voxelIndex(0, 0, 0)].w))) +
    (voxels[voxelIndex(1, 0, 0)] + (voxels[voxelIndex(1, 0, 1)] * (1.0 - voxels[voxelIndex(1, 0, 0)].w))) +
    (voxels[voxelIndex(0, 1, 0)] + (voxels[voxelIndex(0, 1, 1)] * (1.0 - voxels[voxelIndex(0, 1, 0)].w))) +
    (voxels[voxelIndex(1, 1, 0)] + (voxels[voxelIndex(1, 1, 1)] * (1.0 - voxels[voxelIndex(1, 1, 0)].w)))) ;
  }
  out2 = vx*0.25;
  {
  // -x
  fetchVoxels(voxels, volume4, uvw, level);
  vx=(
    (voxels[voxelIndex(1, 0, 0)] + (voxels[voxelIndex(0, 0, 0)] * (1.0 - voxels[voxelIndex(1, 0, 0)].w))) +
    (voxels[voxelIndex(1, 1, 0)] + (voxels[voxelIndex(0, 1, 0)] * (1.0 - voxels[voxelIndex(1, 1, 0)].w))) +
    (voxels[voxelIndex(1, 0, 1)] + (voxels[voxelIndex(0, 0, 1)] * (1.0 - voxels[voxelIndex(1, 0, 1)].w))) +
    (voxels[voxelIndex(1, 1, 1)] + (voxels[voxelIndex(0, 1, 1)] * (1.0 - voxels[voxelIndex(1, 1, 1)].w)))) ;
  }
  out3 = vx*0.25;
  {
  // -y
  fetchVoxels(voxels, volume5, uvw, level);
  vx=(
    (voxels[voxelIndex(0, 1, 0)] + (voxels[voxelIndex(0, 0, 0)] * (1.0 - voxels[voxelIndex(0, 1, 0)].w))) +
    (voxels[voxelIndex(1, 1, 0)] + (voxels[voxelIndex(1, 0, 0)] * (1.0 - voxels[voxelIndex(1, 1, 0)].w))) +
    (voxels[voxelIndex(0, 1, 1)] + (voxels[voxelIndex(0, 0, 1)] * (1.0 - voxels[voxelIndex(0, 1, 1)].w))) +
    (voxels[voxelIndex(1, 0, 1)] + (voxels[voxelIndex(1, 0, 1)] * (1.0 - voxels[voxelIndex(1, 1, 1)].w)))) ;
  }
  out4 = vx*0.25;
  {
  // -z
  fetchVoxels(voxels, volume6, uvw, level);
  vx=(
    (voxels[voxelIndex(0, 0, 1)] + (voxels[voxelIndex(0, 0, 0)] * (1.0 - voxels[voxelIndex(0, 0, 1)].w))) +
    (voxels[voxelIndex(1, 0, 1)] + (voxels[voxelIndex(1, 0, 0)] * (1.0 - voxels[voxelIndex(1, 0, 1)].w))) +
    (voxels[voxelIndex(0, 1, 1)] + (voxels[voxelIndex(0, 1, 0)] * (1.0 - voxels[voxelIndex(0, 1, 1)].w))) +
    (voxels[voxelIndex(1, 1, 1)] + (voxels[voxelIndex(1, 1, 0)] * (1.0 - voxels[voxelIndex(1, 1, 1)].w)))) ;
  }
  out5 = vx*0.25;
}
@end

