
in vec2 uv;
in vec2 uvn;
out vec4 C;

uniform int tex_input;
uniform int tex_var;
uniform int pass;
uniform int tex_eigen;
uniform int width;


void main() {
    vec2 u = uvn;
    
    vec4 eigen = texture(textures[tex_eigen], u)*1.;
    
    vec3 a = texture(textures[tex_input], u).rgb;
    vec2 st = 1./textureSize(textures[tex_input],0);
    
    
    vec4 std_devs = vec4(0);
    vec3 avg_cols[4] = vec3[](vec3(0), vec3(0), vec3(0), vec3(0));
    
    {
        bool gamma = true;
        if(true){
            if(pass == 0){
                vec3 mean = vec3(0);
                vec3 mean_squared = vec3(0);
                float W = 0.;
                for(int x = -width; x <= width; x++){
                    for(int y = -width; y <= width; y++){
                        vec2 oofs = vec2(x,y);

//                        oofs = eigen.xy * float(x) + eigen.zw * float(y);

                        vec3 samp = texture(textures[tex_input], u + oofs*st*1.0).rgb;
                        if(gamma ){
                            samp = pow(samp,vec3(0.454545));
//                            float quant = 0.1;
//                            samp = round(samp/quant)*quant;
                        }
                        mean += samp;
                        mean_squared += samp*samp;
                        W++;
                    }
                }
                
                mean /= W;
                mean_squared /= W;

                float variance = luma(mean_squared - mean*mean);
                C.rgb = mean;
                C.w = max(variance,0.00000001);
            } else {
                float iters = 4;
                float min_var = 1e23;
                for(float i = 0.; i < iters; i++){
                    vec2 offs = vec2(sin(tau*i/iters),cos(tau*i/iters))*float(width)*0.9;
                    
//                    if(true){
//                        if(i == 0){
//                            offs = eigen.xy;
//                        } else if (i == 1){
//                            offs = -eigen.xy;
//                        } else if (i == 2){
//                            offs = eigen.zw;
//                        } else {
//                            offs = -eigen.zw;
//                        }
//                    }
                    vec4 samp = texture(textures[tex_var], u + offs*st);

                    if(gamma ){
                        samp.rgb = pow(samp.rgb,vec3(1./0.454545));
                    }
//                    vec4 samp = texelFetch(
//                        textures[tex_var], 
//                        ivec2(clamp(u + offs*st,0.,0.99)*textureSize(textures[tex_var],0))
//                        ,0
//                    );
                    if(samp.w < min_var){
//                    if(true){
                        min_var = samp.w;
                        C.rgb = samp.rgb;
//                        C.rgb = mix(C.rgb,samp.rgb,1./(float(i) + 1));
                    }
                }
//                for(int )
            }
            
        } else {
            float min_variance = 1e24;
            for(int i = 0; i < 4; i++){
                vec2 offs = vec2(-width + 1, 0);
                //            offs *= 2.;
                if(i == 1){
                    offs.x += width + 1;
                } else if(i == 2){
                    offs.y -= width + 1;
                } else if (i == 3){
                    offs.y -= width + 1;
                    offs.x += width + 1;
                }

                if(true){
                    if(i == 0){
                        offs = eigen.xy;
                    } else if (i == 1){
                        offs = -eigen.xy;
                    } else if (i == 2){
                        offs = eigen.zw;
                    } else {
                        offs = -eigen.zw;
                    }
                }

                vec3 mean = vec3(0);
                vec3 mean_squared = vec3(0);
                
                for(int x = 0; x <= width; x++){
                    for(int y = 0; y <= width; y++){
                        vec2 oofs = offs + vec2(x,y);
                        vec3 samp = texture(textures[tex_input], u + oofs*st*1.0).rgb;
                        mean += samp;
                        mean_squared += samp*samp;
                    }
                }

                float W = (width+1)*(width+1);

                mean /= W;
                mean_squared /= W;

                float variance = luma(sqrt(mean_squared - mean*mean));
                if(variance < min_variance){
                    min_variance = variance;
                    C.rgb = mean*0.2;
                }

            }
            
        }
    }


//    u += eigen*0.04;
    if(length(eigen) > 0.0001){
//        C.r += 2.;
//        C.rg = eigen*100;
    }
    
//    C.rgb = a;
//    C.w = 1.0;
}
