vec3 calcPointLight(Light light, vec3 normal, vec3 fragPos, vec3 viewDir, vec2 texCoord, float shadow) {
	vec3 lightDir = normalize(light.position - fragPos);
	vec3 halfwayDir = normalize(lightDir + viewDir);

	// Ambient
	vec3 ambient = light.color * vec3(texture(material.ambient, texCoord));

	// Diffuse
	float diff = max(dot(normal, lightDir), 0.0);
	vec3 diffuse = light.color * diff * vec3(texture(material.diffuse, texCoord));

	// Specular
	float spec = pow(max(dot(normal, halfwayDir), 0.0), material.shininess);
	vec3 specular = light.color * spec * vec3(texture(material.specular, texCoord));

	// Attenuation
	float dist = length(light.position - fragPos);
	float attenuation = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * (dist * dist));

	ambient *= attenuation;
	diffuse *= attenuation;
	specular *= attenuation;

	return ambient + (1.0 - shadow) * (diffuse + specular);
}

vec3 calcDirectionalLight(Light light, vec3 normal, vec3 viewDir, vec2 texCoord, float shadow) {
	vec3 lightDir = normalize(-light.direction);
	vec3 halfwayDir = normalize(lightDir + viewDir);

	// Ambient
	vec3 ambient = light.color * vec3(texture(material.diffuse, texCoord));

	// Diffuse
	float diff = max(dot(normal, lightDir), 0.0);
	vec3 diffuse = light.color * diff * vec3(texture(material.diffuse, texCoord));

	// Specular
	float spec = pow(max(dot(normal, halfwayDir), 0.0), material.shininess);
	vec3 specular = light.color * spec * vec3(texture(material.specular, texCoord));

	return ambient + (1.0 - shadow) * (diffuse + specular);
}

vec3 calcSpotLight(Light light, vec3 normal, vec3 fragPos, vec3 viewDir, vec2 texCoord, float shadow) {
	vec3 lightDir = normalize(light.position - fragPos);
	vec3 halfwayDir = normalize(lightDir + viewDir);

	// Ambient
	vec3 ambient = light.color * vec3(texture(material.diffuse, texCoord));

	// Diffuse
	float diff = max(dot(normal, lightDir), 0.0);
	vec3 diffuse = light.color * diff * vec3(texture(material.diffuse, texCoord));

	// Specular
	float spec = pow(max(dot(normal, halfwayDir), 0.0), material.shininess);
	vec3 specular = light.color * spec * vec3(texture(material.specular, texCoord));

	// Intensity
	float theta = dot(lightDir, normalize(-light.direction));
	float epsilon = light.cutoff.x - light.cutoff.y;
	float intensity = clamp((theta - light.cutoff.y) / epsilon, 0.0, 1.0);

	// Attenuation
	float dist = length(light.position - fragPos);
	float attenuation = 1.0 / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * (dist * dist));

	ambient *= intensity * attenuation;
	diffuse *= intensity * attenuation;
	specular *= intensity * attenuation;

	return ambient + (1.0 - shadow) * (diffuse + specular);
}
