 diffuseColor.rgb *= ( 1.0 - metalnessFactor );
 
 
+
+GeometricContext geometry = GeometricContext( -vViewPosition, normalize( normal ), normalize(vViewPosition ) );
+
+ReflectedLight directReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) );
+ReflectedLight indirectReflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ) );
+
+
 #if MAX_POINT_LIGHTS > 0
 
 	for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {
 
-		vec3 lightColor = pointLightColor[ i ];
+		IncidentLight directLight = getPointDirectLight( pointLights[ i ], geometry );
 
-		vec3 lightPosition = pointLightPosition[ i ];
-		vec3 lVector = lightPosition + vViewPosition.xyz;
-		vec3 lightDir = normalize( lVector );
+		BRDF_Lambert( directLight, geometry, diffuse, directReflectedLight );
 
-		// attenuation
-
-		float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] );
-
-		// diffuse
-
-		float cosineTerm = saturate( dot( normal, lightDir ) );
-
-		totalDiffuseLight += lightColor * attenuation * cosineTerm;
-
-		// specular
-
-    	vec3 brdf = BRDF_GGX( specularColor, roughnessFactor, normal, lightDir, viewDir );
-
-		totalSpecularLight += brdf * specularStrength * lightColor * attenuation * cosineTerm;
-
+		BRDF_GGX( directLight, geometry, specularColor, roughnessFactor, directReflectedLight );
 
 	}
 

vec3 viewDir = normalize( vViewPosition );

vec3 totalDiffuseLight = vec3( 0.0 );
vec3 totalSpecularLight = vec3( 0.0 );


// roughness linear remapping



	for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) {

		IncidentLight directLight = getSpotDirectLight( pointLights[ i ], geometry );

		BRDF_Lambert( directLight, geometry, diffuse, directReflectedLight );

		BRDF_GGX( directLight, geometry, specularColor, roughnessFactor, directReflectedLight );

	}

