 
 out vec4 color;
 
-void main() {
-  vec3 normal = normalize(fragmentNormal); // normal should be corrected after interpolation
-  vec4 gamma = vec4(vec3(1.0/2.2), 1);
-  vec3 fragmentToCamera = normalize(cameraPos - fragmentPos);
-
-  // direct light TODO: make procedure
-
+vec4 calcDirectionalLight(vec3 normal, vec3 fragmentToCamera) {
   vec4 directAmbientColor = vec4(directionalLight.color, 1) * directionalLight.ambientIntensity;
 
   float directDiffuseFactor = max(0.0, dot(normal, -directionalLight.direction));

  float pointSpecularFactor = pow(max(0.0, dot(fragmentToCamera, pointLightReflect)), materialSpecularFactor);
  vec4 pointSpecularColor = pointLight.specularIntensity * vec4(pointLight.color, 1) * materialSpecularIntensity * pointSpecularFactor / pointLightDistance2;

  vec4 pointColor = pointAmbientColor + pointDiffuseColor + pointSpecularColor;

  // spot light TODO: make procedure

  vec3 spotLightDirection = normalize(fragmentPos - spotLight.position);
  float spotAngleCos = dot(spotLightDirection, spotLight.direction);
  float spotFactor = float(spotAngleCos > spotLight.cutoff) *(1.0 - 1.0*(1.0 - spotAngleCos) / (1.0 - spotLight.cutoff));

  float directSpecularFactor = pow(max(0.0, dot(fragmentToCamera, directLightReflect)), materialSpecularFactor);
  vec4 directSpecularColor = directionalLight.specularIntensity * vec4(directionalLight.color, 1) * materialSpecularIntensity * directSpecularFactor;

  return directAmbientColor + directDiffuseColor + directSpecularColor;
}

vec4 calcPointLight(vec3 normal, vec3 fragmentToCamera) {
  float pointLightDistance = length(fragmentPos - pointLight.position);
  float pointLightDistance2 = 1.0 + pow(pointLightDistance, 2); // 1.0 constant prevents division by zero
  vec3 pointLightDirection = normalize(fragmentPos - pointLight.position);
