float3 PBR_BRDF(float3 N, float3 V, float3 L, float3 albedo, float roughness, float metal)
{
// N = world normal
// V = view direction
// L = direct light direction
float NV = saturate( dot(N,V) );
float NL = saturate( dot(N,L) );
float3 H = normalize(V+L);
float LH = saturate( dot(L,H) );
float NH = saturate( dot(N,H) );
float3 directSpecular = GGX(LH,NH,L,roughness) * directLightColor;
float3 indirectSpecular = SampleCubemap(N,V,roughness);
// F0 = reflectance, or specular color if metal
// specular color is stored in albedo if metal
float3 F0 = lerp( 0.04, albedo, metal );
// metal materials have black albedo
albedo *= (1-metal);
float3 diffuse = albedo * (ambientColor + directLightColor * DiffuseFunc(NL,NV,roughness) );
float3 specular = (directSpecular * directShadow) + (indirectSpecular * ao);
float3 fresnel = FresnelSchlick(F0, NV, roughness);
float3 color = diffuse + (specular * fresnel);
return color;
}