1

After reading the book "Real Time Rendering 4. Edition", I've decided to give online pbr a try and i chose the GGX algorithm for the normal distribution function. The equation shown in this book looks like in this image:

GGX NDF

Now, h is the half vector created from the light and view directions L and V respectively. X(nDotH)+ is 1 if nDotH is greater than 0, else 0. alpha-g is the GGX roughness value between 0 and 1.

My question now is the following: As far as I understood the concept of NDF and roughness, a high alpha value would mean that the (micro)surface is very rough, and a low value smooth. So, if I want to render a smooth metallic surface such as the body of a car, I would set my alpha to a low value such as 0,1. By doing so, the result of my D(h) is so low that the object cant even be seen. Am I missing something or did I not fully understand the value of alpha?

I implemented the NDF in MATLAB to analyse my results. I tried it with the coordinates of a cube placed at origin without transformations. Given 2 coordinates (world space): N = [0.0 1.0 0.0; 0.0 0.0 1.0] P = [-1.0 1.0 1.0; -1.0 1.0 1.0] L-Direction = [0.0 1.0 1.0] C-Position = [0.0 3.0 4.0] alpha = 0.1

Results: D(h) for N1 = 8.6212e-03 D(h) for N2 = 1.7998e-02

As you can see, the values are so low, they aren't visible, specially for the first coordinate whose normal vector point straight up.

tuket
  • 3,232
  • 1
  • 26
  • 41
Miso_Soup
  • 19
  • 5

2 Answers2

1

The root problem is that simple point lights often don't suffice for full PBR rendering. Consider the following two renderings of a smooth metallic sphere:

Sphere renderings

This is the top-left sphere from a glTF sample model rendered in Babylon Sandbox.

On the left side, the sphere is placed in a dark environment against a gray background, and a single point light illuminates the scene. The light is quite bright, but because the sphere is so smooth, and because the "point" nature of the light gives it essentially no radius, the reflection of this light is barely a few pixels, regardless of how bright it may be. The remainder of the sphere has the low D(h) values you mentioned, and is almost black.

On the right side, the same sphere again in the same rendering engine, but this time the engine is using its default environment, which comes from an HDR image. In the case of smooth metal, the resulting render is mostly a mirror reflection of the environment, but rougher and non-metallic surfaces can also have their appearance greatly influenced by colors and intensities in the surrounding environment. With a good quality environment, there's often no need to add point lights at all, and indeed there are no point lights in the right image.

In general, PBR, and particularly metallic PBR, looks best with a full HDRI environment, not just point lights. For some sample code and shaders showing some of this math in action, the Khronos glTF Sample Viewer might be a good place to start. [Disclaimer, I'm a contributor.]

emackey
  • 11,818
  • 2
  • 38
  • 58
  • Thank you for your reply! That makes sense. But what about directional light? And how should I render metals in an online renderer? Simply use a HDR texture for the skybox and fully reflect the sky on the car? – Miso_Soup Feb 07 '23 at 14:55
  • The question of how to render metals in PBR may be too open-ended for Stack Overflow. There are concepts such as pre-convoluted cube maps involved, where each pixel is it own light source for illuminating along a particular reflection vector. You may need to research it, and take a look at existing open-source implementations including the glTF Sample Viewer, etc. Come back and ask a new question if you get stuck. Happy rendering! – emackey Feb 07 '23 at 15:19
0

As far as I understood the concept of NDF and roughness, a high alpha value would mean that the (micro)surface is very rough, and a low value smooth. So, if I want to render a smooth metallic surface such as the body of a car, I would set my alpha to a low value such as 0,1. By doing so, the result of my D(h) is so low that the object cant even be seen. Am I missing something or did I not fully understand the value of alpha?

It's true that the numerator of the equation goes to zero.

But denominator too. And it does so more rapidly.

Taking, as an example, n = h -> dot(n, h) will be one. And if alpha is 0.1:

0.1^2 / (3.141593 * (1 + (0.1^2 - 1))^2)

If you plug that into your calculator you will get ~32.83.

So, as you can see, the whole equation doesn't go to zero.

Actually, if you calculate the limit of the equation as alpha goes to zero, the equation goes to infinity. Which makes sense, because when roughness is zero, all the normals are concentrated in a single direction.

tuket
  • 3,232
  • 1
  • 26
  • 41
  • Thank you for the reply! Well, when n = h, than yes, the NDF is really high. But did you use the values I used for my test? In that case N dot H = 0.6295 and NdotH^2 = 0.396270. Insert this value into the equation and you'll get a division that looks like this: 0.01 / (3.141593 * 0.36928) – Miso_Soup Feb 06 '23 at 15:55
  • @Miso_Soup That makes sense because, when the NDF is smooth, all the micro-normals lay in the same direction (n=h). The NDF tells you "how probable it is to find a micro-normal with that direction". If the micro-normal is not h, then the probability goes to zero. – tuket Feb 07 '23 at 14:51