🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Screen Space Reflections problem

Started by
0 comments, last by Alex Gomez Cortes 4 years, 1 month ago

Hello everybody,

I have been trying to implement SSR for some days, but what I get is a bunch of bad “reflections”. I don't know if I have a problem with the different spaces (I doubt it, i work with normals and positions in clip space, all in the same space) or a problem with the ray marching algorithm (I have compared mine to other algorithms on other posts, and I don't see any problem).

I'll post some code and a video so you can get an idea of what I am trying to explain.

Thanks in advance.

In this video you can see the bad reflections, but the reflected ray works somewhat well.

I use the position texture and the normal texture from the Gbuffer (I reuse the deferred textures):

Normals in world space

Positions in world space

I multiply every normal and position by the view and projection matrices of the camera.

mat4 viewNoTranslation = viewMatrix; 
viewNoTranslation[3] = vec4(0.0, 0.0, 0.0, 1.0); //le sacamos la traslacion a la view matrix de la camara
vec4 clipSpaceNormal = projectionMatrix * viewNoTranslation * vec4(normal, 1.0); //normal is the current world           	normal, texture(...) done before

clipSpaceNormal = 2.0 * clipSpaceNormal - 1.0;


vec4 clipSpacePosition = projectionMatrix * viewMatrix * vec4(position, 1.0); //position is the current world position, texture(...) done before

Then I calculate de reflection vector and the hit position:

vec3 reflectionVector = normalize(reflect(normalize(clipSpacePosition .xyz),normalize(clipSpaceNormal .xyz)));

vec3 hitPosition = clipSpacePosition .xyz;

The coords:

float dDepth = 0.0;

vec2 coords =  RayCast(reflectionVector * max(minRayStep, -clipSpacePosition .z), hitPosition, dDepth);

Where RayCast is:

vec2 RayCast(vec3 dir, inout vec3 hitCoord, out float dDepth) 
{
    dir *= rayStep;  

    for (int i = 0; i < maxSteps; i++) {
        hitCoord += dir; 

        vec4 projectedCoord = projectionMatrix * vec4(hitCoord, 1.0);
        projectedCoord.xy /= projectedCoord.w;
        projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5; 
        
        vec4 depth =  projectionMatrix * viewMatrix * texture(gPosition,  projectedCoord.xy);

         if(depth.z > 1000.0)
            continue;
       
        dDepth = hitCoord.z - depth.z; 

        if(dDepth <= 0.0) 
            return projectedCoord.xy;
    }

    return vec2(-1.0);
}

Consts:

const float rayStep = 0.1;
const float minRayStep = 0.1;
const float maxSteps = 20;
const float searchDist = 5;
const float searchDistInv = 0.2;
const int numBinarySearchSteps = 10;
const float maxDDepth = 1.0;
const float maxDDepthInv = 1.0;

Sample reflections (I use the albedo from the Gbuffer):

SSR = texture(gAlbedo, coords) ;

Thanks again.

See you!

This topic is closed to new replies.

Advertisement