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 4 of 4

Thread: Deferred PointLight in view space

Hybrid View

  1. #1
    Junior Member Newbie
    Join Date
    Sep 2010
    Posts
    5

    Deferred PointLight in view space

    Hi,
    I got some problems getting my pointlight to work for my deferred shader.
    I'm computing the viewspace position of the pixels from my depth-buffer:

    Code :
    float DepthToZPosition(in float depth) {
        return -cameraRange.x / (cameraRange.y - depth * (cameraRange.y - cameraRange.x)) * cameraRange.y;
    }
    Code :
    linearDepth = DepthToZPosition( depth );
     
    screencoord = vec3(((gl_FragCoord.x/bufferSize.x)-0.5) * 2.0,((-gl_FragCoord.y/bufferSize.y)+0.5) * 2.0  ,linearDepth);
    screencoord.x *= -screencoord.z * adjustXY.x;
    screencoord.y *= screencoord.z * adjustXY.y;
     
    lightdir = screencoord.xyz - lightPosition.xyz;

    where cameraRange is the Near+Far plane of my camera.
    I'm drawing a fullscreen quad, with texcoord [ 0 , 1 ]

    When rendering just the length of lightdir/some factor, i get some strange results (i think the depth is not computed correctly, as when i pan the camera towards the ground it is lit (where it shouldn't), but not where it should..
    And also, when rotating the camera on the y-axis the light moves to the left and to the right, but doesn't stay where it should

    In my C++ code:

    Code :
    float top = c->getNearRange() * tan(c->getFOV()*PIOVER180);float right = top * c->getAspectRatio();
    glm::vec4 v = (c->getViewMatrix() * getGlobalMatrix()) * glm::vec4(0,0,0,1);
     
     
    _shader->setVec3(_lightPositionLocation, glm::vec3(v));
    _shader->setVec2(_adjustLocation, glm::vec2(right, top));
    where globalMatrix is the modelMatrix for the light (usually only translations)

  2. #2
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,193
    Quote Originally Posted by spong3bob View Post
    I'm computing the viewspace position of the pixels from my depth-buffer... i get some strange results (i think the depth is not computed correctly
    This is the classic "position from depth" problem, and there's a bunch of stuff our there on the net (just websearch for it). Matt Pettineo for instance has some good blog posts on this. If you don't want to just re-derive it, compare your solution to what they're doing.

    Here's one GLSL solution of many: see the PositionFromDepth_DarkPhoton() function listed at the bottom of this forum post: Re: View Space Light Position Moving.... It assumes standard perspective projection and standard 0..1 depth range. widthInv = 1/res.x and heightInv = 1/res.y.
    Last edited by Dark Photon; 04-18-2013 at 09:28 AM.

  3. #3
    Junior Member Newbie
    Join Date
    Sep 2010
    Posts
    5
    I now implemented your PositionFromDepth- function, but still got the same problem.
    Click image for larger version. 

Name:	error.jpg 
Views:	69 
Size:	86.0 KB 
ID:	1015

    The light is positioned directly under the duck.

    Here's my code:
    Code :
    vec3 PositionFromDepth(in float depth)
    {
      vec2 ndc;             // Reconstructed NDC-space position
      vec3 eye;             // Reconstructed EYE-space position
     
      eye.z = cameraRange.x * cameraRange.y / ((depth * (cameraRange.y - cameraRange.x)) - cameraRange.y);
     
      ndc.x = ((gl_FragCoord.x * (1.0/bufferSize.x)) - 0.5) * 2.0;
      ndc.y = ((gl_FragCoord.y * (1.0/bufferSize.y)) - 0.5) * 2.0;
     
      eye.x =  (-ndc.x * eye.z) * adjustXY.x/cameraRange.x;
      eye.y =  (-ndc.y * eye.z) * adjustXY.y/cameraRange.x;
     
      return eye;
    }
    Code :
    screencoord = PositionFromDepth(depth);
    lightdir = screencoord.xyz - lightPosition.xyz;
    lightdirlen = length(lightdir );
    gl_FragColor=vec4(clamp(1.0-lightdirlen/5.0,0.0,1.0));

    And the passed parameters are still the same as from the first post.
    Code :
     
    float top = c->getNearRange() * tan(c->getFOV()*PIOVER180);float right = top * c->getAspectRatio();glm::vec4 v = (c->getViewMatrix() * getGlobalMatrix()) * glm::vec4(0,0,0,1);  _shader->setVec3(_lightPositionLocation, glm::vec3(v));_shader->setVec2(_adjustLocation, glm::vec2(right, top));

    I'm using widthInv = 1/buffersize.x, as I'm rendering a fullscreen-quad in my fullscreen-buffer.

    What am I doin wrong?
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	error.jpg 
Views:	50 
Size:	88.9 KB 
ID:	1014  

  4. #4
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,948
    Maybe you should try this example from the wiki. This formula doesn't make assumptions about the depth range, and it only makes the minimal assumptions about the nature of your perspective projection matrix.

    Code :
    uniform mat4 persMatrix;
    uniform mat4 invPersMatrix;
    uniform vec4 viewport;
    uniform vec2 depthrange;
     
    vec4 CalcEyeFromWindow(vec3 windowSpace)
    {
            vec3 ndcPos;
            ndcPos.xy = ((2.0 * windowSpace.xy) - (2.0 * viewport.xy)) / (viewport.zw) - 1;
            ndcPos.z = (2.0 * windowSpace.z - depthrange.x - depthrange.y) /
        (depthrange.y - depthrange.x);
     
            vec4 clipPos;
            clipPos.w = persMatrix[3][3] / (ndcPos.z - (persMatrix[4][3] / persMatrix[3][4]));
            clipPos.xyz = ndcPos * clipPos.w;
     
            vec4 eyePos = invPersMatrix * clipPos;
    }

    I haven't used it, so I can't promise that it'll work. But the math seems sound.

Posting Permissions

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