in vec2 uv;

out vec4 C;

uniform float u_t;
uniform float u_bpm;
uniform vec3 bg_col;
uniform vec3 main_col;
uniform vec3 silent_col;

const vec2 ep=vec2(.00035,-.00035);
const float far=160.;
const int STEPCNT=64;
const int SAMPLES=5;
vec3 rand(vec3 p){return fract(sin(p*749.163)*836.164);}
// https://www.shadertoy.com/view/lctGRB
mat3 orthBas(vec3 z) {
    z = normalize(z);
    vec3 up = abs(z.y) < 0.99 ? vec3(0.0, 1.0, 0.0) : vec3(0.0, 0.0, 1.0);
    vec3 x = normalize(cross(up, z));
    return mat3(x, cross(z, x), z);
}
float arrow(vec3 p, float thicc){
    p.y*=-1.;
    p.y+=.5;
    vec2 q=abs(p.xy);
    float SQ2 = sqrt(2.);
    float arrow2d = min(max(q.x,q.y),max(-(p.y-1.5), (q.x+(p.y-1.5))*SQ2));
    return max(abs(p.z)+1.-thicc, arrow2d)-1.;
}
float getDist(vec3 p){
    float t=far;
    for(float z=0.; z<2.; z++){
        t=min(t, arrow(p-vec3(0,0,z*2.),.5));
//        t=min(t, length(p-vec3(0,0,z*1.5))-.5);
    }
    return t;
}
vec3 getNorm(vec3 p){
    return normalize(ep.xyy*getDist(p+ep.xyy)+ep.yyx*getDist(p+ep.yyx)+
    ep.yxy*getDist(p+ep.yxy)+ep.xxx*getDist(p+ep.xxx));
}
vec3 pathtrace(vec2 p) {
    vec3 cd=vec3(.2,-.2,1), 
         ro=orthBas(cd)*vec3(p*5.,-2),
         rd=orthBas(cd)*vec3(0,0,1),
         ld=normalize(vec3(.5,-1.,-.1)),
         po=ro,
         att=vec3(1);
    float lbright=.1;
    float side=1.;
    
    for(int i=0; i<SAMPLES; i++){
        for(int j=0; j<STEPCNT; j++){
            float t=getDist(po);
            vec3 no=getNorm(po);
            po+=rd*t;
            if(t<ep.x){
                att*=vec3(0.1);
                att+=pow(max(dot(-normalize(rd),reflect(ld,no)),0.),2.)*lbright;
                
//                po+=no*ep.x*1.5;
//                rd=reflect(rd,no);
                break;
            }
            if(t>far){
                break;
            }
        }
    }
    return clamp(att, 0., 1.);
}

void main() {
    vec2 UV = vec2(uv.x*R.x/R.y, uv.y);
    C = vec4(pow(pathtrace(UV), vec3(.4545)), 1.0);
}
