/*
 www.UltimateGameProgramming.com
 PerPixel Lighting Shader in GLSlang.
 Created by the Programming Ace.


 Varying...
   texCoord0 = output vertex texture coordinates.
   normal = vertex normal.
   pos = vertex pos.


 Uniform...
   decal = binded texture.
   lightPos = light position.
   lightColor = light color.
   ambientColor = ambient color.
   matAmbient = ambient material.
   matDiffuse = diffuse material.
   matSpecular = specular material.
   emissive = emissive contribution.
   shininess = how shinny object is.
   cameraPos = view position.


 Output...
   gl_FragColor = output vertex color.
*/


varying vec2 texCoord0;
varying vec3 normal;
varying vec4 pos;

uniform sampler2D decal;
uniform vec4 lightPos;
uniform vec4 lightColor;
uniform vec4 ambientColor;
uniform vec4 matAmbient;
uniform vec4 matDiffuse;
uniform vec4 matSpecular;
uniform vec4 emissive;
uniform float shininess;
uniform vec4 cameraPos;


void main()
{
   // Re-normalize.
   vec3 n = normalize(normal);

   // Get ambient.
   vec4 ambient = matAmbient * ambientColor;

   // Get diffuse.
   vec4 lightVec = normalize(lightPos - pos);
   float diffuseLight = max(dot(n, lightVec), 0);
   vec4 diffuse = matDiffuse * lightColor * diffuseLight;

   // Get specular.
   vec4 eyeVec = normalize(cameraPos - pos);
   vec4 halfVec = normalize(lightVec + eyeVec);
   float specularLight = pow(max(dot(n, halfVec), 0), shininess);

   // No diffuse, no specular.
   if(diffuseLight <= 0) specularLight = 0;
   vec4 specular = matSpecular * lightColor * specularLight;
   
   // Final lighting color.
   gl_FragColor = (emissive + ambient + diffuse + specular) *
                  texture2D(decal, texCoord0);
   gl_FragColor.w = 1;
}
