 	uniform vec3 cameraPosition;
 */
 
+/*
+	Contains common vectors for different stuff,
+	unclutters the code quite a bit.
+*/
+struct directions
+{
+	vec3 H;
+	vec3 L;
+	vec3 N;
+	vec3 V;
+};
+
 float schlick(float F0, float HdotV)
 {
 	return F0 + (1.0 - F0) * pow((1.0 - HdotV), 5.0);

	L 	incident light vector.
	F 	fresnel coefficient.
*/
vec3 compute_diffuse(vec3 Nn, vec3 L, float F)
{
	return (1.0 - F) * vec3(dot(Nn, L));
}

void main() 
{
	vec3 V = normalize(viewMatrix * vec4(cameraPosition - p, 1.0)).xyz;
	vec3 Lp = (viewMatrix * vec4(light_pos, 1.0)).xyz;
	vec3 L = normalize(p - Lp);
	vec3 H = normalize(L + V);
	// The normalized-normal, interpolated normals
	// might not be unit vectors.
	vec3 Nn = normalize(N);

	vec3 R = normalize(p + reflect(L, Nn));
	
	float F = schlick_ior(1.0, ior, dot((L + -V), -V));

	vec3 refl = F * textureCube(env, R).xyz * 2.0;

	vec3 diffuse = compute_diffuse(Nn, L, F) * vec3(1.0, 1.0, 1.0);
	vec3 spec    = compute_spec(ior, roughness, H, L, Nn, V, F) * vec3(1.0);

	gl_FragColor = vec4(diffuse + spec + refl, 1.0);
}
		G = geometric attenuation.
		F = fresnel coefficient.
	*/
	float NdotH = max(0.0, dot(dir.N, dir.H));
	float NdotV = max(0.0, dot(dir.N, dir.V));
	float VdotH = max(0.0, dot(dir.V, dir.H));
	float NdotL = max(0.0, dot(dir.N, dir.L));

	vec3 R = normalize(p + reflect(dir.L, dir.N));
	vec3 refl = F * textureCube(env, R).xyz * 2.0;

	float G = min(
		1.0, 
