@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;

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 = mip - 1;
  ivec3 uvw = ivec3(ivec2(gl_FragCoord.xy), z) << 1;
  vec4 voxels[8];
  vec4 vx;
  {

  // +x
  fetchVoxels(voxels, volume, uvw, 0);
    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, volume, uvw, 0);
    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, volume, uvw, 0);
    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, volume, uvw, 0);
    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, volume, uvw, 0);
    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, volume, uvw, 0);
    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

