
float fresnel(in float x)
{
	const float Kf = 1.12;
	float numer = (1.0 / pow(x - Kf, 2.0)) - (1.0 / (Kf*Kf));
	float denom = (1.0 / pow(1.0 - Kf, 2.0)) - (1.0 / (Kf*Kf));
	return numer / denom;
}

float shadow(in float x)
{
	const float Ks = 1.01;

	float numer = (1.0 / pow(1.0 - Ks, 2.0)) - (1.0 / pow(x - Ks, 2.0));
	float denom = (1.0 / pow(1.0 - Ks, 2.0)) - (1.0 / (Ks*Ks));

	return numer / denom;
}


vec3 calculate_strauss_model(in vec3 n, in vec3 l, in vec3 e, in float smoothness, in float metalness, in float transparency)
{
	vec3 hv = reflect(l, n);
	float NdotL = dot(l, n);
	float EdotN = dot(e, n);
	float EdotHV = dot(e, hv);

	float fresNdotL = fresnel(NdotL);

	float smooth_cubed = smoothness * smoothness * smoothness;

	float d = 1.0 - metalness * smoothness;
	float rd = (1.0 - smooth_cubed) * (1.0 - transparency);
	float diffTerm = max(NdotL*d*rd, 0.0);

	float r = (1.0 - transparency) - rd;
	float j = fresNdotL * shadow(NdotL) * shadow(EdotN);

	const float k = 1.0;
	float refl = min(r + j*(r + k), 1.0);

	const float c1 = 1.0;
	float cs = c1 + metalness * (1.0 - fresNdotL) * (diffTerm - c1);
	float specTerm = cs * refl * pow(-EdotHV, 3.0/(1.0 - smoothness));

	return vec3(diffTerm, max(specTerm, 0.0), max(fresNdotL, 0.0));
}
