1
\$\begingroup\$

I've been trying to implement screen space reflections for the past couple of days, however it's been difficult finding specific implementation instructions or guides.

Most of the hits on the subject that I can find relate to UE4 or Unity, or a sample implementation in HLSL derived from GLSL work both using different coordinate systems for the y and z axes.

Following what little I could find, I've been using the following shader:

#version 430

layout (std430, binding = 2) buffer Camera_Frag
{        
    mat4 pMatrix;
    mat4 InvPMatrix;
    vec2 ScreenSize;
};

uniform sampler2D ViewNormalMap;
uniform sampler2D DepthMap;
uniform sampler2D LightMap;

in vec2 TexCoord;
layout (location = 0) out vec4 FragColor;

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

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

        vec4 projectedCoord     = pMatrix * vec4(hitCoord, 1.0);
        projectedCoord.xy      /= projectedCoord.w;
        projectedCoord.xy       = projectedCoord.xy * 0.5 + 0.5; 

        float depth             = texture(DepthMap, projectedCoord.xy).r;  
        dDepth                  = hitCoord.z - depth; 

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

    return vec2(0.0f);
}


void main(void)
{    
    vec3 View_Normal            = texture(ViewNormalMap, TexCoord).xyz;      
    float View_Depth            = texture(DepthMap, TexCoord).r;    
    vec3 ScreenPos              = 2.0f * vec3(TexCoord, View_Depth) - 1.0f;
    vec4 View_Pos               = InvPMatrix * vec4(ScreenPos, 1.0f);
         View_Pos              /= View_Pos.w;

    // Reflection vector
    vec3 reflected              = normalize(reflect(normalize(View_Pos.xyz), normalize(View_Normal))); 

    // Ray cast
    vec3 hitPos                 = View_Pos.xyz;
    float dDepth; 
    float minRayStep            = 0.1f;
    vec2 coords                 = RayCast(reflected * max(minRayStep, -View_Pos.z), hitPos, dDepth); 

    FragColor                   = textureLod(LightMap, coords, 0);  
}

I get the scene projected further down, but it isn't upside down. Notice the vases and the plants on top of them. Its like the scene gets resampled and pushed downwards. enter image description here

Can anyone help me understand why I'm not getting the expected results? I've never done any raytracing before, so perhaps I'm misunderstanding how this is supposed to work.

\$\endgroup\$
  • \$\begingroup\$ I think I found the problem, I will test it and write back tomorrow. \$\endgroup\$ – Yattabyte Mar 16 '17 at 3:00
4
\$\begingroup\$

The problem was that I was not using the right DEPTH value.

I noticed that if I increased the minRayStep value from 0.1f to 30.0f, I was getting what resembled somewhat okay reflections. I figured that didn't make a lot of sense as I was sure to be stepping way too far into the depth buffer.

Within my RayCast function, I somehow overlooked that I needed View Space depth, but I was just grabbing the raw NDC depth by mistake.

To fix this I created the following handy function:

vec3 CalcViewPositionFromDepth(in vec2 TexCoord)
{
    // Combine UV & depth into XY & Z (NDC)
    vec3 rawPosition                = vec3(TexCoord, texture(DepthMap, TexCoord).r);

    // Convert from (0, 1) range to (-1, 1)
    vec4 ScreenSpacePosition        = vec4( rawPosition * 2 - 1, 1);

    // Undo Perspective transformation to bring into view space
    vec4 ViewPosition               = InvPMatrix * ScreenSpacePosition;

    // Perform perspective divide and return
    return                          ViewPosition.xyz / ViewPosition.w;
}

And both in main and RayCast:

vec2 RayCast(vec3 dir, inout vec3 hitCoord, out float dDepth)
{
        ...
        float depth             = CalcViewPosition(projectedCoord.xy).z;
        ...
}

void main(void)
{    
    vec3 View_Normal            = texture(ViewNormalMap, TexCoord).xyz;         
    vec3 View_Pos               = CalcViewPosition(TexCoord);
    ...
}
\$\endgroup\$
  • \$\begingroup\$ I think you forgot to pick this as the answer :) \$\endgroup\$ – John Hamilton May 17 '17 at 18:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.