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

/**
 * Fragment shader stinovych map
 * Pridava rozmazani pomoci PCF
 */

#version 420

in vec3 position;
in vec3 normal;
in vec2 tc;

uniform sampler2D KaTex;
uniform vec3 Ka;
uniform vec3 La;
uniform vec3 Ld;
uniform vec3 Ls;
uniform vec3 lightPos;
uniform vec3 cameraPos;

in vec4 shadowPos;
uniform sampler2DShadow shadowTexture;
uniform float offset;

out vec4 fragColor;

uniform float shininess=32;
uniform int filterSize=3;


float getShadow(){
    vec4 shadowPosW =shadowPos/ shadowPos.w;

    if (shadowPosW.w <= 0.0f || shadowPosW.z>1 ||
	    shadowPosW.x < 0 || shadowPosW.y < 0 ||
	    shadowPosW.x >= 1 || shadowPosW.y >= 1){
	// mimo texturu
	return 1.0;
    } else {

	float sum=0;

	int d=filterSize/2;

	for(int x=-d;x<=d;x+=1){
	    for(int y=-d;y<=d;y+=1){
		// toto na ATI nejede, offset musi byt konstanta
		sum += textureProjOffset(shadowTexture, vec4(shadowPosW.xy,shadowPosW.z-offset,1),ivec2(x,y)).x;
	    }
	}

	return sum/(filterSize*filterSize);
    }
}


void main() {
    float sh = getShadow();

    vec3 col = Ka+texture(KaTex,tc).rgb;

    vec3 N = normalize(normal);
    vec3 L = normalize(lightPos-position);
    vec3 A = La*col;
    vec3 D = Ld*max(dot(L,N),0)*col;
    vec3 S = vec3(0,0,0);
    if(shininess>0){
	vec3 V = normalize(cameraPos-position);
	vec3 R = reflect(-L,N);
	float spec = pow(max(0,dot(R,V)),shininess);
	S = spec*Ls;
    }

    fragColor = vec4(A+(D+S)*sh,1);
}
