/**
 *
 * Diplomova prace
 * Stinove techniky na dnesnim hardware a jejich porovnani
 *
 * Michal Toth
 *
 * Fakulta informacnich technologii
 * Vysoke uceni technicke v Brne
 *
 * 2013/2014
 *
 */

/*
 * Fragment shader pro stinove mapy s cubemapou
 * vykresluje nekolik svetel ajednou
 */

#version 420

#define MAX_LIGHTS 32-3
in vec2 tc;

uniform sampler2D texMaterial;
uniform sampler2D texNormal;
uniform sampler2D texDepth;

uniform vec3 La[MAX_LIGHTS];
uniform vec3 Ld[MAX_LIGHTS];
uniform vec3 Ls[MAX_LIGHTS];
uniform vec3 lightPos[MAX_LIGHTS];
uniform vec3 cameraPos;

uniform samplerCubeShadow  shadowTexture[MAX_LIGHTS];

uniform int lightCount=1;

uniform float far;
uniform float near;
uniform float offset;
uniform mat4 imvp;

out vec4 fragColor;

uniform float shininess=32;


float dir2depth(vec3 dir)
{
    vec3 absDir = abs(dir);
    float z = max(absDir.x, max(absDir.y, absDir.z));
    float c = (far+near) / (far-near) - (2*far*near)/(far-near)/z;
    return (c + 1.0) * 0.5;
}

void main() {
    float depth = texture(texDepth,tc).x;
    vec3 normal = texture(texNormal,tc).xyz;
    vec4 pos = imvp*vec4(tc*2-1,depth*2-1,1);
    vec3 position = pos.xyz/pos.w;

    vec3 color=vec3(0,0,0);


    vec3 N = normalize(normal);
    vec3 col = texture(texMaterial,tc).xyz;
    vec3 V = normalize(cameraPos-position);

    for(int i=0;i<lightCount;i++){
	vec3 dir = position-lightPos[i];
	float dirDepth=dir2depth(dir);
	float sh;
	if(dirDepth>=1.0) sh=1;
	else sh = texture(shadowTexture[i],vec4(dir,dirDepth-offset)).x;

	vec3 L = normalize(lightPos[i]-position);
	vec3 A = La[i]*col;
	vec3 D = Ld[i]*max(dot(L,N),0)*col;
	vec3 S = vec3(0,0,0);
	/*if(shininess>0){
	    vec3 R = reflect(-L,N);
	    float spec = pow(max(0,dot(R,V)),shininess);
	    S = spec*Ls;
	}*/
	color +=A+(D+S)*sh;

    }

    fragColor= vec4(color,1);

}
