JoeyDeVries/LearnOpenGL

Mistake in SSAO

williamhCode opened this issue · 1 comments

While working on SSAO and following the tutorial, i noticed a crucial mistake in the ssao shader.

vec3 samplePos = TBN * samples[i];
samplePos = fragPos + samplePos * radius; 

The TBN matrix converts samples[i] into world space, not into view-space. As a result, the world space offset is added to view space fragPos, which makes for a somewhat believable SSAO but not correct.
Without fix:
image
With fix:
image

As you can see, the results make much more sense with the fix - only corners are darkened, instead of flat surfaces.
This is the code for the fix:

vec3 fragWorldPos = (inverseView * vec4(fragPos, 1.0)).xyz;
...
    vec3 samplePos = TBN * samples[i].xyz;
    samplePos = fragWorldPos + samplePos * radius; 
    samplePos = (view * vec4(samplePos, 1.0)).xyz;

I first get the fragment's world position, calculate the correct samplePos, then convert it back to view space. inverseView is just a uniform which is the inverse of the view matrix.

I believe that the article by John Chapman is incorrect in this regard too.

Great catch! I'll have to take a look and update the code/tutorial when I can find some time, thank you!