I am working on material system in my renderer recently. My old implementation of microfacet models is all isotropic BRDF, as a result of which, I can’t render something like brushed metals in my renderer. After spending three days in my spare time to extend the system to support anisotropic microfacet BRDF, I easily noticed how much mathematics that it needs to understand all the importance sampling method. The fact that and are somewhat correlated makes the importance sampling a lot more complex than isotropic model. For a detailed derivation of isotropic microfacet importance sampling, please check out my previous blog. I strongly suggest checking it out if the math formula in this blog confuses you because there are a lot of basics that I won’t mention in this blog.

It is gonna be very boring to go through the whole blog. In case you are already bored, here is what you can achieve with the BRDF model. Hopefully, this image can convince you finish reading it.

## Sampling GGX

Following is the formula of GGX:

Then the pdf that we choose to sample this function is:

Since this is a joint density probability function of and , we need to take one sample based on the marginal density probability function first and then take the second sample based on the conditional density function. Let’s take a look at the CDF for first.

Since we are not integrating , I’d like to define a helper term to make the whole derivation shorter.

And then becomes this:

Since there is still in the above CDF, we can not just use the inversion method here directly. However, this above function is gonna help us defining the marginal probability density function for and conditional probability density function for . Following is the marginal probability density function for :

By extending A in the above formula, we can easily get the marginal probability density function as following:

Then we will use the inversion method. So the CDF of the above function is:

By setting a random number ranging from 0 to 1 to the CDF, we can easily acquire the following equation:

Before we dive into the derivation of , there is one minor situation to handle. Because arctan only gives you ranges between and , we need to remap some value to get the full range between 0 and .

Above is a graph that I generated, since our random value goes from 0 to 1, we are only interested in ranges between 0 and 1. The factor doesn’t affect the cycle of this function, it only affects the curve shape. It is fine to sample negative values here since doesn’t always need to be positive, it can be anything as long as it covers the whole range. However, one thing that we can easily notice is that the result goes from and and there is even a remap once the random value is larger than 0.5. My solution is to offset each section by an offset.

Extra special attention needed here to make sure the value is correctly taken in the rare case where the random value happens to be 0.25 or 0.75 so that the final curve is a continuous one. And the can be totally ignored since it is the cycle of cos and sin, which is our only usage for . However, I’d like to add it here just to keep the result in the range of [0, ].

Back to the derivation of , let’s look at the CDF of the conditional density function:

Again let’s set a random value from 0 to 1 to the CDF

Then we easily get the following formula for

A little bit further from the above equation:

Then can also be calculated this way

This is exactly the same thing with the above one except that it has less steps. Before we move forward to the next one, here is the final formula for and for importance sampling of GGX

## Sampling Beckmann

Several concepts are very similar to the above derivation, which we will skip here for simplicity.

The formula for Beckmann is as following:

As usual, the PDF that we use to sample Beckmann is defined as following:

Let’s look at the CDF for :

We gonna use the same A term that we defined earlier to simplify the derivation:

Following is the marginal probability density function for

One minor detail to notice is that since we can’t really approach 90 degree angle for , we will not take it into consideration here. Surprisingly, this is exactly the same with GGX’s marginal probability density function, so we will take everything we have derived here to avoid the duplicated work so that we can move forward to the CDF for directly.

By setting the CDF to it is not hard to get the following equation:

Since is randomly chosen between 0 and 1, we can easily replace with itself, resulting in the final formula for

To summarize, following are the formula we used to importance sample Beckmann:

## Sampling Blinn

Here we will talk about the modified Blinn-Phong model, instead of the original one proposed in paper (An Anisotropic Phong BRDF Model), because it obeys the rule of energy conservation. And the other detail that deserves mentioning is that I will use the exponent term instead of alpha term here:

It goes true along both directions. And the evaluation of Blinn is as following:

Following is the pdf we use to sample Blinn:

The CDF for is as following:

Before we move forward, let’s define a B term to make the whole derivation shorter:

And then the above formula becomes:

Following is the marginal probability density function for :

The CDF for is:

It is not hard to get the following formula for

And we also need to offset this parameter like we did for the previous two sampling method, but the way we do it is almost identical. Last, we need to generate based on the conditional probability density function:

With a random variable equals to the above CDF, we can easily have the following formula:

And again, we can also flip the because it goes from 0 to 1.

Before we sumarize, here is the final formula for importance sampling of Blinn:

## Summary

Importance sampling is always importance for a ray tracer. With the above method, a ray tracer should be able to reach relative noise-free image with reasonalely enough sample taken per pixel.

There is also some future work improving the efficiency of importance sampling for the microfacet model, like sampling visible normal. And it is also the default method for PBRT microfacet model sampling.

Last, not least, if someone is interested in the detailed implementation, they can check it out in my github project here .

### Reference:

[1] Marginal probability density function. https://www.statlect.com/glossary/marginal-probability-density-function

[2] Conditional probability distribution. https://en.wikipedia.org/wiki/Conditional_probability_distribution

[3] Physically Based Rendering http://www.pbrt.org/

[4] Importance Sampling Microfacet-Based BSDFs using the Distribution of Visible Normals https://hal.inria.fr/hal-00996995v1/document

[5] An Improved Visible Normal Sampling Routine for the Beckmann Distribution https://www.mitsuba-renderer.org/~wenzel/files/visnormal.pdf

[6] Specular BRDF Reference http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html

[7] An Anisotropic Phong BRDF Model http://www.irisa.fr/prive/kadi/Lopez/ashikhmin00anisotropic.pdf

[8] Microfacet BRDF http://simonstechblog.blogspot.com/2011/12/microfacet-brdf.html

[9] Phong Normalization Factor derivation http://www.farbrausch.de/~fg/stuff/phong.pdf

[10] Sampling Microfacet BRDF https://agraphicsguy.wordpress.com/2015/11/01/sampling-microfacet-brdf/