#vertex shader
#version 330 core
layout (location = 0) in vec3 coords;
layout (location = 2) in vec3 normal;
out vec3 v_coords;
out vec3 v_normal;

uniform mat4 MVP;
uniform mat4 OM;
uniform mat3 NormalMatrix;

void main()
{
  gl_Position = MVP * OM * vec4(coords, 1.0);
  v_normal = NormalMatrix * normal;
  v_coords = vec3(OM * vec4(coords, 1.0));
};

#fragment shader
#version 330 core
out vec4 FragColor;
in vec3 v_coords;
in vec3 v_normal;

uniform vec3 eye;
uniform vec3 color;
uniform vec3 lightpos;

void main()
{
  vec3 whitened = mix(color, vec3(1.0, 1.0, 1.0), 0.2);
  vec3 lightdir = normalize(v_coords - lightpos);
  vec3 N = normalize(v_normal);
  vec3 refdir = reflect(lightdir, N);
  vec3 viewdir = normalize(eye - v_coords);
  vec3 ambient = color * 0.30;
  vec3 diffuse = color * max(0.0, dot(N, -lightdir)) * 0.50;
  vec3 specular = whitened * pow(max(0.0, dot(viewdir, refdir)), 32) * 0.20;
  vec3 contrast1 = color * max(0.0, dot(N, -normalize(vec3(1, -0.5, -0.2)))) * 0.05;
  vec3 contrast2 = color * max(0.0, dot(N, -normalize(vec3(0.5, 0.4, 0.9)))) * 0.04;
  vec3 contrast3 = color * max(0.0, dot(N, -normalize(vec3(0.4, 0.3, -0.5)))) * 0.07;
  FragColor = vec4(clamp(ambient + diffuse + specular + contrast1 + contrast2 + contrast3, 0.0, 1.0), 1.0);
};
