Hey there gamedev people,

this is my firt post on the forums, even if I'm reading and searching here for some years now.

I'm studying computer visualistics in Germany and do a lot of OpenGL programming at the moment.

I'm currently trying to implement screen space reflections, but got some issues.

I first gather all informations in a G-Buffer (first pass rendering to frame buffer object) and do the lighting in a second pass.

Then I have a third pass for calculating the reflections.

Unfortunatelly, my reflections seem to be dependent of a certain viewing direction. They start to appear or disappear depending on the incident angle.

After implementing the approach several times and trying to understand the geometry on paper, this seems to be one of my last issues, until the reflections looks correct. I would be very happy if you'd take a lot at my code and hopefully someone can tell me my mistakes, I'd really appreciate that

Here's a short video to better show the problem:

And here's my shader code:

/******************************************************************************/ // LATEST (working, with some perspective errors) /* SSR (screen space reflections) ******************************************************************************/ vec4 SSR() { // Variables vec4 fragmentColor = vec4(0.0f, 0.0f, 0.0f, 0.0f); float initalStep = 0.001f; float stepSize = 0.01f; float blurSize = 1.0f; // Current fragment vec2 fragment = gl_FragCoord.xy/vec2(Screen.Width, Screen.Height); vec2 ssfragment = 0.5f * fragment + 0.5f; vec3 ssPosition = vec3(ssfragment, 0.0f); ssPosition.z = linearizeDepth( texture(deferredDepthTex, vert_UV) ); // Normal & position vec3 vsNormal = normalize(texture(deferredNormalTex, fragment).xyz); vec3 vsPosition = texture(deferredPositionTex, fragment).xyz; // View vector vec3 vsViewVec = normalize( -ssPosition ); vsViewVec.y -= Camera.Position.y; // Reflection vector vec3 vsReflectVec = reflect(vsViewVec, vsNormal); vsReflectVec = normalize(vsReflectVec); // Initialze traced ray vec3 initialRay = vsReflectVec * initalStep; vec3 tracedRay = initialRay; // Get depth informations float fragmentDepth = linearizeDepth(texture(deferredDepthTex, fragment)); vec3 samplingPosition = ssPosition + tracedRay; float sampledDepth = linearizeDepth(texture(deferredDepthTex, samplingPosition.xy)); float rayDepth = ssPosition.z + tracedRay.z * fragmentDepth; // Ray tracing while in screen space int count = 0; while( samplingPosition.x > 0.0f && samplingPosition.x < 1.0f && samplingPosition.y > 0.0f && samplingPosition.y < 1.0f) { // Update sampling position and depth values samplingPosition.x = (2.0f * ssPosition.x - 1.0f) + tracedRay.x; samplingPosition.y = (2.0f * ssPosition.y - 1.0f) + tracedRay.y; sampledDepth = linearizeDepth( texture(deferredDepthTex, samplingPosition.xy) ); rayDepth = ssPosition.z + tracedRay.z * fragmentDepth; // intersection found if(rayDepth > sampledDepth) { if(abs(rayDepth - sampledDepth) < 0.005f) { fragmentColor = vec4( texture(deferredDiffuseTex, samplingPosition.xy).rgb, 1.0f ); break; } // Ray tracing termination break; } else fragmentColor = vec4(texture(deferredDiffuseTex, fragment).rgb, 1.0f); tracedRay += tracedRay * stepSize; count++; } // Return color from sampled fragment return fragmentColor; }