const float stp = 2.2;			//size of one step for raytracing algorithm
const float ref = 0.3;			//refinement multiplier
const float inc = 2.0;			//increasement factor at each step
const int maxf = 3;				//number of refinements

vec3 nvec3(vec4 pos){
    return pos.xyz/pos.w;
}

vec4 nvec4(vec3 pos){
    return vec4(pos.xyz, 1.0);
}

float cdist(vec2 coord) {
	return max(abs(coord.x-0.5),abs(coord.y-0.5))*2.0;
}

vec4 raytrace(vec3 skyCol, vec3 fragpos, vec3 normal){
    //vec4 color = vec4(0.0);
    vec4 color = vec4(skyCol, 1.0);
    
    vec3 rvector = normalize(reflect(normalize(fragpos), normalize(normal)));
    vec3 vector = stp * rvector;
    vec3 oldpos = fragpos;
	vec3 pos = vec3(0.0);
    fragpos += vector;
    int sr = 0;

    for(int i = 0; i < 15; i++){
        pos = nvec3(gbufferProjection * nvec4(fragpos)) * 0.5 + 0.5;
        if(pos.x < 0 || pos.x > 1 || pos.y < 0 || pos.y > 1 || pos.z < 0 || pos.z > 1.0) break;
        vec3 spos = vec3(pos.st, texture2D(depthtex1, pos.st).r);
        spos = nvec3(gbufferProjectionInverse * nvec4(spos * 2.0 - 1.0));
		float err = abs(fragpos.z-spos.z);
		if(err < pow(length(vector),1.35)){ // && texture2D(colortex2,pos.st).g > 0.15
                sr++;
                if(sr >= maxf){
                    color = texture2D(colortex0, pos.st);
					color.a = 1.0 - pow(cdist(pos.st), 21.0);
                    break;
                }
                fragpos = oldpos;
                vector *= ref;
        }
        vector *= inc;
        oldpos = fragpos;
        fragpos += vector;
    }

    return color;
}