<p>Depth buffer values are clamped to that range because usually they are using fixed-point representation, so if clipping is disabled (by <code>glEnable(GL_DEPTH_CLAMP)</code>) then they can't hold anything beyond that range.</p>

<p>However, there isn't really a good reason for this clamping when floating point depth buffers are used. In fact <code>GL_NV_depth_buffer_float</code> extensions allows you to disable this clamping on Nvidia hardware for floating point buffers. Unfortunately other vendors don't have any documented way of doing that.</p>

<p>Also it's worth noting that unclamped floating point depth values have a minor complication: their depth offset is trickier to define. OpenGL spec resolves this by making the depth offset depend on the range of z-coordinates of the primitive. In fixed-point depth buffers, on the other hand, the offset is a function of the triangle slope only.</p>

CC BY-SA 4.0
2021-02-01T15:40:16.313Z
OpenGL ES 3.0 which shipped in 2012 has floating point depth buffers as a required feature whose values are not clamped 0 to 1. Checking OpenGL from 2012 which is version 4.2 it has the same requirements.
gman
CC BY-SA 4.0
2021-02-01T16:02:29.217Z
@gman: The issue is that even if the depth buffer can hold values outside the [0,1] range, the spec still requires clipping against the near plane (13.5 Primitive Clipping), effectively limiting the depth values to the [0,1] range. With reverse-Z floating point you can, at least, set the far plane at infinity, thus getting rid of the far plane clipping. I should rewrite this answer though to clarify my point.
Yakov Galka
CC BY-SA 4.0
2021-02-01T17:12:32.090Z
Could you write your own depth value?
gman
CC BY-SA 4.0
2021-02-01T18:17:01.590Z
@gman: you can, and to my understanding it should be written as-is to the depth buffer. But near/far plane clipping happens prior to rasterization and, by extension, fragment shading, so you won't have a chance to change the depth.
Yakov Galka
CC BY-SA 4.0
2019-05-06T04:53:38.723Z
2019-05-06T04:53:38.723Z
Yakov Galka
<p>(Just converting comment into an answer)
It seems you might be asking one of two possible questions.</p>

<p>If you meant <em>"Why doesn't the Depth buffer contain camera space Z"</em>
<br>then it's perhaps worth reading <a href="https://computergraphics.stackexchange.com/questions/8017/why-do-gpus-divide-clip-space-z-by-w-for-position]">Why do GPUs divide clip space Z by W, for position?</a> </p>

<p>If, OTOH, you just meant <em>"why is it restricted to [0,1)?"</em>, then that's <em>probably</em> because old systems represented the Z-buffer depth with fixed point numbers, hence a natural [0,1) range.<br><br>
 Of course, later hardware arrived that could use floating-point depths; IIRC Dreamcast's depth representation was an arbitrary positive float representing $\frac{1}{w}$.</p>

CC BY-SA 4.0
2018-09-18T17:52:39.947Z
Thanks! I just mean "why is it restricted to [0,1)?". I came up with this question when I was implementing shadow mapping. When using shadow maps, if the depth values stored in the shadow map are all between [0,1), we have to clamp the depth value of the pixel to [0,1) first and then do the comparison. If the shadow map stores the actual depth values as floats, we can just compare them directly.
yuchen
CC BY-SA 4.0
2018-09-18T08:36:03.673Z
2018-09-18T09:41:27.240Z
2018-09-18T09:41:27.240Z
Simon F
<p>This is a simple question.</p>

<p>I know that in OpenGL or other graphics API, the values stored in the depth buffer are automatically clamped to (0,1).</p>

<p>I just want to know why people do this instead of just keeping the actual depth values as float. Is that just because of the non-linear depth equation which makes the closer depth values more precise and the further depth values less precies?</p>

<p>Thank you!</p>

<opengl><shader><depth-map>
Why are depth buffer values clamped to (0, 1)?
yuchen
# Why are depth buffer values clamped to (0, 1)?

(Asked by: username_0 on 2018-09-17)

This is a simple question.

I know that in OpenGL or other graphics API, the values stored in the depth buffer are automatically clamped to (0,1).

I just want to know why people do this instead of just keeping the actual depth values as float. Is that just because of the non-linear depth equation which makes the closer depth values more precise and the further depth values less precies?

Thank you!

**Tags:** opengl, shader, depth-map


---

## 2 answers

### Answer by username_3 on 2018-09-18. Score: 4 | Accepted answer

(Just converting comment into an answer)
It seems you might be asking one of two possible questions.

If you meant *"Why doesn't the Depth buffer contain camera space Z"*
  
then it's perhaps worth reading [Why do GPUs divide clip space Z by W, for position?](https://computergraphics.stackexchange.com/questions/8017/why-do-gpus-divide-clip-space-z-by-w-for-position])

If, OTOH, you just meant *"why is it restricted to [0,1)?"*, then that's *probably* because old systems represented the Z-buffer depth with fixed point numbers, hence a natural [0,1) range.  
  
Of course, later hardware arrived that could use floating-point depths; IIRC Dreamcast's depth representation was an arbitrary positive float representing $\frac{1}{w}$.

> **Comments:**
> **username_0**: Thanks! I just mean "why is it restricted to [0,1)?". I came up with this question when I was implementing shadow mapping. When using shadow maps, if the depth values stored in the shadow map are all between [0,1), we have to clamp the depth value of the pixel to [0,1) first and then do the comparison. If the shadow map stores the actual depth values as floats, we can just compare them directly.  

---

### Answer by username_1 on 2019-05-06. Score: 2

Depth buffer values are clamped to that range because usually they are using fixed-point representation, so if clipping is disabled (by `glEnable(GL_DEPTH_CLAMP)`) then they can't hold anything beyond that range.

However, there isn't really a good reason for this clamping when floating point depth buffers are used. In fact `GL_NV_depth_buffer_float` extensions allows you to disable this clamping on Nvidia hardware for floating point buffers. Unfortunately other vendors don't have any documented way of doing that.

Also it's worth noting that unclamped floating point depth values have a minor complication: their depth offset is trickier to define. OpenGL spec resolves this by making the depth offset depend on the range of z-coordinates of the primitive. In fixed-point depth buffers, on the other hand, the offset is a function of the triangle slope only.

> **Comments:**
> **username_2**: OpenGL ES 3.0 which shipped in 2012 has floating point depth buffers as a required feature whose values are not clamped 0 to 1. Checking OpenGL from 2012 which is version 4.2 it has the same requirements.  
> **username_1**: @username_2: The issue is that even if the depth buffer can hold values outside the [0,1] range, the spec still requires clipping against the near plane (13.5 Primitive Clipping), effectively limiting the depth values to the [0,1] range. With reverse-Z floating point you can, at least, set the far plane at infinity, thus getting rid of the far plane clipping. I should rewrite this answer though to clarify my point.  
> **username_2**: Could you write your own depth value?  
> **username_1**: @username_2: you can, and to my understanding it should be written as-is to the depth buffer. But near/far plane clipping happens prior to rasterization and, by extension, fragment shading, so you won't have a chance to change the depth.  

---

