# Correctly Implementing SSAO

I am trying to implement Normal-Oriented SSAO and i'm having an issue with the results. Portions of the screen are inverted/wrong, typically half way through the screen but not always, it seems tied to the camera, but can also be anything lol. Here is the resulting render:

And here is the SSAO Shader:

void main()
{

vec3 WorldPosition = texture(GPositionsTexture, In_TexCoords).xyz;
vec3 WorldNormal = normalize(UnScaleNormal( texture( GNormalsTexture, In_TexCoords ).xyz ));

vec3 Random = texture(KernalNoiseTexture, In_TexCoords * KernelNoiseScale).xyz;
vec3 Tangent = normalize(Random - WorldNormal * dot(Random, WorldNormal));
vec3 BiTangent = cross(WorldNormal, Tangent);
mat3 TBN = mat3(Tangent, BiTangent, WorldNormal);

float Occlusion = 0.0;
for (int i = 0; i < KERNEL_SIZE; ++i)
{
// get sample position:
vec3 Sample = inverse(TBN) * Kernel[i];
Sample = Sample * Radius + WorldPosition;

// project sample position:
vec4 Offset = vec4(Sample, 1.0);
Offset = CamData.Projection * CamData.View * Offset;
Offset.xy /= Offset.w;
Offset.xy = Offset.xy * 0.5 + 0.5;

// get sample depth:
float SampleDepth = texture(GPositionsTexture, Offset.xy).z;

// range check & accumulate:
float RangeCheck= abs(WorldPosition.z - SampleDepth) < Radius ? 1.0 : 0.0;
Occlusion += (SampleDepth <= Sample.z ? 1.0 : 0.0) * RangeCheck;
}

Occlusion = 1 - (Occlusion / KERNEL_SIZE);

Out_Diffuse = pow(Occlusion, Power);
}

• Hmn, it looks like I may be getting the sample position in tangent-space, but mixing with world-space. i'm supposed to be doing it all in world-space and i believe that vec3 Sample = TBN * Kernel[i]; is going from world to tangent, but it needs to go from tangent to world. that's just by looking at my code. I'll try the inverse when i have time and report back. – Richmar1 Dec 31 '19 at 8:12
• so actually, the original code was inverse. so the results in the picture ARE with vec3 Sample = inverse(TBN) * Kernel[i]; going to modify the code in post – Richmar1 Jan 1 '20 at 0:54
• Just to make sure, CAN this algorithm be done in world-space? As long as i make sure that everything is in world-space, i should be able to do it correct? or must this be done in view space ONLY? – Richmar1 Jan 1 '20 at 0:57
• I'm getting closer, but still can't quite make it work. result still looks the same, but using NSight Graphics Debugger to view some of my pass results, it appears that this line here float SampleDepth = texture(GPositionsTexture, Offset.xy).z; is what's causing the black issue. Offset.xy is going way out of bounds of (0,1) it's trying to access outside of the screen. Not sure why, but it may be my kernel math with TBN – Richmar1 Jan 2 '20 at 7:58
• still can't figure it out. it's been a couple years and i can't figure it out. everything seems fine. i might just nuke the entire thing and start over from scratch – Richmar1 Jan 6 '20 at 7:10