Final Oren-Nayar diffuse with Fresnel approximaton from research.tri-ace.com (0) in HLSL.
////////////////////////////////////////////////// // a = roughness // // f0 = fresnel // // LdN = dot( light_direction, surface_normal ) // // VdN = dot( view_direction, surface_normal ) // // LdV = dot( light_direction, view_direction ) // ////////////////////////////////////////////////// float fTheta = f0+dot((1.0f-f0), pow(2.0f, -9.60232*pow(VdH,8.0f)-8.58092*VdH)); float Bp = 0.0f; float Bpl = LdV-(VdN*LdN); float Fr = (1.0f-(0.542026f*(a*a)+0.303573f*a)/((a*a)+1.36053f))* (1.0f-(pow(1.0f-VdN,5.0f-4.0f*(a*a)))/((a*a)+1.36053f))* ((-0.733996*(a*a*a)+1.50912*(a*a)-1.16402*a)*(pow(1.0f-VdN,1.0f+(1.0f/(39.0f*(a*a*a*a)+1.0f))))+1.0f); float Lm = (max(1.0f-(2.0f*a),0.0f)*(1.0f-(1.0f-pow(LdN,5.0f)))+min(2.0f*a,1.0f))*((1.0f-0.5f*a)*LdN+(0.5*a)*(pow(LdN,2.0f))); float Vd = ((a*a)/(((a*a)+0.09f)*(1.31072f+0.995584f*VdN)))*(1.0f-(pow(1.0f-LdN,(1.0f-0.3726732*(VdN*VdN))/(0.188566f+0.38841*VdN)))); if (Bpl < 0.0f) Bp = 1.4f*VdN*LdN*(LdV-(VdN*LdN)); else Bp = LdV-((VdN*LdN)); float aDiffuse = (21.0f/(20.0f*pi))*(1.0f-f0)*((Fr*Lm)+(Vd*Bp));