Nathan Reed

Blog Stuff I’ve Made Talks About Me
C++ Compile-Time Array SizeThree Levels Of Locality In Quantum Physics

How Is The NDF Really Defined?

July 31, 2013 · Graphics, Math · 12 Comments

One of the key ingredients of a microfacet BRDF is its normal distribution function (NDF), which statistically describes the microscopic shape of the surface as a distribution of microfacet orientations. For an NDF to be physically sensible it should satisfy certain conditions, such as normalization. But the correct way to normalize an NDF isn’t what you might intuitively think, and I’d like to explain why.

An NDF is a function that gives, loosely speaking, the “likelihood” of a microfacet being aligned in a particular direction. In the BRDF it serves as a weighting function to scale the brightness of reflections, but the NDF is fundamentally a geometric property of the surface, and we should be able to understand it in such terms, without reference to light scattering.

Since it’s a function of direction, and it has units of inverse solid angle, it seems natural to think of the NDF as a probability density over solid angle. Formally, if we have a direction (unit vector) hhh in the normal hemisphere, and a small piece of solid angle dωhd\omega_hdωh​ representing a set of directions near hhh, then the probability of a microfacet having a normal within dωhd\omega_hdωh​ is D(h) dωhD(h)\,d\omega_hD(h)dωh​, where D(h)D(h)D(h) is the NDF.

Since the probability of the microfacet normal being somewhere in the normal hemisphere should be 100%, the integral of the NDF over the whole normal hemisphere should be 1: ∫ΩD(h) dωh=1 \int_\Omega D(h) \, d\omega_h = 1 ∫Ω​D(h)dωh​=1 Seems simple enough, right? Except it’s wrong! If you take a standard NDF, such as the Blinn-Phong, Beckmann or GGX distribution, and plug it into the above integral, the result will not in general be 1. For example, with the Beckmann distribution and m=0.5m = 0.5m=0.5, the integral above comes out to about 1.113. (Try it in your favorite computer algebra system! I’ll wait.)

It turns out that the correct condition for an NDF to be normalized is: ∫ΩD(h) (n⋅h) dωh=1 \int_\Omega D(h) \, (n \cdot h) \, d\omega_h = 1 ∫Ω​D(h)(n⋅h)dωh​=1 Again, you can try this with your favorite NDF and see that it comes out to 1 as it should.

If you’ve read much about BRDFs and radiometry, the extra n⋅hn \cdot hn⋅h factor is probably screaming out “projected area” at you. Indeed it shows up as the conversion factor between macrosurface area, aligned with nnn, and microfacet area, aligned with hhh:

Microfacet versus macrosurface area

If dAhdA_hdAh​ is a microfacet with normal hhh, and its projection onto the macrosurface is dAdAdA, then dA=(n⋅h) dAhdA = (n \cdot h) \, dA_hdA=(n⋅h)dAh​.

So, it seems the NDF is not just a probability density over solid angle; it has something to do with area as well—in fact, two different area measures: macro-area and micro-area. So what is it really?

You Found a Secret Area!

The GGX paper, Microfacet Models for Refraction through Rough Surfaces by Walter et al., has the answer. According to them, the NDF obeys the equation: dAh=D(h) dωh A dA_h = D(h) \, d\omega_h \, A dAh​=D(h)dωh​A where AAA is a patch of macrosurface small enough to be considered flat, but much larger than an individual microfacet, and dAhdA_hdAh​ is the total area of all the microfacets within AAA that have normals within dωhd\omega_hdωh​.

On this view, the NDF is not a probability density at all! Rather, it’s the density of micro-area over the joint domain of macro-area and solid angle. The area units cancel, so the NDF still has units of inverse solid angle, but the fact that it involves area is required to correctly understand and reason about it.

The normalization condition can then be derived from the above equation: after a bit of fiddling, we get 1A∫(n⋅h) dAh=∫ΩD(h) (n⋅h) dωh \frac{1}{A} \int (n \cdot h) \, dA_h = \int_\Omega D(h) \, (n \cdot h) \, d\omega_h A1​∫(n⋅h)dAh​=∫Ω​D(h)(n⋅h)dωh​ The integral on the left is done over the area of all microfacets in the patch, and that on the right is done over the solid angle of the normal hemisphere. If we require this equation to equal 1, we’re saying that the total projected area of all the microfacets should equal the area of the macrosurface patch. In other words, there are exactly as many microfacets as needed to cover the macrosurface, without holes or overlaps. The normalization condition on the NDF ensures that it’s consistent with this picture.

Walter et al. give a stronger condition: for any direction vvv, we should have ∫ΩD(h) (v⋅h) dωh=n⋅v \int_\Omega D(h) \, (v \cdot h) \, d\omega_h = n \cdot v ∫Ω​D(h)(v⋅h)dωh​=n⋅v The normalization condition follows from this in the special case v=nv = nv=n. The more general condition ensures that the NDF is consistent with the microsurface being manifold, not just a triangle soup. The microsurface’s boundaries must match those of the macrosurface.

(I’m not sure if it’s actually possible for an NDF to satisfy the normalization condition, but fail to satisfy the manifold condition for some other vvv. If you know a counterexample, please post it in the comments!)

Incidentally, I’ve assumed here that microfacet normals are always in the normal hemisphere, which—together with the manifold condition—forces the microsurface to be a heightfield. This is convenient, but not essential. For a general 3D microsurface, just extend all integrals from the hemisphere to the whole sphere. Note that all the dot products are unclamped, and that many standard NDFs like the Blinn-Phong, Beckmann and GGX distributions are zero in the antinormal hemisphere.

The fact that an NDF isn’t just a probability density of microfacet normals over solid angle, and that it needs an n⋅hn \cdot hn⋅h in its normalization, doesn’t seem to be very well-known. It certainly had me confused for some time, and even Real-Time Rendering unfortunately gets this a bit wrong.

C++ Compile-Time Array SizeThree Levels Of Locality In Quantum Physics

12 Comments on “How Is The NDF Really Defined?”

Subscribe

  • RSS RSS

Recent Posts

  • Reading Veach’s Thesis, Part 2
  • Reading Veach’s Thesis
  • Texture Gathers and Coordinate Precision
  • git-partial-submodule
  • Slope Space in BRDF Theory
  • Hash Functions for GPU Rendering
  • All Posts

Categories

  • Graphics(32)
  • Coding(23)
  • Math(21)
  • GPU(15)
  • Physics(6)
  • Eye Candy(4)
© 2007–2024 by Nathan Reed. Licensed CC-BY-4.0.