在SSAO着色器中计算切线(learnopengl.com教程)

bmvo0sr5  于 2023-08-04  发布在  其他
关注(0)|答案(1)|浏览(119)

我正在尝试编写一个openGL SSAO着色器,我正在遵循这个教程https://learnopengl.com/Advanced-Lighting/SSAO
我对计算切线的片段着色器的这一部分感到困惑:

vec3 tangent   = normalize(randomVec - normal * dot(randomVec, normal));

字符串
我学到了这是格拉姆·施密特过程,我所理解的是,它是找到随机向量的正交于法线的分量
让我困惑的是,这些随机向量是在C++中生成的,并作为平铺纹理传递给着色器并进行采样:

std::vector<glm::vec3> ssaoNoise;
for (unsigned int i = 0; i < 16; i++)
{
    glm::vec3 noise(
        randomFloats(generator) * 2.0 - 1.0, 
        randomFloats(generator) * 2.0 - 1.0, 
        0.0f); 
    ssaoNoise.push_back(noise);
}


解释为“由于样本内核在切线空间中沿着正z方向定向,因此我们将z分量保留为0. 0,因此我们围绕z轴旋转。
那么这是否意味着随机向量是在切空间中定义的,而法线是在视图空间中定义的?这难道不意味着将一个投影到另一个上就没有意义了吗,因为它们处于完全不同的坐标系中?
我的第二个问题是,是否有可能,randomVec最终和法线一样,在这种情况下,使切线成为零向量?

i86rm4rw

i86rm4rw1#

我的理解是:

  • 切线首先是围绕正z轴的半球中的随机向量(在世界原点处)。
  • 将其乘以TBN矩阵,该矩阵旋转切线,使其成为半球中围绕法线(仍在原点)的随机向量。
  • 缩放radius并添加fragPos,因此切线现在表示视图空间中距离片段radius处的3D点。然后,将其转换为屏幕空间,以便更容易测试深度缓冲器内的深度(也在屏幕空间中)。

那么这是否意味着随机向量是在切空间中定义的,而法线是在视图空间中定义的?
切线是在切线空间中定义的,并先移动到视图空间,然后移动到屏幕空间,以便更容易地针对深度缓冲区进行测试。法线仅在用于创建TBN矩阵的算法中使用。
有没有可能randomVec的结果和normal一样,在这种情况下,使得正切为零向量?
理论上是的但更有可能的是,它有一些浮点值,通过缩放/插值部分向法向量缩放。

相关问题