Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 3 of 3

Thread: Reflection Ray incorrect

  1. #1
    Junior Member Newbie
    Join Date
    Sep 2015
    Posts
    22

    Reflection Ray incorrect

    I need to implement screen space reflections.

    As a first step, I want my fragment shader to draw one reflected, red ray.
    That ray shall begin at world pos x=100,y=0,z=100. For debugging, this world position is drawn as a green square, you can see it in the screen shot.
    The ray needs to be the imagined ray from the camera to world pos 100,0,100 (the green square), reflected on the ground (i.e. reflected at pos 100,0,100).
    The camera x and z values are marked by a big yellow square, to verify the camera position is transferred correctly via a uniform vector into the shader - seems as if this works.

    My shader whose code is listed below recalculates the very same reflected ray for each fragment and checks if the current fragment is near to the ray, if this is the case, the current fragment is drawn in red, otherwise the fragment is read from a previously rendered screen buffer texture.

    Here's a screen shot how this looks like:

    Click image for larger version. 

Name:	Ray6.jpg 
Views:	116 
Size:	15.0 KB 
ID:	2120

    Here's my fragment shader code:

    Code :
    in vec3 in_pos;
    in vec3 norm_wc;
    in vec4 pos_wc;
    in vec4 gl_FragCoord;
     
    out vec4 out_col;
     
    uniform mat4 proj;
    uniform mat4 view;
    uniform mat4 model;
    uniform vec3 cam_pos;
    uniform int comb;
     
    uniform sampler2D screenbuffer_tex;
     
    void main() {
        vec3 CamPos = cam_pos; // the camera position
        vec3 RayPosOriginal = vec3(100.0, 0.0, 100.0); // the green square
        vec3 CamToFragmentDir = ((comb % 16) >= 8 ? +1.0 : -1.0) * normalize(RayPosOriginal - CamPos); // the ray from camera to green square
        vec3 GroundNormal; // the normal at the green square
        if ((comb % 8) == 0)
            GroundNormal = normalize(vec3(-1.0, -1.0, -1.0));
        if ((comb % 8) == 1)
            GroundNormal = normalize(vec3(+1.0, -1.0, -1.0));
        if ((comb % 8) == 2)
            GroundNormal = normalize(vec3(-1.0, +1.0, -1.0));
        if ((comb % 8) == 3)
            GroundNormal = normalize(vec3(-1.0, -1.0, +1.0));
        if ((comb % 8) == 4)
            GroundNormal = normalize(vec3(+1.0, +1.0, -1.0));
        if ((comb % 8) == 5)
            GroundNormal = normalize(vec3(+1.0, -1.0, +1.0));
        if ((comb % 8) == 6)
            GroundNormal = normalize(vec3(-1.0, +1.0, +1.0));
        if ((comb % 8) == 7)
            GroundNormal = normalize(vec3(+1.0, +1.0, +1.0));
        vec3 ReflectionDir = normalize(reflect(CamToFragmentDir, GroundNormal));
        vec3 RayPosCurrent; // in world coordinated
        vec4 RayPosCurrentOnScreen; // in screen coordinates
        mat4 PVM = proj * view * model;
        float RedFactor = 0.0; // black at the ray origin, pure red at full length
        for (float RayLength = 0.0; RayLength <= 500.0; RayLength ++)
        {
            RayPosCurrent = RayPosOriginal + (ReflectionDir * RayLength);
            RayPosCurrentOnScreen = PVM * vec4(RayPosCurrent, 1.0);
     
            RayPosCurrentOnScreen.x = RayPosCurrentOnScreen.x * 0.5 / RayPosCurrentOnScreen.w + 0.5;
            RayPosCurrentOnScreen.y = RayPosCurrentOnScreen.y * 0.5 / RayPosCurrentOnScreen.w + 0.5;
     
            if (abs(RayPosCurrentOnScreen.x - (gl_FragCoord.x / 800.0)) < 0.005 &&
                abs(RayPosCurrentOnScreen.y - (gl_FragCoord.y / 600.0)) < 0.005)
                RedFactor = RayLength;
        }
        if (RedFactor > 0.0)
            out_col = vec4(RedFactor / 512.0, 0.0, 0.0, 1.0); // current fragment is in the ray => draw red
        else
            out_col = texture(screenbuffer_tex, vec2(gl_FragCoord.x / 800.0, gl_FragCoord.y / 600.0)); // don't draw the ray here
     
        if (pos_wc.x > 90.0 && pos_wc.x < 110 &&
            pos_wc.z > 90.0 && pos_wc.z < 110)
            out_col = vec4(0.0, 1.0, 0.0, 1.0); // draw the green square, the origin of the ray
     
        if (abs(pos_wc.x - CamPos.x) < 50 &&
            abs(pos_wc.z - CamPos.z) < 50)
            out_col = vec4(1.0, 1.0, 0.0, 1.0); // mark the camera pos in yellow
    }

    My problem is that the ray is never reflected correctly. In my despair I implemented a hack, the uniform 'comb'[ination], an integer value that can be increased per key press. But for none of the 'comb' values between 0 and 15 the ray is drawn correctly. It either points into the wrong direction, or begins at an odd position, depending on the 'comb' value.

    My question: can anyone see an obvious error in the shader code?

    Thanks!

    PS: I know this code is a nasty hack but I'm a beginner and clean code will come later on in this project, when it works at all

  2. #2
    Junior Member Newbie
    Join Date
    Sep 2015
    Posts
    10
    Just a question Why are you calculating rays inside your shader as opposed to in your code? I can show you my mouse picker class and see if theres anything you can use?

  3. #3
    Junior Member Newbie
    Join Date
    Sep 2015
    Posts
    22
    The red ray I want to draw is just a test if my reflection calculation is correct. I have to implement screen space reflections, once a variation that traces rays in world space and then a second version that works according to the 'new hype', i.e. tracing rays purely in screen space.

    Thanks for your offer about the picker class, but I just need to know why my code does not draw a correctly reflected ray. Something in my calculations seems to be wrong, but I don't know what.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •