Menu

Screen Space Reflections

Help
Daniel
2018-10-31
2018-11-03
  • Daniel

    Daniel - 2018-10-31

    Hi!

    Has anyone tried to implement SSR in GLScene?
    I would love some pointers on how to do it.

    http://imanolfotia.com/blog/update/2017/03/11/ScreenSpaceReflections.html

    Cheers

     
  • Jerome.D (BeanzMaster)

    Hi Daniels, it will be possible but need to convert the GLSL shader from your link to OpenGL 2.0 shader. In your link, shader is for opengl core 4.0. GLScene use Opengl Legacy (opengl version < 3.0)

    You can try this

    uniform sampler2D gColor;
    uniform sampler2D gPosition;
    uniform sampler2D gNormal;
    uniform sampler2D gEffect;
    uniform vec2 gTexSizeInv;
    
    // Consts should help improve performance
    const float rayStep = 0.25;
    const float minRayStep = 0.1;
    const float maxSteps = 20;
    const float searchDist = 5;
    const float searchDistInv = 0.2;
    const int numBinarySearchSteps = 5;
    const float maxDDepth = 1.0;
    const float maxDDepthInv = 1.0;
    
    const float reflectionSpecularFalloffExponent = 3.0;
    
    uniform mat4 projection;
    
    vec3 BinarySearch(vec3 dir, inout vec3 hitCoord, out float dDepth)
    {
        float depth;
    
        for(int i = 0; i < numBinarySearchSteps; i++)
        {
            vec4 projectedCoord = projection * vec4(hitCoord, 1.0);
            projectedCoord.xy /= projectedCoord.w;
            projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
    
            depth = texture2D(gPosition, projectedCoord.xy).z;
    
            dDepth = hitCoord.z - depth;
    
            if(dDepth > 0.0)
                hitCoord += dir;
    
            dir *= 0.5;
            hitCoord -= dir;    
        }
    
        vec4 projectedCoord = projection * vec4(hitCoord, 1.0); 
        projectedCoord.xy /= projectedCoord.w;
        projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
    
        return vec3(projectedCoord.xy, depth);
    }
    
    vec4 RayCast(vec3 dir, inout vec3 hitCoord, out float dDepth)
    {
        dir *= rayStep;
    
        float depth;
    
        for(int i = 0; i < maxSteps; i++)
        {
            hitCoord += dir;
    
            vec4 projectedCoord = projection * vec4(hitCoord, 1.0);
            projectedCoord.xy /= projectedCoord.w;
            projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
    
            depth = texture2D(gPosition, projectedCoord.xy).z;
    
            dDepth = hitCoord.z - depth;
    
            if(dDepth < 0.0)
                return vec4(BinarySearch(dir, hitCoord, dDepth), 1.0);
        }
    
        return vec4(0.0, 0.0, 0.0, 0.0);
    }
    
    void main()
    {
        vec2 gTexCoord = gl_FragCoord.xy * gTexSizeInv;
    
        // Samples
        float specular = texture2D(gColor, gTexCoord).a;
    
        if(specular == 0.0)
        {
            gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
            return;
        }
    
        vec3 viewNormal = texture2D(gNormal, gTexCoord).xyz;
        vec3 viewPos = texture2D(gPosition, gTexCoord).xyz;
    
        // Reflection vector
        vec3 reflected = normalize(reflect(normalize(viewPos), normalize(viewNormal)));
    
        // Ray cast
        vec3 hitPos = viewPos;
        float dDepth;
    
        vec4 coords = RayCast(reflected * max(minRayStep, -viewPos.z), hitPos, dDepth);
    
        vec2 dCoords = abs(vec2(0.5, 0.5) - coords.xy);
    
        float screenEdgefactor = clamp(1.0 - (dCoords.x + dCoords.y), 0.0, 1.0);
    
        // Get color
        gl_FragColor = vec4(texture2D(gEffect, coords.xy).rgb,
            pow(specular, reflectionSpecularFalloffExponent) *
            screenEdgefactor * clamp(-reflected.z, 0.0, 1.0) *
            clamp((searchDist - length(viewPos - hitPos)) * searchDistInv, 0.0, 1.0) * coords.w);
    }
    

    Check also here : https://www.gamedev.net/forums/topic/638355-screen-space-reflections-issues/ , https://www.gamedev.net/forums/topic/663280-screen-space-reflections-again/ and here http://ephenationopengl.blogspot.com/2014/01/simulate-wet-surface-with-screen-space.html

     
  • Daniel

    Daniel - 2018-10-31

    Thanks, I will try that shader!

    Any tips on how to get these uniforms from GLScene?
    Are they all textures?

    uniform sampler2D gColor;
    uniform sampler2D gPosition;
    uniform sampler2D gNormal;
    uniform sampler2D gEffect;

     
  • Daniel

    Daniel - 2018-11-03

    All above uniforms are from gBuffer right?
    Is it possible to fetch it from the TGLScene object, or should it be direct OpenGL-code?

     
  • Jerome.D (BeanzMaster)

    Hi, Daniel SSRwork as fullscreen postprocessing. Basically each texure correspond to depth, normal, specular and color buffer.

    The position is represented by the depth buffer and normal buffer give you the direction
    The colors provide from the color buffer
    Finally all are blended in a resulting reflections according to the specular buffer

    And you're right all are accesing throw the G-Buffer.

    Check GLSPostShaders.pas in sources/shader folder for see how to make a post shader

    In GLScene you can have access to the buffers with Opengl frame buffer (TGLFBORenderer) last entry in the scene editor. Take a look in Examples\effects\shadowFBO, \Samples\materials\TransparencyAdvanced and in \Samples\rendering\multisampletexture for how to use it.

    PS : For samples perhaps, you'll need to add GLScene_Runtime package in the depencies of the projects

    Finally this is a really good resources web site on opengl rendering technique
    https://learnopengl.com/Advanced-Lighting/Deferred-Shading for more informations

    An anothers on SSR : https://www.youtube.com/watch?v=K2rs7K4y_sY
    http://imanolfotia.com/blog/update/2017/03/11/ScreenSpaceReflections.html

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.