I am working on implementing Crytek's original SSAO implementation and I have found myself stuck and confused at the part where I need to find the view-space position of the sample. I have implemented a method which I feel should work however, it seems to give me an odd result with blackening occurring at the back. Am I missing something? Would appreciate any insight, thanks in advance.
vec3 depthToPositions(vec2 tc)
{
float depth = texture(depthMap, tc).x;
vec4 clipSpace = vec4(tc * 2.0 - 1.0, depth, 1.0);
vec4 viewSpace = inverse(camera.proj) * clipSpace;
return viewSpace.xyz / viewSpace.w;
}
for(int i = 0; i < ssao.sample_amount; ++i) {
// Mittring, 2007 "Finding next gen CryEngine 2" document suggests to reflect sample
vec3 samplePos = reflect(ssao.samples[i].xyz, plane);
samplePos.xy = samplePos.xy * 0.5 + 0.5; // conver to 0-1 texture coordinates
samplePos = depthToPositions(samplePos.xy); // this is how I am retrieving view-space position of sample
samplePos = viewSpacePositions + samplePos * radius;
vec4 offset = vec4(samplePos, 1.0);
offset = camera.proj * offset;
offset.xyz /= offset.w;
offset.xy = offset.xy * 0.5 + 0.5;
float sampleDepth = texture(gPosition, offset.xy).z;
float rangeCheck = (viewSpacePositions.z - sampleDepth) < radius ? 1.0 : 0.0;
occlusion += (sampleDepth >= samplePos.z + bias ? 1.0 : 0.0) * rangeCheck;
}
Generating samples in C++
for(unsigned int i = 0; i < 64; i++) {
glm::vec4 sample(
randomFloats(generator) * 2.0 - 1.0,
randomFloats(generator) * 2.0 - 1.0,
randomFloats(generator) * 2.0 - 1.0, 0.0);
sample = glm::normalize(sample);
sample *= randomFloats(generator);
float scale = float(i) / 64;
scale = Lerp(0.1f, 1.0f, scale * scale);
sample *= scale;
ssaoKernel.push_back(sample);
}