1

I'm trying to write an openGL SSAO shader and I'm following this tutorial https://learnopengl.com/Advanced-Lighting/SSAO

I'm confused by this part of the fragment shader that calculates the tangent:

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

I learned that this is the Gram Schmidt process, and what I understood is that it's finding the component of randomVec that's orthogonal to normal

What confuses me is that these random vectors are generated as so in C++ and passed to the shader as a tiled texture and sampled:

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);
}  

With the explanation "As the sample kernel is oriented along the positive z direction in tangent space, we leave the z component at 0.0 so we rotate around the z axis.".

So does this mean that the random vectors are defined in tangent space, and the normal is in view space? Doesn't that make it meaningless to project one onto the other as they are in completely different coordinate systems?

And my second question is couldn't it be possible that randomVec ends up the same as normal, in that case making tangent a zero vector?

1 Answers1

1

The way I understand it is:

  • The tangent is firstly a random vector (at the world origin) in the hemisphere around the positive z axis.

  • Multiply it by TBN matrix which rotates the tangent so that it is a random vector in the hemisphere around the normal (still at the origin).

  • Scale by radius and add fragPos, so the tangent now represents a 3D point in view space at radius from the fragment. Then it is converted to screen-space for the benefit of making it easier to test depths within the depth buffer (also in screen-space).

So does this mean that the random vectors are defined in tangent space, and the normal is in view space?

The tangent is defined in tangent space and moved into view space then screen space for easier testing against the depth buffer. The normal is only used in the algorithm for the creation of the TBN matrix.

couldn't it be possible that randomVec ends up the same as normal, in that case making tangent a zero vector?

Theoretically, yes. But more likely it is has some float value that gets scaled toward the normal vector with the scaling/interpolation part.

got here
  • 203
  • 1
  • 7
  • But in order to create the TBN matrix we first need to calculate the tangent – TwoheadedFetus Jun 29 '23 at 12:45
  • Yeah, so the TBN is created from a random vector, not the original tangent, to decrease the samples for good results. It is essentially another element of randomness when moving the tangent into view space. So its pretty much create a random tangent, multiply it by a semi-random normal matrix (TBN) and you get a vector that will be pointing somewhat in the direction of the normal of the fragment, which you scale by radius and test whether that point is below or above (depth test) the fragment at that point (occlusion). – got here Jun 30 '23 at 06:07