I am implementing anisotropic GGX BRDF and have encountered strange behaviour of my implementation. I thought that if I compare the microfacet distribution function I have with the one of an isotropic GGX, then they should be equal when the anisotropy parameter is 0. I haven't been able to do that, though.

Here is the GGX formula I have used:

enter image description here

Here is the anisotropic GGX formula I have used:

enter image description here

If anisotropy is 0, then \alpha_x is equal to \alpha_y, therefore I can get the following from the second formula:

enter image description here

Problem 1

The problem now is that the third formula can never match the first one because of the negative 1 in the first one.

Problem 2

The specific issue I have when rendering using my anisotropic GGX is that the normals seem to be ignored in the result.

Here is a visualization of the distribution function of isotropic GGX on a flat material patch with normal mapping:

enter image description here

And here is the anisotropic one:

enter image description here


To complete the explanation of my solution, I use H for the half-vector, N for the normal, \alpha for roughness, X for the tangent and Y for the bi-tangent (in my case these are simply aligned with the x and y axes respectively). \alpha_x and \alpha_y represent roughness in the corresponding directions.


  1. Is there a mistake in my reasoning? Is my anisotropic GGX correct?
  2. What is the relationship between the two? Is there a simple explanation for the extension from GGX to anisotropic GGX?
  3. Do you have any general tips for verifying the correctness of one's BRDF implementation?


Here are my main references:

  • $\begingroup$ Try substituting $1/\alpha^2$ with $\cos^2\phi/\alpha^2_x + \sin^2\phi/\alpha^2_y$. $\endgroup$
    – lightxbulb
    Feb 7 '19 at 3:11
  • $\begingroup$ Thanks for your comment, @lightxbulb. That does indeed seem to make the two formulas equal if anisotropy is 0. Before I can investigate further, can you please clarify what ϕ stands for in your formula? $\endgroup$
    – honzukka
    Feb 8 '19 at 6:44
  • $\begingroup$ It's the azimuthal angle (the one accounting for anisotropy). Go to the course notes of "Physically based shading at Disney". Specifically at the end of the pdf you have derivations in the appendix: blog.selfshadow.com/publications/s2012-shading-course $\endgroup$
    – lightxbulb
    Feb 8 '19 at 11:40

After coming back to the problem now with a fresh pair of eyes, I have managed to find my mistake.

Ad Question 1

Yes, the formula is correct. The problem is hidden in the tangent X and bi-tangent Y. When performing normal mapping, the tangent frame has to be perpendicular to the mapped normal, otherwise the term tangent-halfway dot will not carry any information about the normal mapping.

Another issue here might be that once the normal is mapped, the tangent frame is not uniquely determined. Some more info on that can be found here: http://www.thetenthplanet.de/archives/1180. I have decided to solve this the same way as Blender does (look for make_orthonormals_tangent() in their repo) because I need to be compatible with it. Here is my algorithm for that:

bitangent_ortho = norm(cross(normal, tangent))
tangent_ortho = cross(bitangent_ortho, normal)

(Assuming that the normal is mapped and has unit length and the tangent was a valid tangent before the normal was mapped.)

Ad Question 2

This was indeed well answered by user @lightxbulb in a comment to my question. My only problem with the "Physically based shading at Disney" course notes was that the variable symbols weren't very clearly explained. I have since learned that the convention is the following:

  • \theta_v is the angle between the normal and v
  • \phi_v is the azimuthal angle between the tangent and v

Ad Question 3

The only pieces of advice that were useful for me here were the following:

  1. Always come up with the simplest toy examples possible
  2. Verify your assumptions
  3. Visualize everything


I hope this is helpful for somebody else than just me. Good luck implementing BRDFs!


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.