Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 12

Thread: Depth-texture values always clamped to [0, 1]

  1. #1
    Junior Member Newbie
    Join Date
    Nov 2009
    Posts
    6

    Depth-texture values always clamped to [0, 1]

    Hi there!

    I know that shadow mapping is a common problem on forums but this time I couldn't find the answer to my problem.
    I set up an FBO and a depth-component texture correctly and render my scene from my light's point of view to this FBO. Later I wanted to use this texture in a fragment shader but the values in this are always between 0 and 1. Somewhere I read that GL_DEPTH_COMPONENT-type texture values are clamped but isn't there a function to disable this? Or should I use a different component-type (like GL_R32)?

  2. #2
    Senior Member OpenGL Lord
    Join Date
    May 2009
    Posts
    6,067

    Re: Depth-texture values always clamped to [0, 1]

    Later I wanted to use this texture in a fragment shader but the values in this are always between 0 and 1.
    That's what depth values are. It's up to you to properly interpret them in the shader.

  3. #3
    Junior Member Newbie
    Join Date
    Nov 2009
    Posts
    6

    Re: Depth-texture values always clamped to [0, 1]

    Of course they have to be between them but I thought that zero represents the near z plane and one represents the far z plane. But in this case the clamping was done on world-space distances so the depth-texture "can't see" further than one world unit. If I render a scene where the objects are two units far away from the light then the texture will contain only 1.0 values.

  4. #4
    Senior Member OpenGL Pro Ilian Dinev's Avatar
    Join Date
    Jan 2008
    Location
    Watford, UK
    Posts
    1,294

    Re: Depth-texture values always clamped to [0, 1]


  5. #5
    Member Regular Contributor strattonbrazil's Avatar
    Join Date
    Jun 2007
    Location
    Los Angeles, CA
    Posts
    305

    Re: Depth-texture values always clamped to [0, 1]

    Quote Originally Posted by Lost Lont
    Of course they have to be between them but I thought that zero represents the near z plane and one represents the far z plane. But in this case the clamping was done on world-space distances so the depth-texture "can't see" further than one world unit. If I render a scene where the objects are two units far away from the light then the texture will contain only 1.0 values.
    Those values are in normal coordinates after your projection, so if your zNear is 10 and zFar is 1000, something like 10 would be zero in the depth texture and something at 1000 would be one in your depth texture.

    It's perfectly legitimate to go between those spaces. In shadow mapping, you're taking a point in world or camera space and moving it into your "depth map" space, which would also have a value between zero and one for the comparison.

  6. #6
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    4,569

    Re: Depth-texture values always clamped to [0, 1]

    Quote Originally Posted by Lost Lont
    ...but I thought that zero represents the near z plane and one represents the far z plane.
    In a depth texture, typically yes.

    But in this case the clamping was done on world-space distances so the depth-texture "can't see" further than one world unit.
    No! Definitely not! You don't store world-space depth values in a depth map. You store window-space depth values (typically), which are 0..1 and represent the entire depth range for the entire light-space frustum (i.e. the region between the light-space near and far clip planes)!

    For a little more context, NDC-space depth values are within -1..1 for depth values within the light frustum (of course, always are). glDepthRange is typically 0,1, which means the resulting window-space depth values are 0..1 when you're rendering your shadow map. And "that" is what gets stuffed in your shadow map (i.e. depth map).

    See this image from the OpenGL Programming Guide, Chapter 3:



    For some insight in how to get around the coordinate spaces when doing shadow map lookups, see this image from Paul's Shadow Mapping Project:

  7. #7
    Junior Member Newbie
    Join Date
    Nov 2009
    Posts
    6

    Re: Depth-texture values always clamped to [0, 1]

    Sorry for the late reply and thanks for all the answers.

    Now I remember that the OpenGL uses reciprocal depth storage and comparison but what I couldn't puzzle out is *how* does it calculate the z-values before storing them in a floating-point texture. If I knew the formula then I could decipher the inverse operation to calculate the linear value but I couldn't find this equation.
    (I tried the "return (2.0 * n) / (f + n - z * (f - n))" formula from the geeks3d.com page but I would like to know how does the "non-linearisation" (and thus the linearisation) work and not just implement it anyway.)

    Is there a place in the OpenGL documentation where the z calculation is written down?

  8. #8
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    4,569

    Re: Depth-texture values always clamped to [0, 1]

    Quote Originally Posted by Lost Lont
    (I tried the "return (2.0 * n) / (f + n - z * (f - n))" formula from the geeks3d.com page...
    Re the geeks3d formula, looking at it a bit, it doesn't feel right. Plug in z_win=1 and you do get 1, but plug in z_win=0 and you just get a mess (not 0, which you'd expect).

    ...but I would like to know how does the "non-linearisation" (and thus the linearisation) work and not just implement it anyway.)

    Is there a place in the OpenGL documentation where the z calculation is written down?
    Sure. You know what the PROJECTION transform is, right? Takes eye-space to clip-space. Do the perspective divide and you have NDC-space. Then just scale and shift that and you have window-space.

    The main thing you need is the PROJECTION transform. Look at Appendix F in the Red Book:

    * http://glprogramming.com/red/appendixf.html

    At the bottom of the page are the perspective and orthographic projection matricies. All you need are the bottom two rows to compute z_clip and w_clip from z_eye (w_eye == 1). Then just divide z_clip/w_clip, and you have z_ndc. Then shift and scale that -1..1 value into 0..1 (*.5+.5, assuming glDepthRange 0,1) to get window-space Z. You can write all this out. It's not complex. That'll give you an expression that defines z_win in terms of z_eye. This defines the normal Z transform, and what you call "non-linearizing" it.

    Then given z_win, you want to "re-linearize" it. So you want something like z_eye, but in 0..1 range. In other words you want to take the previous equation, solve for z_eye in terms of z_win, then plug that into (-z_eye-n)/(f-n) to get a linear-in-eye-space 0..1 Z value in terms of the window-space Z value.

  9. #9
    Junior Member Newbie
    Join Date
    Nov 2009
    Posts
    6

    Re: Depth-texture values always clamped to [0, 1]

    That Red Book appendix was what I was looking for. Now it works, thanks for everyone for the help.

    Code :
    // Eye space -> window space:
    float z_ndc = (f + n + 2.0/z_eye*f*n) / (f - n);
    float z_win = z_ndc*0.5 + 0.5;
     
    // Window space -> eye space:
    float z_ndc = (z_win - 0.5) * 2.0;
    float z_eye = 1.0 / ( (z_ndc*(f - n) - f - n)*f*n*0.5 );

    I wanted to ask which direction is better (converting the depth texture values to world space or converting the in-world distances to the texture's window space) but maybe the first method needs less extra calculations in the case of a cube map texture.

  10. #10
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    4,569

    Re: Depth-texture values always clamped to [0, 1]

    Quote Originally Posted by Lost Lont
    I wanted to ask which direction is better (converting the depth texture values to world space or converting the in-world distances to the texture's window space)
    I don't understand the question. They produce two different things, not the same thing via two different methods.

    Also beware anytime you're thinking of working with "world space" in a shader. In general, world space may be bigger than can be represented with sufficient accuracy in a shader with single-precision floats (if not now, then maybe in your app in the future), and you may screw your current (or future) self by doing stuff with world space in the shader. Use object, eye, clip, NDC spaces, but avoid world like crazy.

    What are you trying to do again? There's probably another way to do it.

Posting Permissions

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