0

As you can tell from the title, I'm trying to create the mirror reflection while using deferred rendering and ambient occlusion. For ambient occlusion I'm specifically using the ssao algorithm.

To create the mirror I use the basic idea of reflecting all the models to the other side of the mirror and then rendering only the parts visible through the mirror.

Using deferred rendering I decided to do this during the creation of the gBuffer. In order to achieve correct lighting of the reflected objects, I made sure that the positions and normals of the reflected objects in the gBuffer are the same with their 'non reflected' version. That way, both the actual models and their images will receive the same lighting.

My problem is now with the ssao algorithm. It seems that the reflected objects are calculated to be highly occluded and this results in black areas which you can see in the mirror:

enter image description here

I've noticed that these black areas appear only in places that are not in my view. Things that I can see without the mirror have no unexpected black spots on them.

Note that the data in the gBuffer are all in view space. So there must be a connection there. Maybe the random samples used during ssao or their normals are not calculated correctly.

So , this is the fragment shader for the ambient occlusion :

void main()
{
vec3 fragPos = texture(gPosition, TexCoords).xyz;
vec3 normal = texture(gNormal, TexCoords).rgb;
vec3 randomVec = texture(texNoise, TexCoords * noiseScale).xyz;

vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal));
vec3 bitangent = cross(normal, tangent);
mat3 TBN = mat3(tangent, bitangent, normal);

float occlusion = 0.0;
float kernelSize=64;
for(int i = 0; i < kernelSize; ++i)
{
    // get sample position
    vec3 sample = TBN * samples[i]; // From tangent to view-space
    sample = fragPos + sample * radius;
    vec4 offset = vec4(sample, 1.0);
    offset = projection * offset; // from view to clip-space
    offset.xyz /= offset.w; // perspective divide
    offset.xyz = offset.xyz * 0.5 + 0.5;

    float sampleDepth = texture(gPosition, offset.xy).z;

    float rangeCheck = smoothstep(0.0, 1.0, radius / abs(fragPos.z - 
sampleDepth));
    occlusion += (sampleDepth >= sample.z + bias ? 1.0 : 0.0) * rangeCheck;
    
}
occlusion = 1.0 - (occlusion / kernelSize);

//FragColor = vec4(1,1,1,1);
occl=vec4(occlusion,occlusion,occlusion,1);
}

Any ideas as to why these black areas appear or suggestions to correct them? I could just ignore the ambient occlusion in the reflection but I'm not happy with that.

Maybe, if the ambient occlusion shader used the positions and normals of the reflected objects there would be no problem. But then I'll get into trouble of saving more things in the buffer so I gave up that idea for now.

Community
  • 1
  • 1
John Katsantas
  • 571
  • 6
  • 20
  • Can you show us the shader used for creating the gBuffer? Specifically I'm interested in how you deal with surface normals in the reflection. You will have to reflect those normals, too. The usual normal transformation method applies: Transform by transposed inverse of the modelview; hence this will require the mirror-modelview matrix to be used for that. – datenwolf Dec 29 '18 at 23:45
  • Could you show us the RGB representation of the gBuffer normal layer? Use something like Renderdoc to extract it right out of your program as it is. – datenwolf Dec 29 '18 at 23:46

0 Answers0