Depth Test: Difference between revisions

From OpenGL Wiki
Jump to navigation Jump to search
Briefly filled in the details. It's more API-oriented than these should be, but it's accurate and complete.
 
(4 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{pipeline float}}
{{pipeline float}}
The '''Depth Test''' is a per-sample operation performed [[Early Depth Test|conceptually]] after the [[Fragment Shader]]. The output depth may be tested against the [[Depth Buffer|depth of the sample being written to]]. If the test fails, the fragment is discarded. If the test passes, the depth buffer may be written to.
The '''Depth Test''' is a [[Per-Sample_Processing|per-sample processing operation]] performed after the [[Fragment Shader]] (and [[#Early test|sometimes before]]). The [[Fragment]]'s output depth value may be tested against the [[#Depth buffer|depth of the sample being written to]]. If the test fails, the fragment is discarded. If the test passes, the depth buffer will be updated with the fragment's output depth, unless a subsequent per-sample operation prevents it (such as [[Write Mask|turning off depth writes]]).


== Steps ==
== Depth buffer ==


If the depth buffer exists, the value it is cleared to can be assigned with {{apifunc|glClearDepth}} or retrieved with {{apifunc|glGet}}...({{enum|GL_DEPTH_CLEAR_VALUE}}), and then the buffer itself is cleared using {{apifunc|glClear}}({{enum|GL_DEPTH_BUFFER_BIT}}).
In order to use the depth test, the current [[Framebuffer]] must have a depth buffer. A depth buffer is an image that uses a depth image format. The [[Default Framebuffer]] may have a depth buffer, and [[Framebuffer Object|user-defined framebuffers]] can attach depth formatted images (either [[Depth Stencil Format|depth/stencil]] or [[Depth Image Format|depth-only]]) to the {{enum|GL_DEPTH_ATTACHMENT}} attachment point.


After clipping and division by w, depth coordinates range from -1 to 1, corresponding to the near and far clipping planes. Each viewport has an independent depth range specified as a linear mapping of the normalized depth coordinates in this range to window depth coordinates. Regardless of the actual depth buffer implementation, window coordinate depth values are treated as though they range from 0 through 1 (like color components). The depth values are mapped from window coordinates to normalized device coordinates using {{apifunc|glDepthRange}}(GLdouble {{param|nearVal}}, GLdouble {{param|farVal}}), which can be retrieved as a pair using {{apifunc|glGet}}...({{enum|GL_DEPTH_RANGE}}); the initial values are 0 and 1 respectively. When there are multiple viewports, {{apifunc|glDepthRangeIndexed}}(GLuint {{param|index}}, GLdouble {{param|nearVal}}, GLdouble {{param|farVal}}) and {{apifunc|glDepthRangeArray}}(GLuint {{param|first}}, GLsizei {{param|count}}, const GLdouble *{{param|v}}) are used.
If the current framebuffer has no depth buffer, then the depth test behaves as if it is always disabled.


The depth test does not occur unless if {{enum|GL_DEPTH_TEST}} is enabled; the initial value is <i>false</i>. The depth of the sample being written to (<i>s</i>) is compared to the value in the depth buffer (<i>d</i>) using the function specified by {{apifunc|glDepthFunc}}(GLenum {{param|func}}) (which is retrieved with {{apifunc|glGet}}...({{enum|GL_DEPTH_FUNC}}). This can be {{enum|GL_NEVER}} (<i>false</i>), {{enum|GL_LESS}} (<i>s</i> &lt; <i>d</i>), {{enum|GL_EQUAL}} (<i>s</i> = <i>d</i>), {{enum|GL_LEQUAL}} (<i>s</i> ≤ <i>d</i>), {{enum|GL_GREATER}} (<i>s</i> &gt; <i>d</i>), {{enum|GL_NOTEQUAL}} (<i>s</i> ≠ <i>d</i>), {{enum|GL_GEQUAL}} (<i>s</i> ≥ <i>d</i>), or {{enum|GL_ALWAYS}} (<i>true</i>). The initial value is {{enum|GL_LESS}}.
== Fragment depth value ==


If the test passes or is disabled, the depth value may then be written to the depth buffer. To control whether to write to the depth buffer, call {{apifunc|glDepthMask}}(GLboolean {{param|flag}}) or retrieve the current setting with {{apifunc|glGet}}...({{enum|GL_DEPTH_WRITEMASK​}}). The default is <i>true</i>.
Every [[Fragment]] has a depth value. This value is either computed by the [[Fragment Shader]] (if it writes to {{code|gl_FragDepth}}) or is the [[Window Space|window-space Z coordinate]] computed as the output of the [[Vertex Post-Processing]] steps.


== Associated Gets ==
== Depth test ==


{{apifunc|glGet}} with argument {{enum|GL_DEPTH_CLEAR_VALUE}}, {{enum|GL_DEPTH_FUNC}}, {{enum|GL_DEPTH_RANGE}}, {{enum|GL_DEPTH_WRITEMASK​}}
To enable depth testing, call {{apifunc|glEnable}} with {{enum|GL_DEPTH_TEST}}. When rendering to a framebuffer that has no depth buffer, depth testing always behaves as though the test is disabled.


{{apifunc|glIsEnabled}} with argument {{enum|GL_DEPTH_TEST}}
When depth testing is disabled, writes to the depth buffer are also disabled.


== See Also ==
When depth testing is active, the depth value from the fragment is compared to the depth value from the matching sample currently in the framebuffer. Let us call the fragment's depth N, while the framebuffer's depth P. The conditional test is of the form (N FUNC P), where FUNC is specified by this function:


{{apifunc|glClear}}, {{apifunc|glClearDepth}}, {{apifunc|glDepthFunc}}, {{apifunc|glDepthMask}}, {{apifunc|glDepthRange}}, {{apifunc|glDepthRangeArray}}, {{apifunc|glDepthRangeIndexed}}
{{funcdef|void {{apifunc|glDepthFunc}}(GLenum {{param|func}});}}


{{stub}}
The {{param|func}} may be one of the following:
 
{| class="wikitable" style="line-height: 1.0em;"
|-
! Enum
! Test
! Enum
! Test
|-
| {{enum|GL_NEVER}}
| Always fails.
| {{enum|GL_ALWAYS}}
| Always passes
|-
| {{enum|GL_LESS}}
| <
| {{enum|GL_LEQUAL}}
| ≤
|-
| {{enum|GL_GREATER}}
| >
| {{enum|GL_GEQUAL}}
| ≥
|-
| {{enum|GL_EQUAL}}
| =
| {{enum|GL_NOTEQUAL}}
| ≠
|}
 
== Early test ==
{{main|Early Depth Test}}
 
The depth test can take place before the [[Fragment Shader]] executes. It can only do this if the FS does not discard the fragment and does not modify {{code|gl_FragDepth}}. This is done as an optimization.
 
Early testing can also be enforced (with {{require|4.2|shader_image_load_store}}). If it is enforced, then the fragment shader's modifications to {{code|gl_FragDepth}} will be ignored, and if the FS discards the fragment, the depth will still be written (unless the current [[Write Mask]] prevents it).
 
== See also ==
 
* [[Stencil Test]]
* [[Fragment Shader]]


[[Category:Sample Writing]]
[[Category:Sample Writing]]

Latest revision as of 05:22, 8 March 2018

The Depth Test is a per-sample processing operation performed after the Fragment Shader (and sometimes before). The Fragment's output depth value may be tested against the depth of the sample being written to. If the test fails, the fragment is discarded. If the test passes, the depth buffer will be updated with the fragment's output depth, unless a subsequent per-sample operation prevents it (such as turning off depth writes).

Depth buffer

In order to use the depth test, the current Framebuffer must have a depth buffer. A depth buffer is an image that uses a depth image format. The Default Framebuffer may have a depth buffer, and user-defined framebuffers can attach depth formatted images (either depth/stencil or depth-only) to the GL_DEPTH_ATTACHMENT attachment point.

If the current framebuffer has no depth buffer, then the depth test behaves as if it is always disabled.

Fragment depth value

Every Fragment has a depth value. This value is either computed by the Fragment Shader (if it writes to gl_FragDepth) or is the window-space Z coordinate computed as the output of the Vertex Post-Processing steps.

Depth test

To enable depth testing, call glEnable with GL_DEPTH_TEST. When rendering to a framebuffer that has no depth buffer, depth testing always behaves as though the test is disabled.

When depth testing is disabled, writes to the depth buffer are also disabled.

When depth testing is active, the depth value from the fragment is compared to the depth value from the matching sample currently in the framebuffer. Let us call the fragment's depth N, while the framebuffer's depth P. The conditional test is of the form (N FUNC P), where FUNC is specified by this function:

void glDepthFunc(GLenum func​);

The func​ may be one of the following:

Enum Test Enum Test
GL_NEVER Always fails. GL_ALWAYS Always passes
GL_LESS < GL_LEQUAL
GL_GREATER > GL_GEQUAL
GL_EQUAL = GL_NOTEQUAL

Early test

The depth test can take place before the Fragment Shader executes. It can only do this if the FS does not discard the fragment and does not modify gl_FragDepth. This is done as an optimization.

Early testing can also be enforced (with OpenGL 4.2 or ARB_shader_image_load_store). If it is enforced, then the fragment shader's modifications to gl_FragDepth will be ignored, and if the FS discards the fragment, the depth will still be written (unless the current Write Mask prevents it).

See also