float square(float a)
{
return a*a;
}
float normal_distribution_ggx(vec3 normal, vec3 halfway, float roughness)
{
float a2 = square(square(roughness));
float dotnh = max(dot(normal, halfway), 0.0);
float dotnh2 = square(dotnh);
return a2 / (PI * square(dotnh2 * (a2 - 1.0) + 1.0));
}
float k_direct(float roughness)
{
return square(roughness + 1) / 8;
}
float k_ibl(float roughness)
{
return square(roughness) / 2;
}
float geometry_schlick_ggx(float dotnv, float k)
{
return dotnv / (dotnv * (1.0 - k) + k);
}
float geometry_smith(vec3 normal, vec3 vdir, vec3 point_to_light, float k)
{
float dotnv = max(dot(normal, vdir), 0.0);
float dotnl = max(dot(normal, point_to_light), 0.0);
return geometry_schlick_ggx(dotnv, k) *
geometry_schlick_ggx(dotnl, k);
}
float fresnel_schlick(float cos_theta, float F0)
{
return F0 + (1.0 - F0) * pow(1.0 - cos_theta, 5.0);
}