Name
NV_depth_buffer_float
Name Strings
GL_NV_depth_buffer_float
Contributors
Pat Brown
Mike Strauss
Contact
Mike Strauss, NVIDIA Corporation (mstrauss 'at' nvidia.com)
Status
Shipping for GeForce 8 Series (November 2006)
Version
Last Modified Date: 07/27/2010
NVIDIA Revision: 11
Number
334
Dependencies
OpenGL 2.0 is required.
ARB_color_buffer_float is required.
EXT_packed_depth_stencil is required.
EXT_framebuffer_object is required.
This extension modifies EXT_depth_bounds_test.
This extension modifies NV_copy_depth_to_color.
This extension interacts with ARB_depth_buffer_float.
This extension is written against the OpenGL 2.0 specification.
Overview
This extension provides new texture internal formats whose depth
components are stored as 32-bit floating-point values, rather than the
normalized unsigned integers used in existing depth formats.
Floating-point depth textures support all the functionality supported for
fixed-point depth textures, including shadow mapping and rendering support
via EXT_framebuffer_object. Floating-point depth textures can store
values outside the range [0,1].
By default, OpenGL entry points taking depth values implicitly clamp the
values to the range [0,1]. This extension provides new DepthClear,
DepthRange, and DepthBoundsEXT entry points that allow applications to
specify depth values that are not clamped.
Additionally, this extension provides new packed depth/stencil pixel
formats (see EXT_packed_depth_stencil) that have 64-bit pixels consisting
of a 32-bit floating-point depth value, 8 bits of stencil, and 24 unused
bites. A packed depth/stencil texture internal format is also provided.
This extension does not provide support for WGL or GLX pixel formats with
floating-point depth buffers. The existing (but not commonly used)
WGL_EXT_depth_float extension could be used for this purpose.
New Procedures and Functions
void DepthRangedNV(double n, double f);
void ClearDepthdNV(double d);
void DepthBoundsdNV(double zmin, double zmax);
New Tokens
Accepted by the parameter of TexImage1D, TexImage2D,
TexImage3D, CopyTexImage1D, CopyTexImage2D, and RenderbufferStorageEXT,
and returned in the parameter of GetTexLevelParameter and
GetRenderbufferParameterivEXT:
DEPTH_COMPONENT32F_NV 0x8DAB
DEPTH32F_STENCIL8_NV 0x8DAC
Accepted by the parameter of DrawPixels, ReadPixels, TexImage1D,
TexImage2D, TexImage3D, TexSubImage1D, TexSubImage2D, TexSubImage3D, and
GetTexImage:
FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD
Accepted by the parameters of GetBooleanv, GetIntegerv,
GetFloatv, and GetDoublev:
DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF
Additions to Chapter 2 of the OpenGL 2.0 Specification (OpenGL Operation)
Modify Section 2.11.1 (Controling the Viewport), p. 41
(modify second paragraph) The factor and offset applied to z_d
encoded by n and f are set using
void DepthRange(clampd n, clampd f);
void DepthRangedNV(double n, double f);
z_w is represented as either fixed-point or floating-point
depending on whether the framebuffer's depth buffer uses
fixed-point or floating-point representation. If the depth buffer
uses fixed-point representation, we assume that the representation
used represents each value k/(2^m - 1), where k is in
{0,1,...,2^m-1}, as k (e.g. 1.0 is represented in binary as a
string of all ones). The parameters n and f are clamped to [0, 1]
when using DepthRange, but not when using DepthRangedNV. When n
and f are applied to z_d, they are clamped to the range appropriate
given the depth buffer's representation.
Additions to Chapter 3 of the OpenGL 2.0 Specification (Rasterization)
Modify Section 3.5.5 (Depth Offset), p. 112
(modify third paragraph) The minimum resolvable difference r is
an implementation dependent parameter that depends on the depth
buffer representation. It is the smallest difference in window
coordinate z values that is guaranteed to remain distinct
throughout polygon rasterization and in the depth buffer. All
pairs of fragments generated by the rasterization of two polygons
with otherwise identical vertices, but z_w values that differ by r,
will have distinct depth values.
For fixed-point depth buffer representations, r is constant
throughout the range of the entire depth buffer. For
floating-point depth buffers, there is no single minimum resolvable
difference. In this case, the minimum resolvable difference for a
given polygon is dependent on the maximum exponent, e, in the range
of z values spanned by the primitive. If n is the number of bits
in the floating-point mantissa, the minimum resolvable difference,
r, for the given primitive is defined as
r = 2^(e - n). (3.11)
(modify fourth paragraph) The offset value o for a polygon is
o = m * factor + r * units. (3.12)
m is computed as described above. If the depth buffer uses a
fixed-point representation, m is a function of depth values in the
range [0, 1], and o is applied to depth values in the same range.
(modify last paragraph) For fixed-point depth buffers, fragment
depth values are always limited to the range [0, 1], either by
clamping after offset addition is performed (preferred), or by
clamping the vertex values used in the rasterization of the
polygons. Fragment depth values are not clamped when the depth
buffer uses a floating-point representation.
Add a row to table 3.5, p. 128
type Parameter GL Type Special
------------------------------------------------
... ... ...
FLOAT_32_UNSIGNED_INT_24_8_REV_NV N/A Yes
... ... ...
Modify Section 3.6.4 (Rasterization of Pixel Rectangles), p. 128
(modify second paragraph as updated by EXT_packed_depth_stencil)
... If the GL is in color index mode and is not one of
COLOR_INDEX, STENCIL_INDEX, DEPTH_COMPONENT, or DEPTH_STENCIL_EXT,
then the error INVALID_OPERATION occurs. If is BITMAP and
is not COLOR_INDEX or STENCIL_INDEX then the error
INVALID_ENUM occurs. If is DEPTH_STENCIL_EXT and
is not UNSIGNED_INT_24_8_EXT or FLOAT_32_UNSIGNED_INT_24_8_REV_NV,
then the error INVALID_ENUM occurs. Some additional constraints
on the combinations of and values that are accepted
are discussed below.
(modify fifth paragraph of "Unpacking," p 130. as updated by
EXT_packed_depth_stencil) Calling DrawPixels with a of
UNSIGNED_BYTE_3_3_2, ..., UNSIGNED_INT_2_10_10_10_REV, or
UNSIGNED_INT_24_8_EXT is a special case in which all the components
of each group are packed into a single unsigned byte, unsigned
short, or unsigned int, depending on the type. If is
FLOAT_32_UNSIGNED_INT_24_8_REV_NV, the components of each group
are two 32-bit words. The first word contains the float component.
The second word contains packed 24-bit and 8-bit components.
Add two rows to table 3.8, p. 132
type Parameter GL Type Components Pixel Formats
------------------------------------------------------------------
... ... ... ...
FLOAT_32_UNSIGNED_INT_24_8_REV_NV N/A 2 DEPTH_STENCIL_EXT
... ... ... ...
Add a row to table 3.11, p. 134
FLOAT_32_UNSIGNED_INT_24_8_REV_NV:
31 30 29 28 ... 4 3 2 1 0 31 30 29 ... 9 8 7 6 5 ... 2 1 0
+-------------------------+ +--------------------------------+
| Float Component | | 2nd Component | 1st Component |
+-------------------------+ +--------------------------------+
(modify last paragraph of "Final Conversion," p. 136) For a depth
component, an element is processed according to the depth buffer's
representation. For fixed-point depth buffers, the element is first
clamped to [0, 1] and then converted to fixed-point as if it were a
window z value (see section 2.11.1, Controling the Viewport).
Clamping and conversion are not necessary when the depth buffer uses
a floating-point representation.
Modify Section 3.8.1 (Texture Image Specification), p. 150
(modify the second paragraph, p. 151, as modified by
ARB_color_buffer_float) The selected groups are processed exactly
as for DrawPixels, stopping just before final conversion. Each R,
G, B, A, or depth value so generated is clamped based on the
component type in the . Fixed-point components
are clamped to [0, 1]. Floating-point components are clamped to
the limits of the range representable by their format. 32-bit
floating-point components are in the standard IEEE float format.
16-bit floating-point components have 1 sign bit, 5 exponent bits,
and 10 mantissa bits. Stencil index values are masked by 2^n-1
where n is the number of stencil bits in the internal format
resolution (see below). If the base internal format is
DEPTH_STENCIL_EXT and is not DEPTH_STENCIL_EXT, then the
values of the stencil index texture components are undefined.
Add two rows to table 3.16, p. 154
Sized Base R G B A L I D S
Internal Format InternalFormat bits bits bits bits bits bits bits bits
------------------------------------------------------------------------------
... ... ... ... ... ... ... ... ... ...
DEPTH_COMPONENT32F_NV DEPTH_COMPONENT f32
DEPTH32F_STENCIL8_NV DEPTH_STENCIL_EXT f32 8
... ... ... ... ... ... ... ... ... ...
Modify Section 3.8.14 (Texture Comparison Modes), p. 185
(modify second paragraph of "Depth Texture Comparison Mode," p.
188) Let D_t be the depth texture value, and R be the interpolated
texture coordinate. If the texture's internal format indicates a
fixed-point depth texture, then D_t and R are clamped to [0, 1],
otherwise no clamping is performed. The effective texture value
L_t, I_t, or A_t is computed as follows:
Modify Section 3.11.2 (Shader Execution), p. 194
(modify first paragraph of "Shader Outputs," p, 196, as modified by
ARB_color_buffer_float) The OpenGL Shading Language specification
describes the values that may be output by a fragment shader.
These are gl_FragColor, gl_FragData[n], and gl_FragDepth. If
fragment clamping is enabled, the final fragment color values or
the final fragment data values written by a fragment shader are
clamped to the range [0, 1] and then may be converted to
fixed-point as described in section 2.14.9. If fragment clamping
is disabled, the final fragment color values or the final fragment
data values are not modified. For fixed-point depth buffers the
final fragment depth written by a fragment shader is first clamped
to [0, 1] and then converted to fixed-point as if it were a window
z value (see section 2.11.1). Clamping and conversion are not
applied for floating-point depth buffers. Note that the depth
range computation is not applied here.
Additions to Chapter 4 of the OpenGL 2.0 Specification (Per-Fragment
Operations and the Frame Buffer)
(modify third paragraph in the introduction, p. 198, as modified by
ARB_color_buffer_float) Color buffers consist of either unsigned
integer color indices, R, G, B and optionally A unsigned integer
values, or R, G, B, and optionally A floating-point values. Depth
buffers consist of either unsigned integer values of the format
described in section 2.11.1, or floating-point values. The number
of bitplanes...
Modify Section 4.2.3 (Clearing the Buffers), p. 215
(modify fourth paragraph)
The functions
void ClearDepth(clampd d);
void ClearDepthdNV(double d);
are used to set the depth value used when clearing the depth buffer.
ClearDepth takes a floating-point value that is clamped to the range
[0, 1]. ClearDepthdNV takes a floating-point value that is not
clamped. When clearing a fixed-point depth buffer, the depth clear
value is clamped to the range [0, 1], and converted to fixed-point
according to the rules for a window z value given in section 2.11.1.
No clamping or conversion are applied when clearing a floating-point
depth buffer.
Modify Section 4.3.1 (Writing to the Stencil Buffer), p. 218
(modify paragraph added by EXT_packed_depth_stencil, p. 219)
If the is DEPTH_STENCIL_EXT, then values are taken from
both the depth buffer and the stencil buffer. If there is no depth
buffer or if there is no stencil buffer, then the error
INVALID_OPERATION occurs. If the parameter is not
UNSIGNED_INT_24_8_EXT, or FLOAT_32_UNSIGNED_INT_24_8_REV_NV then the
error INVALID_ENUM occurs.
Modify Section 4.3.2 (Reading Pixels), p. 219
(modify "Conversion of Depth values," p. 222, as modified by
EXT_packed_depth_stencil) This step only applies if is
DEPTH_COMPONENT or DEPTH_STENCIL_EXT and the depth buffer uses a
fixed-point representation. An element taken from the depth buffer
is taken to be a fixed-point value in [0, 1] with m bits, where
m is the number of bits in the depth buffer (see section 2.11.1).
No conversion is necessary if is DEPTH_COMPONENT or
DEPTH_STENCIL_EXT and the depth buffer uses a floating-point
representation.
Add a row to table 4.6, p. 223
type Parameter Index Mask
----------------------------------------------
... ...
FLOAT_32_UNSIGNED_INT_24_8_REV_NV 2^8-1
Add a row to table 4.7, p. 224
type Parameter GL Type Component Conversion
------------------------------------------------------------------
... ... ...
FLOAT_32_UNSIGNED_INT_24_8_REV_NV float c = f (depth only)
Additions to Chapter 5 of the OpenGL 2.0 Specification (Special Functions)
None.
Additions to Chapter 6 of the OpenGL 2.0 Specification (State and
State Requests)
Modify DEPTH_RANGE entry in table 6.9 (Transformation State) p. 270
Init
Get Value Type Get Command Value Description Sec. Attribute
----------- ---- ----------- ----- ---------------------- ------ ---------
DEPTH_RANGE 2xR GetFloatv 0,1 Depth range near & far 2.11.1 viewport
Modify DEPTH_BOUNDS_EXT entry in table 6.19 (Pixel Operation) p. 280
Init
Get Value Type Get Command Value Description Sec Attribute
--------------------- ----------- ----- ------------------------ ----- ------------
DEPTH_BOUNDS_EXT 2xR GetFloatv 0,1 Depth bounds zmin & zmax 4.1.X depth-buffer
Modify DEPTH_CLEAR_VALUE entry in table 6.21 (Framebuffer Control) p. 280
Init
Get Value Type Get Command Value Description Sec Attribute
----------------- ---- ----------- ---- ------------------------ ----- ------------
DEPTH_CLEAR_VALUE R GetFloatv 1 Depth buffer clear value 4.2.3 depth-buffer
Add DEPTH_BUFFER_FLOAT_MODE entry to table 6.32 (Implementation Dependent Values) p. 293
Init
Get Value Type Get Command Value Description Sec Attribute
----------------------- ---- ----------- ---- --------------------------- ---- ------------
DEPTH_BUFFER_FLOAT_MODE B GetBooleanv - True if depth buffer uses a 4 -
floating-point represnetation
Additions to Appendix A of the OpenGL 2.0 Specification (Invariance)
None.
Additions to the AGL/GLX/WGL Specifications
None.
GLX Protocol
The following rendering commands are sent to the server as part of
glXRender requests:
DepthRangedNV
2 20 rendering command length
2 4283 rendering command opcode
8 FLOAT64 n
8 FLOAT64 f
ClearDepthdNV
2 12 rendering command length
2 4284 rendering command opcode
8 FLOAT64 d
DepthBoundsdNV
2 20 rendering command length
2 4285 rendering command opcode
8 FLOAT64 zmin
8 FLOAT64 zmax
Dependencies on EXT_depth_bounds_test:
Modify the definition of DepthBoundsEXT in section 4.1.x Depth
Bounds Test.
Modify section 4.1.x (Depth Bounds Test)
(modify first paragraph) ...These values are set with
void DepthBoundsEXT(clampd zmin, clampd zmax);
void DepthBoundsdNV(double zmin, double zmax);
The paramerters to DepthBoundsEXT are clamped to the range [0, 1].
No clamping is applied to the parameters of DepthBoundsdNV. Each
of zmin and zmax are subject to clamping to the range of the depth
buffer at the time the depth bounds test is applied. For
fixed-point depth buffers, the applied zmin and zmax are clamped to
[0, 1]. For floating-point depth buffers, the applied zmin and
zmax are unmodified. If zmin <= Zpixel <= zmax, then the depth
bounds test passes. Otherwise, the test fails and the fragment is
discarded. The test is enabled or disabled using Enable or Disable
using the constant DEPTH_BOUNDS_TEST_EXT. When disabled, it is as
if the depth bounds test always passes. If zmin is greater than
zmax, then the error INVALID_VALUE is generated. The state
required consists of two floating-point values and a bit indicating
whether the test is enabled or disabled. In the initial state,
zmin and zmax are set to 0.0 and 1.0 respectively; and the depth
bounds test is disabled.
Interactions with ARB_depth_buffer_float
The ARB and NV internal formats for floating-point depth buffers
behave identically. This extension optionally relaxes the clamping
behavior of ARB_depth_buffer_float when using the NV entry points.
If an ARB internal format is used to define a depth buffer, the
values passed to DepthRangedNV, ClearDepthdNV, and DepthBoundsdNV
are not clamped to [0,1].
Additionally, querying DEPTH_BUFFER_FLOAT_MODE_NV is allowed on a
floating-point depth buffer created with an ARB internal format.
Errors
Modify the following error in the EXT_packed_depth_stencil
specification by adding mention of
FLOAT_32_UNSIGNED_INT_24_8_REV_NV:
The error INVALID_ENUM is generated if DrawPixels or ReadPixels is
called where format is DEPTH_STENCIL_EXT and type is not
UNSIGNED_INT_24_8_EXT, or FLOAT_32_UNSIGNED_INT_24_8_REV_NV.
Modify the following error in the EXT_packed_depth_stencil
specification by adding mention of
FLOAT_32_UNSIGNED_INT_24_8_REV_NV:
The error INVALID_OPERATION is generated if DrawPixels or
ReadPixels is called where type is UNSIGNED_INT_24_8_EXT,
or FLOAT_32_UNSIGNED_INT_24_8_REV_NV and format is not
DEPTH_STENCIL_EXT.
Add the following error to the NV_copy_depth_to_color
specification:
The error INVALID_OPERATION is generated if CopyPixels is called
where type is DEPTH_STENCIL_TO_RGBA_NV or DEPTH_STENCL_TO_BGRA_NV
and the depth buffer uses a floating point representation.
New State
None.
Issues
1. Should this extension expose floating-point depth buffers through
WGL/GLX "pixel formats?"
RESOLVED: No. The WGL_EXT_depth_float extension already provides a
mechanism for requesting a floating-point depth buffer.
2. How does an application access the full range of a floating-point
depth buffer?
RESOLVED: New functions have been introduced that set existing GL
state without clamping to the range [0, 1]. These functions are
DepthRangedNV, ClearDepthdNV, and DepthBoundsdNV.
3. Should we add a new state query to determine if the depth buffer is
using a floating-point representation?
RESOLVED: Yes. An application can query DEPTH_FLOAT_MODE_NV to see
if the depth buffer is using a floating-point representation.
4. How does polygon offset work with floating-point depth buffers?
RESOLVED: The third paragraph of section 3.5.5 (Depth Offset)
describes the minimum resolvable difference r as "the smallest
difference in window coordinate z values that is guaranteed to remain
distinct throughout polygon rasterization and in the depth buffer."
The polygon offset value o is computed as a function of r. The
minimum resolvable difference r makes sense for fixed-point depth
values, and even floating-point depth values in the range [-1, 1].
For unclamped floating-point depth values, there is no constant
minimum resolvable difference -- the minimum difference necessary to
change the mantissa of a floating-point value by one bit depends on
the exponent of the value being offset. To remedy this problem, the
minimum resolvable difference is defined to be relative to the range
of depth values for the given primitive when the depth buffer is
floating-point.
5. How does NV_copy_depth_to_color work with floating-point depth values?
RESOLVED: It isn't clear that there is any usefulness to copying the
data for 32-bit floating-point depth values to a fixed-point color
buffer. It is even less clear how copying packed data from a
FLOAT_32_UNSIGNED_24_8_REV_NV depth/stencil buffer to a fixed-point color
buffer would be useful or even how it should be implemented. An error
should be generated if CopyPixels is called where is
DEPTH_STENCIL_TO_RGBA_NV or DEPTH_STENCIL_TO_BGRA and the depth buffer
uses a floating-point representation.
6. Other OpenGL hardware implementations may be capable of supporting
floating-point depth buffers. Why is this an NV extension?
RESOLVED: When rendering to floating-point depth buffers, we expect
that other implementations may only be capable of supporting Z values
in the range [0,1]. For such implementations, floating-point Z
buffers do not improve the range of Z values supported, but do offer
increased precision than conventional 24-bit fixed-point Z buffers,
particularly around zero.
This extension was initially proposed as an EXT, but we have changed
it to an NV extension in the expectation that an EXT may be offered at
some point in the not-too-distant future. We expect that the EXT
could be supported by a larger range of vendors. NVIDIA would
continue to support both extensions, where the NV extension could be
thought of as taking the capability of the EXT version and extending
it to support Z values outside the range [0,1].
Revision History
Rev. Date Author Changes
---- -------- -------- -----------------------------------------
11 07/27/10 srahman GLX protocol added.
10 01/30/09 rsrinivasiah Define interaction with ARB_depth_buffer_float
9 08/06/08 jleech Fix missing _REV in some token names.
8 02/09/07 pbrown Updated status section (now released).
7 10/11/06 pbrown Rename the extension from EXT to NV.
6 Internal spec revisions.