<p>Because you are working on screen space, the view ray points towards the eye (being Z the camera space depth). In order to create an orthonormal base, the vectors must be perpendicular to each other. To do this, you set the coordinate z to 0 for the tangents and bitangets, which ensures these vectors will live in the plane perpendicular to the view ray. </p>

<p>Lastly, you need to make the tangent and bitangent perpendicular to each other, which is accomplished with this</p>

<pre><code>vec3 tangent = normalize(rvec - normal * dot(rvec, normal));
vec3 bitangent = cross(normal, tangent);
</code></pre>

CC BY-SA 4.0
2018-09-14T15:11:34.273Z
2018-09-14T15:11:34.273Z
Nadir
<p>I am currently trying to implement SSAO on my graphics engine. I am following John Chapman's tutorial <a href="http://john-chapman-graphics.blogspot.com/2013/01/ssao-tutorial.html" rel="nofollow noreferrer">here</a>. This is a pretty popular article that is used as reference in many SSAO articles.</p>

<p>The part that confuses me is on the generation of rotation vector.</p>

<pre><code>for (int i = 0; i &lt; noiseSize; ++i) {
   noise[i] = vec3(
      random(-1.0f, 1.0f),
      random(-1.0f, 1.0f),
      0.0f
   );
   noise[i].normalize();
}
</code></pre>

<p>Notice that the z component of the vector is zero. In the article John explain that he want to rotate the sample vector around the z axis. But later when he construct the TBN matrix, he use it as if it is a view space coordinate.</p>

<pre><code>vec3 rvec = texture(uTexRandom, vTexcoord * uNoiseScale).xyz * 2.0 - 1.0;
vec3 tangent = normalize(rvec - normal * dot(rvec, normal));
vec3 bitangent = cross(normal, tangent);
mat3 tbn = mat3(tangent, bitangent, normal);
</code></pre>

<p>I don't see any reason why the z vector of the noise vector should be zero. I think that the zero component could be any component. And then what happen if the normal vector is parallel with the noise vector, wouldn't it create a wrong TBN matrix?</p>

<glsl><ssao>
SSAO random noise vector generation
kevinyu
# SSAO random noise vector generation

(Asked by: username_0 on 2018-08-27)

I am currently trying to implement SSAO on my graphics engine. I am following John Chapman's tutorial [here](http://john-chapman-graphics.blogspot.com/2013/01/ssao-tutorial.html). This is a pretty popular article that is used as reference in many SSAO articles.

The part that confuses me is on the generation of rotation vector.

```
for (int i = 0; i < noiseSize; ++i) {
   noise[i] = vec3(
      random(-1.0f, 1.0f),
      random(-1.0f, 1.0f),
      0.0f
   );
   noise[i].normalize();
}

```

Notice that the z component of the vector is zero. In the article John explain that he want to rotate the sample vector around the z axis. But later when he construct the TBN matrix, he use it as if it is a view space coordinate.

```
vec3 rvec = texture(uTexRandom, vTexcoord * uNoiseScale).xyz * 2.0 - 1.0;
vec3 tangent = normalize(rvec - normal * dot(rvec, normal));
vec3 bitangent = cross(normal, tangent);
mat3 tbn = mat3(tangent, bitangent, normal);

```

I don't see any reason why the z vector of the noise vector should be zero. I think that the zero component could be any component. And then what happen if the normal vector is parallel with the noise vector, wouldn't it create a wrong TBN matrix?

**Tags:** glsl, ssao


---

## 1 answers

### Answer by username_1 on 2018-09-14. Score: 1

Because you are working on screen space, the view ray points towards the eye (being Z the camera space depth). In order to create an orthonormal base, the vectors must be perpendicular to each other. To do this, you set the coordinate z to 0 for the tangents and bitangets, which ensures these vectors will live in the plane perpendicular to the view ray.

Lastly, you need to make the tangent and bitangent perpendicular to each other, which is accomplished with this

```
vec3 tangent = normalize(rvec - normal * dot(rvec, normal));
vec3 bitangent = cross(normal, tangent);

```


---

