The problem is, that you want the integral to evaluate to 1 and not to "<= 1".
I did solve it for integral = 1. I just wrote it as <= 1. Thanks for noticing.
I wrote a brdf for BRDF explorer with "Mittring" specular.
[source lang="plain"]analytic::begin parametersfloat n 1 1000 100bool normalized 1::end parameters::begin shadervec3 BRDF( vec3 L, vec3 V, vec3 N, vec3 X, vec3 Y ){ vec3 H = normalize( L + V ); float Dot = clamp( dot( N, H ), 0, 1 ); float Threshold = 0.04; float CosAngle = pow( Threshold, 1 / n ); float NormAngle = ( Dot - 1 ) / ( CosAngle - 1 ); float D = exp( -NormAngle * NormAngle ); if (normalized) { D *= 0.17287429 + 0.01388682 * n; //D *= 0.34574858 + 0.02777364 * n; } return vec3(D);}::end shader[/source]
Now when you use mine aprox, then max albedo in BRDF explorer correctly comes up as 1, but when using yours it's 2. This means, that in yours aprox sometimes outgoing energy is two times greater than incoming. I believe it's because you did integrate over full sphere, instead of just upper hemisphere.
Edited by Krzysztof Narkowicz, 16 October 2012 - 03:11 PM.