varying vec3 vViewPosition;

#ifndef FLAT_SHADED

	varying vec3 vNormal;

#endif


struct BlinnPhongMaterial {

	vec3	diffuseColor;
	vec3	specularColor;
	float	specularShininess;
	float	specularStrength;

};

#if NUM_RECT_AREA_LIGHTS > 0
	void RE_Direct_RectArea_BlinnPhong( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {

		vec3 matDiffColor = material.diffuseColor;
		vec3 matSpecColor = material.specularColor;
		vec3 lightColor   = rectAreaLight.color;

		float roughness = BlinnExponentToGGXRoughness( material.specularShininess );

		// Evaluate Lighting Equation
		vec3 spec = Rect_Area_Light_Specular_Reflectance(
				geometry,
				rectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight,
				roughness,
				ltcMat, ltcMag );
		vec3 diff = Rect_Area_Light_Diffuse_Reflectance(
				geometry,
				rectAreaLight.position, rectAreaLight.halfWidth, rectAreaLight.halfHeight );

		// TODO (abelnation): note why division by 2PI is necessary
		reflectedLight.directSpecular += lightColor * matSpecColor * spec / PI2;
		reflectedLight.directDiffuse  += lightColor * matDiffColor * diff / PI2;

	}
#endif

void RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {

	#ifdef TOON

		vec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;

	#else

		float dotNL = saturate( dot( geometry.normal, directLight.direction ) );
		vec3 irradiance = dotNL * directLight.color;

	#endif

	#ifndef PHYSICALLY_CORRECT_LIGHTS

		irradiance *= PI; // punctual light

	#endif

	reflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );
	reflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;

}

void RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {

	reflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );

}

#define RE_Direct				RE_Direct_BlinnPhong
#define RE_Direct_RectArea		RE_Direct_RectArea_BlinnPhong
#define RE_IndirectDiffuse		RE_IndirectDiffuse_BlinnPhong

#define Material_LightProbeLOD( material )	(0)
