Please look at my new post in this thread where I supply new information!
I'm trying to implement SSAO in my 'engine' (based on this article) but I'm getting odd results. I know I'm doing something wrong but I can't figure out what's causing the particular issue im having at the moment.
" rel="external">Here's a video of what it looks like . The rendered output is the SSAO map.
As you can see the result is heavily altered depending on the camera (although it seems to be unaffected my camera translation). The fact that the occlusion itself isn't correct isn't much of a problem at this stage, since I've hardcoded a lot of stuff that shouldn't be. E.g. I don't have a random-vector texture, all I do is use one of the sample vectors in order to construct the TBN matrix.
One issue at a time...
My shaders are as follows:
//SSAO VS
struct VS_IN
{
float3 pos : POSITION;
float3 ray : VIEWRAY;
};
struct VS_OUT
{
float4 pos : SV_POSITION;
float4 ray : VIEWRAY;
};
VS_OUT VS_main( VS_IN input )
{
VS_OUT output;
output.pos = float4(input.pos, 1.0f); //already in NDC space, pass through
output.ray = float4(input.ray, 0.0f); //interpolate view ray
return output;
}
Texture2D depthTexture : register(t0);
Texture2D normalTexture : register(t1);
struct VS_OUT
{
float4 pos : SV_POSITION;
float4 ray : VIEWRAY;
};
cbuffer cbViewProj : register(b0)
{
float4x4 view;
float4x4 projection;
}
float4 PS_main(VS_OUT input) : SV_TARGET
{
//Generate samples
float3 kernel[8];
kernel[0] = float3(1.0f, 1.0f, 1.0f);
kernel[1] = float3(-1.0f, -1.0f, 0.0f);
kernel[2] = float3(-1.0f, 1.0f, 1.0f);
kernel[3] = float3(1.0f, -1.0f, 0.0f);
kernel[4] = float3(1.0f, 1.0f, 0.0f);
kernel[5] = float3(-1.0f, -1.0f, 1.0f);
kernel[6] = float3(-1.0f, 1.0f, .0f);
kernel[7] = float3(1.0f, -1.0f, 1.0f);
//Get texcoord using SV_POSITION
int3 texCoord = int3(input.pos.xy, 0);
//Fragment viewspace position (non-linear depth)
float3 origin = input.ray.xyz * (depthTexture.Load(texCoord).r);
//world space normal transformed to view space and normalized
float3 normal = normalize(mul(view, float4(normalTexture.Load(texCoord).xyz, 0.0f)));
//Grab arbitrary vector for construction of TBN matrix
float3 rvec = kernel[3];
float3 tangent = normalize(rvec - normal * dot(rvec, normal));
float3 bitangent = cross(normal, tangent);
float3x3 tbn = float3x3(tangent, bitangent, normal);
float occlusion = 0.0;
for (int i = 0; i < 8; ++i) {
// get sample position:
float3 samp = mul(tbn, kernel[i]);
samp = samp * 1.0f + origin;
// project sample position:
float4 offset = float4(samp, 1.0);
offset = mul(projection, offset);
offset.xy /= offset.w;
offset.xy = offset.xy * 0.5 + 0.5;
// get sample depth. (again, non-linear depth)
float sampleDepth = depthTexture.Load(int3(offset.xy, 0)).r;
// range check & accumulate:
occlusion += (sampleDepth <= samp.z ? 1.0 : 0.0);
}
//Average occlusion
occlusion /= 8.0;
return min(occlusion, 1.0f);
}
I'm fairly sure my matrices are correct (view and projection) and that the input rays are correct.
I don't think the non-linear depth is the problem here either, but what do I know I haven't fixed the linear depth mostly because I don't really understand how it's done...
Any ideas are very appreciated!