What is a plausible, basic equation/pseudo-code for energy-conservative Blinn-Phong shading, including Fresnel with a coloured light-source?
The net gives so many alternatives that it's hard to figure out which I should use.
I'm not very good with English, let's hope that the variable names are clear.
float3 half_vector = normalize( eye_dir + light_dir );
float n_dot_l = saturate( dot( normal, light_dir ) );
float n_dot_h = saturate(dot( normal, half_vector );
float h_dot_l = saturate(dot( half_vector, light_dir ));
// Amount of reflected energy based on angle
// usually is [f0 + (1-f0)*pow( 1 - l_dot_h, 5 )]
// f0 is another name for specular colour
// should be very low (< 0.17) and gray for dielectric
// should be high (> 0.7) for metals. 1.0 for crome.
float3 fresnel_term = FSlick( f0, l_dot_h );
// Reflected energy is not diffused, so we remove the fresnel
float3 diffuse_term = (1 - fresnel)*albedo/pi;
// implicit visibility term, can be substitute with SmithGGX for better results.
float visibility_term = 0.25;
float phong_blinn = pow( n_dot_h, specular_power );
// Check http://www.farbrausch.de/~fg/stuff/phong.pdf for reference
float blinn_normalization = ( specular_power + 8.0 ) / (8.0*pi);
float normal_distribution = phong_blinn * blinn_normalization;
float3 specular_term = fresnel_term * visibility_term * normal_distribution;
return light_intensity * (diffuse_term + specular_term) * n_dot_l;
Check this http://graphicrants.blogspot.co.uk/2013/08/specular-brdf-reference.html for reference.
Said that most of the game engine use GGX ( https://seblagarde.wordpress.com/2014/11/03/siggraph-2014-moving-frostbite-to-physically-based-rendering/ )