I readded "+ Fd90" to mimic Disney's BRDF as written. Without it looks pretty dark.
float3 CookTorranceBRDFxCos(float3 n, float3 l, float3 v,
float3 base_color, float roughness, float metalness) {
const float alpha = sqr(roughness);
const float n_dot_l = sat_dot(n, l);
const float n_dot_v = sat_dot(n, v);
const float3 h = HalfDirection(l, v);
const float n_dot_h = sat_dot(n, h);
const float v_dot_h = sat_dot(v, h);
const float Fd90 = F_D90(v_dot_h, roughness);
const float FL = 1.0f + Fd90 - BRDF_F_COMPONENT(n_dot_l, Fd90);
const float FV = 1.0f + Fd90 - BRDF_F_COMPONENT(n_dot_v, Fd90);
const float F_diff = (1.0f - metalness) * FL * FV;
const float3 c_spec = lerp(g_dielectric_F0, base_color, metalness);
const float3 F_spec = BRDF_F_COMPONENT(v_dot_h, c_spec);
const float D = BRDF_D_COMPONENT(n_dot_h, alpha);
const float V = BRDF_V_COMPONENT(n_dot_v, n_dot_l, n_dot_h, v_dot_h, alpha);
const float3 Fd = F_diff * base_color * g_inv_pi;
const float3 Fs = F_spec * 0.25f * D * V;
return (Fd + Fs) * n_dot_l;
}
Though, not that visually different from an older Cook-Torrance version:
float3 CookTorranceBRDFxCos(float3 n, float3 l, float3 v,
float3 base_color, float roughness, float metalness) {
const float alpha = sqr(roughness);
const float n_dot_l = sat_dot(n, l);
const float n_dot_v = sat_dot(n, v);
const float3 h = HalfDirection(l, v);
const float n_dot_h = sat_dot(n, h);
const float v_dot_h = sat_dot(v, h);
const float3 F0 = lerp(g_dielectric_F0, base_color, metalness);
const float3 F_spec = BRDF_F_COMPONENT(v_dot_h, F0);
const float3 F_diff = (1.0f - F_spec) * (1.0f - metalness);
const float D = BRDF_D_COMPONENT(n_dot_h, alpha);
const float V = BRDF_V_COMPONENT(n_dot_v, n_dot_l, n_dot_h, v_dot_h, alpha);
const float3 Fd = F_diff * base_color * g_inv_pi;
const float3 Fs = F_spec * 0.25f * D * V;
return (Fd + Fs) * n_dot_l;
}