 

#define AA 2.

vec2 boxIntersection(in vec3 ro, in vec3 rd, in vec3 size)
{
    vec3 m = 1.0/rd;
    vec3 n = m*ro;
    vec3 k = abs(m)*size;
    vec3 t1 = -n - k;
    vec3 t2 = -n + k;
    float tN = max( max( t1.x, t1.y ), t1.z );
    float tF = min( min( t2.x, t2.y ), t2.z );
    if(tN > tF)
        return vec2(-1.0);
    return vec2( tN, tF );
}

mat2 rot(in float t)
{
    float c = cos(t);
    float s = sin(t);
    return mat2(c, -s, s, c);
}

vec3 wavelengthToRGB(float wavelength) {
  vec3 rgb;
  if (wavelength < 380.0) {
    rgb = vec3(0.0, 0.0, 0.0);
  } else if (wavelength < 440.0) {
    rgb = vec3(0.0, 0.0, 0.4 + 0.6 * (wavelength - 380.0) / (440.0 - 380.0));
  } else if (wavelength < 490.0) {
    rgb = vec3(0.0, (wavelength - 440.0) / (490.0 - 440.0), 1.0);
  } else if (wavelength < 510.0) {
    rgb = vec3((wavelength - 490.0) / (510.0 - 490.0), 1.0, 1.0 - (wavelength - 490.0) / (510.0 - 490.0));
  } else if (wavelength < 580.0) {
    rgb = vec3(1.0, 1.0 - (wavelength - 510.0) / (580.0 - 510.0), 0.0);
  } else if (wavelength < 645.0) {
    rgb = vec3(1.0 - (wavelength - 580.0) / (645.0 - 580.0), 0.0, (wavelength - 580.0) / (645.0 - 580.0));
  } else if (wavelength < 781.0) {
    rgb = vec3(0.0, 0.0, 0.4 + 0.6 * (780.0 - wavelength) / (780.0 - 645.0));
  } else {
    rgb = vec3(0.0, 0.0, 0.0);
  }
  return rgb;
}

void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
    vec3 sum = vec3(0);
    for (float x = 0.; x < AA; x++)
    for (float y = 0.; y < AA; y++)
    {
        vec2 uv = (fragCoord+vec2(x,y)/AA-.5*iResolution.xy)/iResolution.y;

        vec3 ro = vec3(0,0,-5);
        vec3 rd = normalize(vec3(uv, 1));

        mat2 r0 = rot( iTime *.1 );
        mat2 r1 = rot(0.4);

        ro.yz *= r1;
        rd.yz *= r1;
        ro.xz *= r0;
        rd.xz *= r0;

        vec2 dist = boxIntersection(ro, rd, vec3(1)) + vec2(1e-4,-1e-4);

        vec3 col = vec3(0);

        vec3 p = ro + rd * dist.x;
        float S = 128.;
        float d = (dist.y-dist.x)/S;

        for (float i = 0.; dist.x > 0. && i < S; i++)
        {
            vec3 k = floor(p*Size)/Size;
            ivec3 v = ivec3((k*.5+.5)*Size);
            if (texelFetch(iChannel0, to2d(v), 0).r > 0.5)
            {
                float c = 0.;
                for (int x = -1; x < 2; x++)
                for (int y = -1; y < 2; y++)
                for (int z = -1; z < 2; z++)
                    c += texelFetch(iChannel0, to2d(v + ivec3(x,y,z)), 0).r;

                float b = 1.;
                for (int y = 1; y < 9; y++)
                    b += texelFetch(iChannel0, to2d(v + ivec3(0,y,0)), 0).r;

                col = wavelengthToRGB( c / 27.0 * (780.-440.) + 440. ) / b;
                break;
            }

            p += rd * d;
        }

        sum += col;
    }

    sum /= AA * AA;

    fragColor = vec4(sum, 1.0);
}
