#version 120

uniform sampler2D tex_diffuse;
uniform sampler2D tex_normal;
uniform sampler2D tex_depth;

uniform vec3    fov_modifier;

uniform vec4    light_pos_ra;   ///< light position (in viewspace) + radius
uniform vec4    light_color_rar;    ///< light color + 1/radius

uniform vec2    res_r;          ///< reciprocal of source buffer's resolution
uniform vec3    depth_range;    ///< near and far clip depths


/// light attenuation function (put this in an "#include" file or something?)
float distFunc(in float dist, in float radius, in float radius_r){
    return pow(max((radius-dist)*radius_r, 0.0), 1.3);
}

/// mangles the depth texture's contents into actual depth values
float readDepth(in vec2 coord) {
    float sample = ((texture2D(tex_depth, coord).x * 2.0) - 1.0);
    return depth_range.z / (sample * (depth_range.y - depth_range.x)
                            - (depth_range.y+depth_range.x));
}

void main(){
    vec2 tex_coord = gl_FragCoord.xy * res_r;
    vec3 eye_vec = vec3(tex_coord * 2.0 - vec2(1.0,1.0), -1.0) * fov_modifier;
    float depth = readDepth(tex_coord);
    vec3 frag_pos = eye_vec * depth;
    vec3 light_vec = light_pos_ra.xyz - frag_pos;

    float dist_factor = distFunc(length(light_vec), light_pos_ra.w, light_color_rar.w);
    light_vec = normalize(light_vec);

    vec4 diffuse = texture2D(tex_diffuse, tex_coord);
    vec3 ns = texture2D(tex_normal, tex_coord).xyz;
    vec3 normal = normalize((ns - vec3(0.5, 0.5, 0.5)) * vec3(2.0, 2.0, 2.0));

    vec3 bpv = normalize(-normalize(eye_vec) + light_vec);
    float spec = max(pow(dot(bpv, normal), 30.0) * 3.0, 0.0);
    float vdn = max(dot(light_vec, normal), 0.0);

	gl_FragColor = vec4(light_color_rar.xyz,1.0) * diffuse
                  * (mix(vdn, 1.0, diffuse.a) + spec) * dist_factor;
}
