I try to implement screen space reflections in my graphics engine using ray marching algorithm. After a lot of trying I got this result:
As you can see, the reflections are cut off if you get closer and stretched if you move further away. All vectors seem to be in view space, the transformation function between spaces is correct.
void main()
{
vec4 texelNormalWS = getNormal(TexCoords);
vec4 texelNormalVS = inverse(transpose(view)) * texelNormalWS;
vec4 texelPositionWS = getPosition(TexCoords);
vec3 viewDirVS = (view * texelPositionWS).xyz;
vec3 reflectDirVS = normalize(reflect(normalize(viewDirVS.xyz),normalize(texelNormalVS.xyz)));
...
color = vec4(ssrVS(viewDirVS, reflectDirVS),1.0f);
}
vec2 viewSpaceToSS(vec3 position)
{
vec4 pVP = proj * vec4(position,1.0f);
pVP.xy /=pVP.w;
pVP.xy = pVP.xy * 0.5f + 0.5f;
return pVP.xy;
}
vec2 BinarySearchVS(vec3 ray, vec3 dir)
{
vec2 projectedCoords;
float depth;
for(int i = 0; i < 5; i++)
{
projectedCoords = viewSpaceToSS(ray);
depth = getPosition(projectedCoords).z;
float dDepth = ray.z - depth;
dir *= 0.5f;
if(dDepth > 0.0f)
ray += dir;
else
ray -= dir;
}
ray.z-=depth;
return viewSpaceToSS(ray);
}
vec3 ssrVS(vec3 ray, vec3 dir)
{
float stepSize = 0.2f;
const int maxSteps = 100;
vec2 projectedCoords;
dir*=stepSize;
for(int i = 0; i < maxSteps; i++)
{
ray+=dir;
projectedCoords = viewSpaceToSS(ray);
float depth = getPosition(projectedCoords).z;
if (depth > 100.0f)
continue;
float dDepth = ray.z - depth;
if(dDepth <= 0 && dir.z - dDepth < 1.2)
projectedCoords = BinarySearchVS(ray,dir);
}
return getColor(projectedCoords).xyz;
}
Any idea how to fix this distortion?
UPD:
I figured out that
if(dDepth <= 0 && dir.z - dDepth < 1.2)
doesn't hit most of the time.
I added after hit checking branch:
return vec3(1.0f,0.0f,0.0f);
got this: