uniform mat4 modelview;
uniform mat4 projection;
in vec3 a_normal;
in vec3 a_vertex;
in vec2 a_textureCoord0;
varying out vec2 textureCoord0;
varying out vec4 color;
struct tLight{
vec4 position;
vec4 ambient;
vec4 diffuse;
vec4 specular;
vec4 spotDirection;
float spotCutoff;
float spotCosCutoff;
float spotExpoent;
float constantAttenuation;
float linearAttenuation;
float quadraticAttenuation;
};
struct tMaterial{
vec4 ambient;
vec4 diffuse;
vec4 specular;
vec4 emissive;
float shininess;
};
uniform struct tLight light0;
uniform struct tMaterial material;
vec4 DirectionalLight(struct tMaterial material,struct tLight light,vec3 vertex,vec3 normal,mat4 MVm){
vec4 finalColor = vec4(0.0,0.0,0.0,0.0);
mat3 normalMatrix = mat3(MVm);
vec3 N = normalMatrix * normal;
//light direction
vec3 position = (MVm * vec4(vertex,1.0)).xyz;
vec3 lightDirection = (MVm * vec4(light.position.xyz,0.0)).xyz;
float lambertTerm = max(dot(normalize(N),normalize(lightDirection)),0.0);
if(lambertTerm > 0.0){
float diffuse = material.diffuse * light0.diffuse * lambertTerm;
vec3 eye = -position;
vec3 HV = normalize(eye + lightDirection);
float specularTerm = max(dot(HV,normalize(normal)),0.0);
vec4 specular = material.specular * light.specular * pow(specularTerm,material.shininess);
finalColor += diffuse + specular;
}
return finalColor;
}
vec4 PointLight(struct tMaterial material,struct tLight light,vec3 vertex,vec3 normal,mat4 MVm){
vec4 finalColor = vec4(0.0,0.0,0.0,0.0);
mat3 normalMatrix = mat3(MVm);
vec3 N = normalMatrix * normal;
//light direction
vec3 position = (MVm * vec4(vertex,1.0)).xyz;
vec3 lightPosition = (MVm * vec4(light.position.xyz,1.0)).xyz;
vec3 lightDirection = lightPosition - position;
float dist = length(lightDirection);
float lambertTerm = max(dot(normalize(N),normalize(lightDirection)),0.0);
if(lambertTerm > 0.0){
vec4 diffuse = material.diffuse * light0.diffuse * lambertTerm;
vec3 eye = -position;
vec3 HV = normalize(eye + lightDirection);
float specularTerm = max(dot(HV,normalize(normal)),0.0);
vec4 specular = material.specular * light.specular * pow(specularTerm,material.shininess);
finalColor += diffuse + specular;
}
float attenuation = 1.0/(light.constantAttenuation +
light.linearAttenuation * dist +
light.quadraticAttenuation * dist * dist);
return finalColor * attenuation;
}
vec4 SpotLight(struct tMaterial material,struct tLight light,vec3 vertex,vec3 normal,mat4 MVm){
vec4 finalColor = vec4(0.0,0.0,0.0,0.0);
mat3 normalMatrix = mat3(MVm);
vec3 N = normalMatrix * normal;
//light direction
vec3 position = (MVm * vec4(vertex,1.0)).xyz;
vec3 lightPosition = (MVm * vec4(light.position.xyz,1.0)).xyz;
vec3 lightDirection = lightPosition - position;
float dist = length(lightDirection);
float lambertTerm = max(dot(normalize(N),normalize(lightDirection)),0.0);
float attenuation = 0.0;
if(lambertTerm > 0.0){
float spotEffect = dot(normalize(-lightDirection),normalize(light.spotDirection.xyz));
if(spotEffect > cos(light.spotCutoff)){
vec4 diffuse = material.diffuse * light0.diffuse * lambertTerm;
vec3 eye = -position;
vec3 HV = normalize(eye + lightDirection);
float specularTerm = max(dot(HV,normalize(normal)),0.0);
vec4 specular = material.specular * light.specular * pow(specularTerm,material.shininess);
finalColor += diffuse + specular;
spotEffect = pow(spotEffect,light.spotExpoent);
attenuation = spotEffect/(light.constantAttenuation +
light.linearAttenuation * dist +
light.quadraticAttenuation * dist * dist);
finalColor += diffuse;
finalColor += specular;
}
}
return finalColor * attenuation;
}
void main(){
vec4 position = modelview * vec4(a_vertex,1.0);
//output position
gl_Position = projection * position;
//output color
color = SpotLight(material,light0,a_vertex,a_normal,modelview);
//output texture coordinates
textureCoord0 = a_textureCoord0;
}