英文:
I need help understanding the GGX normal distribution function
问题
在阅读了《Real Time Rendering 4. Edition》之后,我决定尝试在线PBR,并选择了GGX算法作为法线分布函数。该书中显示的方程式如下图所示:
现在,h是由光线和视角方向L和V分别创建的半向量。X(nDotH)+是当nDotH大于0时为1,否则为0。alpha-g是介于0和1之间的GGX粗糙度值。
我的问题是:据我理解,NDF和粗糙度的概念,高alpha值意味着(微观)表面非常粗糙,而低值则表示光滑。所以,如果我想渲染一个光滑的金属表面,比如汽车的车身,我会将我的alpha值设置为较低的值,比如0.1。但是,这样做的话,我的D(h)的结果太低,甚至无法看到物体。我是不是漏掉了什么,或者我没有完全理解alpha的值?
我在MATLAB中实现了NDF以分析我的结果。我尝试了一个位于原点的立方体的坐标,没有进行变换。
给定两个坐标(世界空间):
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
结果:
N1的D(h) = 8.6212e-03
N2的D(h) = 1.7998e-02
如你所见,这些值非常低,几乎看不到,特别是对于法线向上的第一个坐标。
英文:
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:
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.
答案1
得分: 1
根本问题在于简单的点光源通常不足以实现全PBR渲染。考虑下面这两个对一个光滑金属球体的渲染:
这是一个gLTF示例模型中左上角的球体,在Babylon Sandbox中渲染出来的。
在左侧,球体置于一个黑暗环境中,背景为灰色,一个单一的点光源照亮了场景。光源非常亮,但由于球体非常光滑,并且由于光源的“点”性质使其基本上没有半径,该光的反射仅仅是几个像素,无论它有多亮。球体的其余部分具有你提到的低D(h)值,并且几乎是黑色的。
在右侧,同样的球体再次出现在同一个渲染引擎中,但这次引擎使用的是默认环境,来自一个HDR图像。对于光滑的金属,渲染的结果主要是环境的镜面反射,但是粗糙和非金属表面的外观也可以受到周围环境中颜色和强度的极大影响。有了高质量的环境,通常根本不需要添加点光源,实际上右图中根本没有点光源。
总的来说,PBR,特别是金属PBR,在全HDRI环境下效果最好,而不仅仅是点光源。如果你想看一些这种数学运算实际应用的示例代码和着色器,Khronos glTF示例查看器可能是个不错的起点。[免责声明,我是一个贡献者。]
英文:
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:
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.]
答案2
得分: 0
> 据我理解 NDF 和粗糙度的概念,高 alpha 值意味着(微观)表面非常粗糙,而低值表示平滑。所以,如果我想渲染类似汽车车身这样的光滑金属表面,我会将 alpha 设置为较低的值,比如 0.1。但这样做会导致 D(h) 的结果非常低,以至于对象几乎看不见。我是不是漏掉了什么,或者我没有完全理解 alpha 值的含义?
方程的分子的确趋近于零。
但分母也是如此,而且它的趋近速度更快。
以 n = h
为例 - dot(n, h)
将为一。如果 alpha 是 0.1:
0.1^2 / (3.141593 * (1 + (0.1^2 - 1))^2)
如果你在计算器上计算这个,结果将约为 ~32.83。
因此,整个方程并没有趋近于零。
实际上,如果计算当 alpha 趋近于零时方程的极限,方程将趋向无穷大。这是有道理的,因为当粗糙度为零时,所有法线都集中在一个方向上。
英文:
> 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论