Actually, I can kind of resolve my "flat plane paradox" with a bit of a reinterpretation of the law...

Let's say for simplicity that:

* when V is glancing and L is overhead: 0% of the light is reflected, meaning 100% is diffused. When it's diffused, 1% reaches the camera.

* when L is glancing and V is overhead: 99% of the light is reflected, meaning 1% is diffused. When it's diffused, 1% of that 1% reaches the camera.

The law only talks about particular **rays** of light, but when a ray hits a surface it splits in two! I can interpret the law as if "a ray" is one particular sequence of rays, picking **one** arbitrary exit ray at every surface interaction.

So, if I only track the light that takes one particular path at the boundary, the refracted path only:

* when L is glancing and V is overhead: 0.01% reaches the camera, but 99% of the input energy was invalidated as it took the wrong path. If I divide the measured light by the amount that took the "valid path", then I get 0.0001 / 0.01 == 1%, which is the same as when L and V are swapped.

I don't know if I'm tired and bending the rules to make garbage makes sense, or if this is the way I should be interpreting reciprocity...

If this is true, then the specular term of a BRDF should obey the rule in isolation, and also the diffuse term in isolation... but when you add the two together, it's possible to break the rule, which maybe is OK, because you're adding output rays that followed different paths? If that's the case, then the real rule is that *each particular path* within a BRDF should obey reciprocity?

[edit] No, don't listen to me, this isn't how physics works. The fact that reciprocity doesn't hold for my above thought experiment shows that the thought experiment is based on flawed assumptions... [/edit]

Not quite. If you assume that your surface is perfectly flat, your microfacet distribution, as you mentioned, returns 1 where N=H and 0 where N!=H, and thus your BRDF only returns a value other than 0, when N=H.

Only the specular part of the BRDF has that behaviour -- the Lambertian part is just a constant number regardless of V/L/H (*unless we try to make it energy conserving*).

To try and make the Lambertian part energy conserving, I've got to find the amount of light that's refracted. Any physics textbook will tell you that you can use Fresnel's law for this, and it won't include the viewer's location at all! Only the light source and the normal are considered (*in this example, our macro-normal and all our microfacet normals are equal, so we can ignore microfacet distributions*).

The physically correct amount of energy to input into the Lambertian term in this example, is based on the Fresnel term for NdotL.