 	float specular = 0.0;
 	if(diffuse > 0.0){
 		vec3 r = reflect(-d,n);
-		specular = pow(max(dot(r,v),0.0),light.shininess);
+		specular = pow(max(dot(r,v),0.0),lightShininess);
 	}
 	
-	vec3 reflectionColor = vec3(0.0);
-	vec3 rCubeMap = reflect(-v, n);
-	rCubeMap = vec3(inverseV * vec4(rCubeMap,0.0));
-	reflectionColor = texture(textureCubeMap,rCubeMap).rgb;
-	
-	
-	
-	vec3 lightShading = diffuse * diffuseColor + specular * light.Is.rgb;
-	
+	return diffuse * diffuseColor + specular * lightColor;
+}
+
+
+// Compute the shadow multiplicator based on shadow map.
+
+float shadow(vec3 lightSpacePosition){
 	// Shadows
-	float shadow = 0.0;
+	float shadowMultiplicator = 0.0;
 	float bias = 0.005;
 	
 	// If the depth at the current fragment is too high, we are necessarily out of the light frustum, no shadow. Else:
-	if(In.lightSpacePosition.z < 1.0){
+	if(lightSpacePosition.z < 1.0){
 		// PCF sampling: draw eight samples at random around the current position in the shadow map.
 		for (int i=0;i<8;i++){
 			// Draw a random float in [0,1], based on the position of the fragment in world space, scaled and floored to avoid repetitions, and on the current sample index.

									vec2(0.14383161, -0.14100790)
									);

// Returns a random float in [0,1] based on the input vec4 seed.
float random(vec4 p){
	return fract(sin(dot(p, vec4(12.9898,78.233,45.164,94.673))) * 43758.5453);
}


void main(){
	// Compute the normal at the fragment using the tangent space matrix and the normal read in the normal map.
	vec3 n = texture(textureNormal,In.uv).rgb;
	n = normalize(n * 2.0 - 1.0);
	n = normalize(In.tbn * n);

	
	// Compute the direction from the point to the light
	vec3 d = normalize(light.position.xyz - In.position);
	
	vec3 diffuseColor = texture(textureColor, In.uv).rgb;
	
	vec3 worldNormal = vec3(inverseV * vec4(n,0.0));
	vec3 lightColor = texture(textureCubeMapSmall,normalize(worldNormal)).rgb;
	diffuseColor = mix(diffuseColor, diffuseColor * lightColor, 0.5);
	
	// The ambient factor
	vec3 ambient = 0.3 * diffuseColor;
	
	// Compute the diffuse factor
	float diffuse = max(0.0, dot(d,n));

			// Compute a [0-15] index using this random float.
			int randomIndex = int(16.0*randomValue)%16;
			// Compute the shifted position using the poisson disk reference vectors.
			vec2 shiftedPosition = lightSpacePosition.xy + poissonDisk[randomIndex]/500.0;
			// Query the corresponding depth in the shadow map.
			float depthLight = texture(shadowMap, shiftedPosition).r;
			// If the fragment is in the shadow, increment the shadow value.
			shadowMultiplicator += (lightSpacePosition.z - depthLight  > bias) ? 0.125 : 0;
		}
	}
	
	return 1.0 - shadowMultiplicator;
}

void main(){
	
	vec3 ambient;
	vec3 lightShading = shading(In.uv, light.position.xyz, light.shininess, light.Is.rgb,ambient);
	float shadowMultiplicator = shadow(In.lightSpacePosition);
	
	// Mix the ambient color (always present) with the light contribution, weighted by the shadow factor.
	fragColor = ambient * light.Ia.rgb + shadowMultiplicator * lightShading;
	
}
