I'm trying to complete a look-up table for an energy-conserving variation of microfacet GGX as implemented here: https://patapom.com/blog/BRDF/MSBRDFEnergyCompensation/
I have a (pretty standard) GGX form of the microfacet equation and my white furnace test behaves similar to what is shown elsewhere (i.e., it loses energy as roughness increases).
However, when I attempt to integrate the brdf and store the total energy in a texture, I get results that are inverse to my expectation - higher roughness yields more total energy in the integral. Some code below (this is done in a compute shader):
float evalSum = 0.0;
const float theta_i = 0.05;
const float phi_i = 0.05;
for (float phiWi = 0.0; phiWi < PI2; phiWi += phi_i)
{
for (float NoL = 0.0; NoL < 1.0; NoL += theta_i)
{
float nohA = 1.0 + NoL * NoV + (1.0 - NoV * NoV) * (1.0 - NoL * NoL) * cos(phiWi);
float NoH = (NoL + NoV) / sqrt(2.0 * nohA);
float D = Fs.eNDF(NoH, roughness);
float G = Fs.eGS(NoV, NoL, roughness);
float Fr = D * G;
evalSum += Fr * NoL;
}
}
outBuf[idx] = evalSum * phi_i * theta_i;
I'm expecting something more like this:

As the Y axis goes down, roughness increases, and as the X axis goes to the right, NoV (N dot V) increases. Total energy increases with roughness and I also get a strange valley to the energy which I wasn't expecting.
Here's the two GGX terms:
float getNDF(const float NoH, float linearRoughness)
{
float a2 = linearRoughness * linearRoughness;
float b = NoH * NoH * (a2 - 1.0) + 1.0;
return a2 / (PI * (b * b));
}
float getGS(const float NoV, const float NoL, const float linearRoughness)
{
float a2 = linearRoughness * linearRoughness;
float G_V = NoV + sqrt((NoV - NoV * a2) * NoV + a2);
float G_L = NoL + sqrt((NoL - NoL * a2) * NoL + a2);
return rcp(G_V * G_L);
}
Pretty stumped here. I must be doing the integral wrong somehow because the in-engine renders look correct - the brdf code seems straightforward. Any ideas on why my LUT is not producing the expected result?

float Fr = D * G;but never using it. Perhaps you forgot something? – Tare May 14 '19 at 08:51I have never seen
– polyrhythm May 16 '19 at 01:22NoLto mean "normal of light"...