Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Z-buffering
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
==Mathematics== The range of depth values in [[camera space]] to be rendered is often defined between a <math>\textit{near}</math> and <math>\textit{far}</math> value of <math>z</math>. After a [[perspective transform]]ation, the new value of <math>z</math>, or <math>z'</math>, is defined by: : <math>z'= \frac{\textit{far} + \textit{near}}{\textit{far} - \textit{near}} + \frac{1}{z} \left(\frac{-2 \cdot \textit{far} \cdot \textit{near}}{\textit{far} - \textit{near}}\right) </math> After an [[orthographic projection]], the new value of <math>z</math>, or <math>z'</math>, is defined by: :<math>z'= 2 \cdot \frac{{z} - \textit{near}}{\textit{far}-\textit{near}} - 1 </math> where <math>z</math> is the old value of <math>z</math> in camera space, and is sometimes called <math>w</math> or <math>w'</math>. The resulting values of <math>z'</math> are normalized between the values of -1 and 1, where the <math>\textit{near}</math> [[plane (mathematics)|plane]] is at -1 and the <math>\mathit{far}</math> plane is at 1. Values outside of this range correspond to points which are not in the viewing [[frustum]], and shouldn't be rendered. ===Fixed-point representation=== Typically, these values are stored in the z-buffer of the hardware graphics accelerator in [[Fixed-point arithmetic|fixed point]] format. First they are normalized to a more common range which is {{nowrap|[0, 1]}} by substituting the appropriate conversion <math>z'_2 = \frac{1}{2}\left(z'_1 + 1\right)</math> into the previous formula: :<math>z'= \frac{\textit{far} + \textit{near}}{2 \cdot \left( \textit{far} - \textit{near} \right)} + \frac{1}{2} + \frac{1}{z} \left(\frac{-\textit{far} \cdot \textit{near}}{\textit{far} - \textit{near}}\right) </math> Simplifying: :<math>z'= \frac{\textit{far}}{\left( \textit{far} - \textit{near} \right)} + \frac{1}{z} \left(\frac{-\textit{far} \cdot \textit{near}}{\textit{far} - \textit{near}}\right) </math> Second, the above formula is multiplied by <math>S = 2^d - 1</math> where d is the depth of the z-buffer (usually 16, 24 or 32 bits) and rounding the result to an integer:<ref>{{cite web | url = https://www.khronos.org/opengl/wiki/Depth_Buffer_Precision#Why_is_my_depth_buffer_precision_so_poor.3F | title = Open GL / FAQ 2 - Depth Buffer Precision | author = The OpenGL Organization | access-date = 2017-12-26}}</ref> :<math>z' = f(z) = \left\lfloor \left(2^d - 1\right) \cdot \left(\frac{\textit{far}}{\left( \textit{far} - \textit{near} \right)} + \frac{1}{z} \left(\frac{-\textit{far} \cdot \textit{near}}{\textit{far} - \textit{near}}\right) \right)\right\rfloor </math> This formula can be inverted and derived in order to calculate the z-buffer resolution (the 'granularity' mentioned earlier). The inverse of the above <math>f(z)\,</math>: :<math>z = \frac{-\textit{far} \cdot \textit{near}}{\frac{z'}{S}\left(\textit{far} - \textit{near}\right) - \textit{far}} = \frac{-S \cdot \textit{far} \cdot \textit{near}}{z'\left(\textit{far} - \textit{near}\right) - \textit{far} \cdot S} </math> where <math>S = 2^d - 1</math> The z-buffer resolution in terms of camera space would be the incremental value resulted from the smallest change in the integer stored in the z-buffer, which is +1 or -1. Therefore, this resolution can be calculated from the derivative of <math>z</math> as a function of <math>z'</math>: :<math>\frac{dz}{dz'} = \frac{-1 \cdot -1 \cdot S \cdot \textit{far} \cdot \textit{near}} {\left( z'\left(\textit{far} - \textit{near}\right) - \textit{far} \cdot S \right)^2} \cdot \left(\textit{far} - \textit{near}\right) </math> Expressing it back in camera space terms, by substituting <math>z'</math> by the above <math>f(z)\,</math>: :<math>\begin{align} \frac{dz}{dz'} &= \frac{-1 \cdot -1 \cdot S \cdot \textit{far} \cdot \textit{near} \cdot \left(\textit{far} - \textit{near}\right)} {\left(S \cdot \left(\frac{-\textit{far} \cdot \textit{near}}{z} + \textit{far}\right) - \textit{far} \cdot S \right)^2} \\ &= \frac{\left(\textit{far} - \textit{near}\right) \cdot z^2}{S \cdot \textit{far} \cdot \textit{near}} \\ &= \frac{z^2}{S \cdot \textit{near}} - \frac{z^2}{S \cdot \textit{far}} \approx \frac{z^2}{S \cdot \textit{near}} \end{align}</math> This shows that the values of <math>z'</math> are grouped much more densely near the <math>\textit{near}</math> plane, and much more sparsely farther away, resulting in better precision closer to the camera. The smaller <math>near</math> is, the less precision there is far away—having the <math>near</math> plane set too closely is a common cause of undesirable rendering artifacts in more distant objects.<ref>{{cite web | url = http://www.codermind.com/articles/Depth-buffer-tutorial.html | title = Depth buffer - the gritty details | author = Grégory Massal | access-date = 2008-08-03 | archive-url=https://web.archive.org/web/20081015234602/http://www.codermind.com/articles/Depth-buffer-tutorial.html | url-status=dead |archive-date=15 October 2008}}</ref> To implement a z-buffer, the values of <math>z'</math> are [[Linear interpolation|linearly interpolated]] across screen space between the [[vertex (geometry)|vertices]] of the current [[polygon]], and these intermediate values are generally stored in the z-buffer in [[Fixed-point arithmetic|fixed point]] format. ===W-buffer=== To implement a w-buffer,<ref>{{cite web | url = https://www.sjbaker.org/steve/omniv/love_your_z_buffer.html | title = Learning to Love your Z-buffer | author = Steve Baker | access-date = 2018-01-03}}</ref> the old values of <math>z</math> in camera space, or <math>w</math>, are stored in the buffer, generally in [[floating point]] format. However, these values cannot be linearly interpolated across screen space from the vertices—they usually have to be [[Multiplicative inverse|inverted]], interpolated, and then inverted again. The resulting values of <math>w</math>, as opposed to <math>z'</math>, are spaced evenly between <math>\textit{near}</math> and <math>\textit{far}</math>. There are implementations of the w-buffer that avoid the inversions altogether. Whether a z-buffer or w-buffer results in a better image depends on the application.
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)