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?
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
radiusand addfragPos, so the tangent now represents a 3D point in view space atradiusfrom 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).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.
Theoretically, yes. But more likely it is has some float value that gets scaled toward the normal vector with the scaling/interpolation part.