I'm quite confused as to the relationship between GGX specular and Lambert diffuse... mostly concerning the placement of PI.
I've taken the GGX code from http://www.filmicworlds.com/images/ggx-opt/optimized-ggx.hlsl
(modified the F0 term to be 3 dimensional)
Basically I am adding a vanilla Lambert term divide by PI to that.
Could someone verify this to be correct \ incorrect?
float G1V(float dotNV, float k)
{
return 1.0f/(dotNV*(1.0f-k)+k);
}
float3 LightingFuncGGX_REF(float3 N, float3 V, float3 L, float roughness, float3 F0)
{
float alpha = roughness*roughness;
float3 H = normalize(V+L);
float dotNL = saturate(dot(N,L));
float dotNV = saturate(dot(N,V));
float dotNH = saturate(dot(N,H));
float dotLH = saturate(dot(L,H));
float3 F;
float D, vis;
// D
float alphaSqr = alpha*alpha;
float pi = 3.14159f;
float denom = dotNH * dotNH *(alphaSqr-1.0) + 1.0f;
D = alphaSqr/(pi * denom * denom);
// F
float dotLH5 = pow(1.0f-dotLH,5);
F = F0 + (1.0-F0)*(dotLH5);
// V
float k = alpha/2.0f;
vis = G1V(dotNL,k)*G1V(dotNV,k);
float3 specular = dotNL * D * F * vis;
return specular;
}
float3 directionalLight(float3 N,float3 V,float3 L,float in_rough,float3 in_diffuse,float3 in_specular,float3 in_light)
{
float NdotL = saturate(dot(N,L));
float3 l_specular = LightingFuncGGX_REF(N,V,L,epsilonRough(in_rough),in_specular);
float3 l_diffuse = in_diffuse * PI_INV * NdotL;
return (l_diffuse + l_specular) * in_light;
}