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):
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!