I've got the disney(GGX) brdf running with current vdrift material system, just to see the differences... roughness value 1.0 (smooth) and specular reflectance 0.5
Current brdf without clearcoat (gl2 renderer)
Update: Disney brdf (GGX) without clearcoat (gl2 renderer)
Disney brdf (GGX) without clearcoat max roughness (gl2 renderer)
I am plugging roughness here directly into the brdf, which is not exactly correct, need to use some mapping like disney guys maybe.
Math:
Code:
// Fresnel term F [f0, 1]
// Schlick: F(f0, hv) = f0 + (1 - f0) * (1 - hv)^5
vec3 F(const vec3 f0, const float hv)
{
return f0 + (vec3(1) - f0) * pow(1 - hv, 5);
}
// Microfacet normal distribution D [0, 1]
// Statistical distribution of surface normals
// ag (width) determines shape, ag -> 0 dirac delta
// GGX: D(nh, ag) = ag^2 / (pi * (nh^2 * (ag^2 - 1) + 1)^2)
float D(const float nh, const float ag)
{
float ag2 = ag * ag;
float nh2 = nh * nh;
float s = (nh2 * (ag2 - 1) + 1);
float s2 = s * s;
return ag2 / (PI * s2);
}
// Shadow masking function G [0, 1]
// Needed to maintain energy conservation of D
// ag (width) determines shape, ag -> 0 box function
// GGX: G = G1(nv, ag) * G1(nl, ag) with G1(x, ag) = 2 / (1 + sqrt(ag^2 / x^2 - ag^2 + 1))
float G(const float nv, const float nl, const float ag)
{
float ag2 = ag * ag;
float nl2 = nl * nl;
float nv2 = nv * nv;
return 2 / ((1 + sqrt(ag2 / nl2 - ag2 + 1)) * 2 / (1 + sqrt(ag2 / nv2 - ag2 + 1)));
}
vec3 BRDF(const vec3 fd, const vec3 f0, const float hv, const float nv, const float nl, const float nh, const float roughness)
{
return fd / PI + D(nh, roughness) * F(f0, hv) * G(nv, nl, roughness) / (4 * nl * nv)
}