/*
 * fragment shader for bump lighting, using a normal map
 *
 * written by:
 * christian moellinger <ch.moellinger@gmail.com>
 * 11/2010
 */

#version 330 core

precision highp float;

out vec4 out_Color;
in vec3 my_Texcoord;
in vec3 my_LightDir;
in vec3 my_EyeDir;
in vec3 my_ObjPosition;
in mat4 my_ModelviewMatrix;

uniform mat4 Camera_ProjectionMatrix;
uniform mat4 Camera_TransformMatrix;
uniform mat3 NormalMatrix;

uniform sampler2D color_texture;
uniform sampler2D normal_texture;
uniform sampler2D shadowmap;
uniform mat4 Camera_TempTransformMatrix;
uniform vec4 Light0Position;

const float invRadius = 0.1;

const vec4 Light0Ambient = vec4(0.1);
const vec4 Light0Diffuse = vec4(0.6);
const vec4 Light0Specular = vec4(1.0);

const vec4 MaterialAmbient = vec4(1.0);
const vec4 MaterialDiffuse = vec4(1.0);
const vec4 MaterialSpecular = vec4(1.0);

float calcLight()
{
    float light = 1.0;
    vec4 shadowcoords_f = Camera_TempTransformMatrix * my_ModelviewMatrix * vec4(my_ObjPosition, 1.0);
    vec2 shadowcoords = (shadowcoords_f / shadowcoords_f.w).xy;
    shadowcoords += 1.0;
    shadowcoords *= 0.5;

    float ShadowMapValue = texture(shadowmap, shadowcoords).r;

    float ComparedZ = shadowcoords_f.z / shadowcoords_f.w;

    if (ComparedZ >= ShadowMapValue)
	return 0.2;
    else
	return 1.0;
}

void main(void)
{
    float distSqr = dot(my_LightDir, my_LightDir);

    vec3 lVec = my_LightDir * inversesqrt(distSqr);

    vec3 vVec = normalize(my_EyeDir);

    vec4 bump_value = texture(normal_texture, my_Texcoord.st);

    vec4 texture_value = texture(color_texture, my_Texcoord.st);

    vec4 base = texture_value;

    vec3 bump = normalize(bump_value.rgb * 2.0 - 1.0);

    vec4 vAmbient = Light0Ambient * MaterialAmbient;

    float diffuse = max( dot(lVec, bump), 0.0 );

    vec4 vDiffuse = Light0Diffuse * MaterialDiffuse * diffuse;

    float shadowLight = calcLight();

    float specular = shadowLight * pow(clamp(dot(reflect(-lVec, bump), vVec), 0.0, 1.0), 100.0);

    vec4 vSpecular = Light0Specular * MaterialSpecular * specular;

    vec4 light_value = (vAmbient*base + vDiffuse*base + vSpecular);

    out_Color = shadowLight * light_value * texture_value;
}
