LearnOpenGL

Translation in progress of learnopengl.com.
git clone https://git.mtkn.jp/LearnOpenGL
Log | Files | Refs

Depth-testing.html (30987B)


      1 <!DOCTYPE html>
      2 <html lang="ja"> 
      3 <head>
      4     <meta charset="utf-8"/>
      5     <title>LearnOpenGL</title>
      6     <link rel="shortcut icon" type="image/ico" href="/favicon.ico"  />
      7 	<link rel="stylesheet" href="../static/style.css" />
      8 	<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"> </script>
      9 	<script src="/static/functions.js"></script>
     10 </head>
     11 <body>
     12 	<nav>
     13 <ol>
     14 	<li id="Introduction">
     15 		<a href="https://learnopengl.com/Introduction">はじめに</a>
     16 	</li>
     17 	<li id="Getting-started">
     18 		<span class="closed">入門</span>
     19 		<ol>
     20 			<li id="Getting-started/OpenGL">
     21 				<a href="https://learnopengl.com/Getting-started/OpenGL">OpenGL </a>
     22 			</li>
     23 			<li id="Getting-started/Creating-a-window">
     24 				<a href="https://learnopengl.com/Getting-started/Creating-a-window">ウィンドウの作成</a>
     25 			</li>
     26 			<li id="Getting-started/Hello-Window">
     27 				<a href="https://learnopengl.com/Getting-started/Hello-Window">最初のウィンドウ</a>
     28 			</li>
     29 			<li id="Getting-started/Hello-Triangle">
     30 				<a href="https://learnopengl.com/Getting-started/Hello-Triangle">最初の三角形</a>
     31 			</li>
     32 			<li id="Getting-started/Shaders">
     33 				<a href="https://learnopengl.com/Getting-started/Shaders">シェーダー</a>
     34 			</li>
     35 			<li id="Getting-started/Textures">
     36 				<a href="https://learnopengl.com/Getting-started/Textures">テクスチャ</a>
     37 			</li>
     38 			<li id="Getting-started/Transformations">
     39 				<a href="https://learnopengl.com/Getting-started/Transformations">座標変換</a>
     40 			</li>
     41 			<li id="Getting-started/Coordinate-Systems">
     42 				<a href="https://learnopengl.com/Getting-started/Coordinate-Systems">座標系</a>
     43 			</li>
     44 			<li id="Getting-started/Camera">
     45 				<a href="https://learnopengl.com/Getting-started/Camera">カメラ</a>
     46 			</li>
     47 			<li id="Getting-started/Review">
     48 				<a href="https://learnopengl.com/Getting-started/Review">まとめ</a>
     49 			</li>
     50 		</ol>
     51 	</li>
     52 	<li id="Lighting">
     53 		<span class="closed">Lighting </span>
     54 		<ol>
     55 			<li id="Lighting/Colors">
     56 				<a href="https://learnopengl.com/Lighting/Colors">Colors </a>
     57 			</li>
     58 			<li id="Lighting/Basic-Lighting">
     59 				<a href="https://learnopengl.com/Lighting/Basic-Lighting">Basic Lighting </a>
     60 			</li>
     61 			<li id="Lighting/Materials">
     62 				<a href="https://learnopengl.com/Lighting/Materials">Materials </a>
     63 			</li>
     64 			<li id="Lighting/Lighting-maps">
     65 				<a href="https://learnopengl.com/Lighting/Lighting-maps">Lighting maps </a>
     66 			</li>
     67 			<li id="Lighting/Light-casters">
     68 				<a href="https://learnopengl.com/Lighting/Light-casters">Light casters </a>
     69 			</li>
     70 			<li id="Lighting/Multiple-lights">
     71 				<a href="https://learnopengl.com/Lighting/Multiple-lights">Multiple lights </a>
     72 			</li>
     73 			<li id="Lighting/Review">
     74 				<a href="https://learnopengl.com/Lighting/Review">Review </a>
     75 			</li>
     76 		</ol>
     77 	</li>
     78 	<li id="Model-Loading">
     79 		<span class="closed">Model Loading </span>
     80 		<ol>
     81 			<li id="Model-Loading/Assimp">
     82 				<a href="https://learnopengl.com/Model-Loading/Assimp">Assimp </a>
     83 			</li>
     84 			<li id="Model-Loading/Mesh">
     85 				<a href="https://learnopengl.com/Model-Loading/Mesh">Mesh </a>
     86 			</li>
     87 			<li id="Model-Loading/Model">
     88 				<a href="https://learnopengl.com/Model-Loading/Model">Model </a>
     89 			</li>
     90 		</ol>
     91 	</li>
     92 	<li id="Advanced-OpenGL">
     93 		<span class="closed">Advanced OpenGL </span>
     94 		<ol>
     95 			<li id="Advanced-OpenGL/Depth-testing">
     96 				<a href="https://learnopengl.com/Advanced-OpenGL/Depth-testing">Depth testing </a>
     97 			</li>
     98 			<li id="Advanced-OpenGL/Stencil-testing">
     99 				<a href="https://learnopengl.com/Advanced-OpenGL/Stencil-testing">Stencil testing </a>
    100 			</li>
    101 			<li id="Advanced-OpenGL/Blending">
    102 				<a href="https://learnopengl.com/Advanced-OpenGL/Blending">Blending </a>
    103 			</li>
    104 			<li id="Advanced-OpenGL/Face-culling">
    105 				<a href="https://learnopengl.cm/Advanced-OpenGL/Face-culling">Face culling </a>
    106 			</li>
    107 			<li id="Advanced-OpenGL/Framebuffers">
    108 				<a href="https://learnopengl.com/Advanced-OpenGL/Framebuffers">Framebuffers </a>
    109 			</li>
    110 			<li id="Advanced-OpenGL/Cubemaps">
    111 				<a href="https://learnopengl.com/Advanced-OpenGL/Cubemaps">Cubemaps </a>
    112 			</li>
    113 			<li id="Advanced-OpenGL/Advanced-Data">
    114 				<a href="https://learnopengl.com/Advanced-OpenGL/Advanced-Data">Advanced Data </a>
    115 			</li>
    116 			<li id="Advanced-OpenGL/Advanced-GLSL">
    117 				<a href="https://learnopengl.com/Advanced-OpenGL/Advanced-GLSL">Advanced GLSL </a>
    118 			</li>
    119 			<li id="Advanced-OpenGL/Geometry-Shader">
    120 				<a href="https://learnopengl.com/Advanced-OpenGL/Geometry-Shader">Geometry Shader </a>
    121 			</li>
    122 			<li id="Advanced-OpenGL/Instancing">
    123 				<a href="https://learnopengl.com/Advanced-OpenGL/Instancing">Instancing </a>
    124 			</li>
    125 			<li id="Advanced-OpenGL/Anti-Aliasing">
    126 				<a href="https://learnopengl.com/Advanced-OpenGL/Anti-Aliasing">Anti Aliasing </a>
    127 			</li>
    128 		</ol>
    129 	</li>
    130 	<li id="Advanced-Lighting">
    131 		<span class="closed">Advanced Lighting </span>
    132 		<ol>
    133 			<li id="Advanced-Lighting/Advanced-Lighting">
    134 				<a href="https://learnopengl.com/Advanced-Lighting/Advanced-Lighting">Advanced Lighting </a>
    135 			</li>
    136 			<li id="Advanced-Lighting/Gamma-Correction">
    137 				<a href="https://learnopengl.com/Advanced-Lighting/Gamma-Correction">Gamma Correction </a>
    138 			</li>
    139 			<li id="Advanced-Lighting/Shadows">
    140 				<span class="closed">Shadows </span>
    141 				<ol>
    142 					<li id="Advanced-Lighting/Shadows/Shadow-Mapping">
    143 						<a href="https://learnopengl.com/Advanced-Lighting/Shadows/Shadow-Mapping">Shadow Mapping </a>
    144 					</li>
    145 					<li id="Advanced-Lighting/Shadows/Point-Shadows">
    146 						<a href="https://learnopengl.com/Advanced-Lighting/Shadows/Point-Shadows">Point Shadows </a>
    147 					</li>
    148 				</ol>
    149 			</li>
    150 			<li id="Advanced-Lighting/Normal-Mapping">
    151 				<a href="https://learnopengl.com/Advanced-Lighting/Normal-Mapping">Normal Mapping </a>
    152 			</li>
    153 			<li id="Advanced-Lighting/Parallax-Mapping">
    154 				<a href="https://learnopengl.com/Advanced-Lighting/Parallax-Mapping">Parallax Mapping </a>
    155 			</li>
    156 			<li id="Advanced-Lighting/HDR">
    157 				<a href="https://learnopengl.com/Advanced-Lighting/HDR">HDR </a>
    158 			</li>
    159 			<li id="Advanced-Lighting/Bloom">
    160 				<a href="https://learnopengl.com/Advanced-Lighting/Bloom">Bloom </a>
    161 			</li>
    162 			<li id="Advanced-Lighting/Deferred-Shading">
    163 				<a href="https://learnopengl.com/Advanced-Lighting/Deferred-Shading">Deferred Shading </a>
    164 			</li>
    165 			<li id="Advanced-Lighting/SSAO">
    166 				<a href="https://learnopengl.com/Advanced-Lighting/SSAO">SSAO </a>
    167 			</li>
    168 		</ol>
    169 	</li>
    170 	<li id="PBR">
    171 		<span class="closed">PBR </span>
    172 		<ol>
    173 			<li id="PBR/Theory">
    174 				<a href="https://learnopengl.com/PBR/Theory">Theory </a>
    175 			</li>
    176 			<li id="PBR/Lighting">
    177 				<a href="https://learnopengl.com/PBR/Lighting">Lighting </a>
    178 			</li>
    179 			<li id="PBR/IBL">
    180 				<span class="closed">IBL </span>
    181 				<ol>
    182 					<li id="PBR/IBL/Diffuse-irradiance">
    183 						<a href="https://learnopengl.com/PBR/IBL/Diffuse-irradiance">Diffuse irradiance </a>
    184 					</li>
    185 					<li id="PBR/IBL/Specular-IBL">
    186 						<a href="https://learnopengl.com/PBR/IBL/Specular-IBL">Specular IBL </a>
    187 					</li>
    188 				</ol>
    189 			</li>
    190 		</ol>
    191 	</li>
    192 	<li id="In-Practice">
    193 		<span class="closed">In Practice </span>
    194 		<ol>
    195 			<li id="In-Practice/Debugging">
    196 				<a href="https://learnopengl.com/In-Practice/Debugging">Debugging </a>
    197 			</li>
    198 			<li id="In-Practice/Text-Rendering">
    199 				<a href="https://learnopengl.com/In-Practice/Text-Rendering">Text Rendering </a>
    200 			</li>
    201 			<li id="In-Practice/2D-Game">
    202 				<span class="closed">2D Game </span>
    203 				<ol>
    204 					<li id="In-Practice/2D-Game/Breakout">
    205 						<a href="https://learnopengl.com/In-Practice/2D-Game/Breakout">Breakout </a>
    206 					</li>
    207 					<li id="In-Practice/2D-Game/Setting-up">
    208 						<a href="https://learnopengl.com/In-Practice/2D-Game/Setting-up">Setting up </a>
    209 					</li>
    210 					<li id="In-Practice/2D-Game/Rendering-Sprites">
    211 						<a href="https://learnopengl.com/In-Practice/2D-Game/Rendering-Sprites">Rendering Sprites </a>
    212 					</li>
    213 					<li id="In-Practice/2D-Game/Levels">
    214 						<a href="https://learnopengl.com/In-Practice/2D-Game/Levels">Levels </a>
    215 					</li>
    216 					<li id="In-Practice/2D-Game/Collisions">
    217 						<span class="closed">Collisions </span>
    218 						<ol>
    219 							<li id="In-Practice/2D-Game/Collisions/Ball">
    220 								<a href="https://learnopengl.com/In-Practice/2D-Game/Collisions/Ball">Ball </a>
    221 							</li>
    222 							<li id="In-Practice/2D-Game/Collisions/Collision-detection">
    223 								<a href="https://learnopengl.com/In-Practice/2D-Game/Collisions/Collision-detection">Collision detection </a>
    224 							</li>
    225 							<li id="In-Practice/2D-Game/Collisions/Collision-resolution">
    226 								<a href="https://learnopengl.com/In-Practice/2D-Game/Collisions/Collision-resolution">Collision resolution </a>
    227 							</li>
    228 						</ol>
    229 					</li>
    230 					<li id="In-Practice/2D-Game/Particles">
    231 						<a href="https://learnopengl.com/In-Practice/2D-Game/Particles">Particles </a>
    232 					</li>
    233 					<li id="In-Practice/2D-Game/Postprocessing">
    234 						<a href="https://learnopengl.com/In-Practice/2D-Game/Postprocessing">Postprocessing </a>
    235 					</li>
    236 					<li id="In-Practice/2D-Game/Powerups">
    237 						<a href="https://learnopengl.com/In-Practice/2D-Game/Powerups">Powerups </a>
    238 					</li>
    239 					<li id="In-Practice/2D-Game/Audio">
    240 						<a href="https://learnopengl.com/In-Practice/2D-Game/Audio">Audio </a>
    241 					</li>
    242 					<li id="In-Practice/2D-Game/Render-text">
    243 						<a href="https://learnopengl.com/In-Practice/2D-Game/Render-text">Render text </a>
    244 					</li>
    245 					<li id="In-Practice/2D-Game/Final-thoughts">
    246 						<a href="https://learnopengl.com/In-Practice/2D-Game/Final-thoughts">Final thoughts </a>
    247 					</li>
    248 				</ol>
    249 			</li>
    250 		</ol>
    251 	</li>
    252 	<li id="Guest-Articles">
    253 		<span class="closed">Guest Articles </span>
    254 		<ol>
    255 			<li id="Guest-Articles/How-to-publish">
    256 				<a href="https://learnopengl.com/Guest-Articles/How-to-publish">How to publish </a>
    257 			</li>
    258 			<li id="Guest-Articles/2020">
    259 				<span class="closed">2020 </span>
    260 				<ol>
    261 					<li id="Guest-Articles/2020/OIT">
    262 						<span class="closed">OIT </span>
    263 						<ol>
    264 							<li id="Guest-Articles/2020/OIT/Introduction">
    265 								<a href="https://learnopengl.com/Guest-Articles/2020/OIT/Introduction">Introduction </a>
    266 							</li>
    267 							<li id="Guest-Articles/2020/OIT/Weighted-Blended">
    268 								<a href="https://learnopengl.com/Guest-Articles/2020/OIT/Weighted-Blended">Weighted Blended </a>
    269 							</li>
    270 						</ol>
    271 					</li>
    272 					<li id="Guest-Articles/2020/Skeletal-Animation">
    273 						<a href="https://learnopengl.com/Guest-Articles/2020/Skeletal-Animation">Skeletal Animation </a>
    274 					</li>
    275 				</ol>
    276 			</li>
    277 			<li id="Guest-Articles/2021">
    278 				<span class="closed">2021 </span>
    279 				<ol>
    280 					<li id="Guest-Articles/2021/CSM">
    281 						<a href="https://learnopengl.com/Guest-Articles/2021/CSM">CSM </a>
    282 					</li>
    283 					<li id="Guest-Articles/2021/Scene">
    284 						<span class="closed">Scene </span>
    285 						<ol>
    286 							<li id="Guest-Articles/2021/Scene/Scene-Graph">
    287 								<a href="https://learnopengl.com/Guest-Articles/2021/Scene/Scene-Graph">Scene Graph </a>
    288 							</li>
    289 							<li id="Guest-Articles/2021/Scene/Frustum-Culling">
    290 								<a href="https://learnopengl.com/Guest-Articles/2021/Scene/Frustum-Culling">Frustum Culling </a>
    291 							</li>
    292 						</ol>
    293 					</li>
    294 					<li id="Guest-Articles/2021/Tessellation">
    295 						<span class="closed">Tessellation </span>
    296 						<ol>
    297 							<li id="Guest-Articles/2021/Tessellation/Height-map">
    298 								<a href="https://learnopengl.com/Guest-Articles/2021/Tessellation/Height-map">Height map </a>
    299 							</li>
    300 						</ol>
    301 					</li>
    302 				</ol>
    303 			</li>
    304 		</ol>
    305 	</li>
    306 	<li id="Code-repository">
    307 		<a href="https://learnopengl.com/Code-repository">Code repository </a>
    308 	</li>
    309 	<li id="Translations">
    310 		<a href="https://learnopengl.com/Translations">Translations </a>
    311 	</li>
    312 	<li id="About">
    313 		<a href="https://learnopengl.com/About">About </a>
    314 	</li>
    315 </ol>
    316 	</nav>
    317 	<main>
    318     <h1 id="content-title">Depth testing</h1>
    319 <h1 id="content-url" style='display:none;'>Advanced-OpenGL/Depth-testing</h1>
    320 <p>
    321   In the <a href="https://learnopengl.com/Getting-started/Coordinate-Systems" target="_blank">coordinate systems</a> chapter we've rendered a 3D container and made use of a <def>depth buffer</def> to prevent triangles rendering in the front while they're supposed to be behind other triangles. In this chapter we're going to elaborate a bit more on those <def>depth values</def> the depth buffer (or z-buffer) stores and how it actually determines if a fragment is in front. 
    322 </p>
    323 
    324 <p>
    325   The depth-buffer is a buffer that, just like the <def>color buffer</def> (that stores all the fragment colors: the visual output), stores information per fragment and has the same width and height as the color buffer. The depth buffer is automatically created by the windowing system and stores its depth values as <code>16</code>, <code>24</code> or <code>32</code> bit floats. In most systems you'll see a depth buffer with a precision of <code>24</code> bits. 
    326 </p>
    327 
    328 <p>
    329   When depth testing is enabled, OpenGL tests the depth value of a fragment against the content of the depth buffer. OpenGL performs a depth test and if this test passes, the fragment is rendered and the depth buffer is updated with the new depth value. If the depth test fails, the fragment is discarded.
    330 </p>
    331 
    332 <p>
    333   Depth testing is done in screen space after the fragment shader has run (and after the stencil test which we'll get to in the <a href="https://learnopengl.com/Advanced-OpenGL/Stencil-testing" target="_blank">next</a> chapter). The screen space coordinates relate directly to the viewport defined by OpenGL's <fun><function id='22'>glViewport</function></fun> function and can be accessed via GLSL's built-in <var>gl_FragCoord</var> variable in the fragment shader. The x and y components of <var>gl_FragCoord</var> represent the fragment's screen-space coordinates (with (0,0) being the bottom-left corner). The <var>gl_FragCoord</var> variable also contains a z-component which contains the depth value of the fragment. This z value is the value that is compared to the depth buffer's content. 
    334 </p>
    335 
    336 <note>
    337   Today most GPUs support a hardware feature called <def>early depth testing</def>. Early depth testing allows the depth test to run before the fragment shader runs. Whenever it is clear a fragment isn't going to be visible (it is behind other objects) we can prematurely discard the fragment. 
    338 <br/><br/>
    339 Fragment shaders are usually quite expensive so wherever we can avoid running them we should. A restriction on the fragment shader for early depth testing is that you shouldn't write to the fragment's depth value. If a fragment shader would write to its depth value, early depth testing is impossible;  OpenGL won't be able to figure out the depth value beforehand. 
    340 </note>
    341 
    342 <p>
    343   Depth testing is disabled by default so to enable depth testing we need to enable it with the <var>GL_DEPTH_TEST</var> option:
    344 </p>
    345 
    346 <pre><code>
    347 <function id='60'>glEnable</function>(GL_DEPTH_TEST);  
    348 </code></pre>
    349 
    350 <p>
    351   Once enabled, OpenGL automatically stores fragments their z-values in the depth buffer if they passed the depth test and discards fragments if they failed the depth test accordingly. If you have depth testing enabled you should also clear the depth buffer before each frame using <var>GL_DEPTH_BUFFER_BIT</var>; otherwise you're stuck with the depth values from last frame:
    352 </p>
    353 
    354 <pre><code>
    355 <function id='10'>glClear</function>(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  
    356 </code></pre>
    357 
    358 <p>
    359   There are certain scenarios imaginable where you want to perform the depth test on all fragments and discard them accordingly, but <strong>not</strong> update the depth buffer. Basically, you're (temporarily) using a <def>read-only</def> depth buffer. OpenGL allows us to disable writing to the depth buffer by setting its depth mask to <code>GL_FALSE</code>:
    360 </p>
    361 
    362 <pre><code>
    363 <function id='65'>glDepthMask</function>(GL_FALSE);  
    364 </code></pre>
    365 
    366 <p>
    367   Note that this only has effect if depth testing is enabled. 
    368 </p>
    369 
    370 <h2>Depth test function</h2>
    371 <p>
    372   OpenGL allows us to modify the comparison operators it uses for the depth test. This allows us to control when OpenGL should pass or discard fragments and when to update the depth buffer. We can set the comparison operator (or depth function) by calling <fun><function id='66'>glDepthFunc</function></fun>:
    373 </p>
    374 
    375 <pre><code>
    376 <function id='66'>glDepthFunc</function>(GL_LESS);  
    377 </code></pre>
    378 
    379 <p>
    380   The function accepts several comparison operators that are listed in the table below:
    381 </p>
    382 
    383 <table>
    384   <tr>
    385   	<th>Function</th>
    386   	<th>Description</th>
    387   </tr>  
    388   <tr>
    389     <td><code>GL_ALWAYS</code></td>
    390  	<td>The depth test always passes.</td>
    391   </tr>
    392   <tr>
    393     <td><code>GL_NEVER</code></td>
    394  	<td>The depth test never passes.</td>
    395   </tr>
    396   <tr>
    397     <td><code>GL_LESS</code></td>
    398  	<td>Passes if the fragment's depth value is less than the stored depth value.</td>
    399   </tr>
    400   <tr>
    401     <td><code>GL_EQUAL</code></td>
    402  	<td>Passes if the fragment's depth value is equal to the stored depth value.</td>
    403   </tr><tr>
    404     <td><code>GL_LEQUAL</code></td>
    405  	<td>Passes if the fragment's depth value is less than or equal to the stored depth value.</td>
    406   </tr> 
    407   <tr>
    408     <td><code>GL_GREATER</code></td>
    409  	<td>Passes if the fragment's depth value is greater than the stored depth value.</td>
    410   </tr>
    411   <tr>
    412     <td><code>GL_NOTEQUAL</code></td>
    413  	<td>Passes if the fragment's depth value is not equal to the stored depth value.</td>
    414   </tr>
    415   <tr>
    416     <td><code>GL_GEQUAL</code></td>
    417  	<td>Passes if the fragment's depth value is greater than or equal to the stored depth value.</td>
    418   </tr>
    419 </table>
    420 
    421 <p>
    422   By default the depth function <var>GL_LESS</var> is used that discards all the fragments that have a depth value higher than or equal to the current depth buffer's value.
    423 </p>
    424 
    425 <p>
    426   Let's show the effect that changing the depth function has on the visual output. We'll use a fresh code setup that displays a basic scene with two textured cubes sitting on a textured floor with no lighting. You can find the source code <a href="/code_viewer_gh.php?code=src/4.advanced_opengl/1.1.depth_testing/depth_testing.cpp" target="_blank">here</a>.
    427 </p>
    428 
    429 <p>
    430   Within the source code we changed the depth function to <var>GL_ALWAYS</var>:
    431 </p>
    432 
    433 <pre><code>
    434 <function id='60'>glEnable</function>(GL_DEPTH_TEST);
    435 <function id='66'>glDepthFunc</function>(GL_ALWAYS); 
    436 </code></pre>
    437 
    438 <p>
    439   This simulates the same behavior we'd get if we didn't enable depth testing. The depth test always passes so the fragments that are drawn last are rendered in front of the fragments that were drawn before, even though they should've been at the front. Since we've drawn the floor plane last, the plane's fragments overwrite each of the container's previously written fragments:
    440 </p>
    441 
    442 <img src="/img/advanced/depth_testing_func_always.png" class="clean" alt="Depth testing in OpenGL with GL_ALWAYS as depth function"/>
    443 
    444 <p>
    445   Setting it all back to <var>GL_LESS</var> gives us the type of scene we're used to:
    446 </p>
    447 
    448 <img src="/img/advanced/depth_testing_func_less.png" class="clean" alt="Depth testing in OpenGL with GL_LESS as depth function"/>
    449 
    450 <h2>Depth value precision</h2>
    451 <p>
    452   The depth buffer contains depth values between <code>0.0</code> and <code>1.0</code> and it compares its content with the z-values of all the objects in the scene as seen from the viewer. These z-values in view space can be any value between the projection-frustum's <code>near</code> and <code>far</code> plane. We thus need some way to transform these view-space z-values to the range of <code>[0,1]</code> and one way is to linearly transform them. The following (linear) equation transforms the z-value to a depth value between <code>0.0</code> and <code>1.0</code>:
    453 </p>
    454 
    455 \begin{equation} F_{depth} = \frac{z - near}{far - near} \end{equation}
    456 
    457 <p>
    458   Here \(near\) and \(far\) are the <em>near</em> and <em>far</em> values we used to provide to the projection matrix to set the visible frustum (see <a href="https://learnopengl.com/Getting-started/Coordinate-Systems" target="_blank">coordinate Systems</a>). The equation takes a depth value \(z\) within the frustum and transforms it to the range <code>[0,1]</code>. The relation between the z-value and its corresponding depth value is presented in the following graph:
    459 </p>
    460 
    461 <img src="/img/advanced/depth_linear_graph.png" class="clean" alt="Graph of depth values in OpenGL as a linear function"/>
    462 
    463 <note>
    464   Note that all equations give a depth value close to <code>0.0</code> when the object is close by  and a depth value close to <code>1.0</code> when the object is close to the far plane.
    465 </note>
    466 
    467 <p>
    468   In practice however, a <def>linear depth buffer</def> like this is almost never used. Because of projection properties a non-linear depth equation is used that is proportional to 1/z. The result is that we get enormous precision when z is small and much less precision when z is far away.
    469 </p>
    470 
    471 <p>
    472   Since the non-linear function is proportional to 1/z, z-values between <code>1.0</code> and <code>2.0</code> would result in depth values between <code>1.0</code> and <code>0.5</code> which is half of the [0,1] range, giving us enormous precision at small z-values. Z-values between <code>50.0</code> and <code>100.0</code> would account for only 2% of the [0,1] range. Such an equation, that also takes near and far distances into account, is given below:
    473 </p>
    474 
    475 \begin{equation} F_{depth} = \frac{1/z - 1/near}{1/far - 1/near} \end{equation}
    476 
    477 <p>
    478   Don't worry if you don't know exactly what is going on with this equation. The important thing to remember is that the values in the depth buffer are not linear in clip-space (they are linear in view-space before the projection matrix is applied). A value of <code>0.5</code> in the depth buffer does not mean the pixel's z-value is halfway in the frustum; the z-value of the vertex is actually quite close to the near plane! You can see the non-linear relation between the z-value and the resulting depth buffer's value in the following graph:
    479 </p>
    480 
    481 <img src="/img/advanced/depth_non_linear_graph.png" class="clean" alt="Graph of depth values in OpenGL as a non-linear function"/>
    482 
    483 <p>
    484   As you can see, the depth values are greatly determined by the small z-values giving us large depth precision to the objects close by. The equation to transform z-values (from the viewer's perspective) is embedded within the projection matrix so when we transform vertex coordinates from view to clip, and then to screen-space the non-linear equation is applied. 
    485 </p>  
    486 
    487 <p>
    488   The effect of this non-linear equation quickly becomes apparent when we try to visualize the depth buffer.
    489 </p>
    490 
    491 <h2>Visualizing the depth buffer</h2>
    492 <p>
    493   We know that the z-value of the built-in <var>gl_FragCoord</var> vector in the fragment shader contains the depth value of that particular fragment. If we were to output this depth value of the fragment as a color we could display the depth values of all the fragments in the scene:
    494 </p>
    495 
    496 <pre><code>
    497 void main()
    498 {             
    499     FragColor = vec4(vec3(gl_FragCoord.z), 1.0);
    500 }  
    501 </code></pre>
    502 
    503 <p>
    504   If you'd then run the program you'll probably notice that everything is white, making it look like all of our depth values are the maximum depth value of <code>1.0</code>. So why aren't any of the depth values closer to <code>0.0</code> and thus darker?
    505 </p>
    506 
    507 <p>
    508   In the previous section we described that depth values in screen space are non-linear e.g. they have a very high precision for small z-values and a low precision for large z-values. The depth value of the fragment increases rapidly over distance so almost all the vertices have values close to <code>1.0</code>. If we were to carefully move really close to an object you may eventually see the colors getting darker, their z-values becoming smaller:
    509 </p>
    510 
    511 <img src="/img/advanced/depth_testing_visible_depth.png" class="clean" alt="Depth buffer visualized in OpenGL and GLSL"/>
    512 
    513 <p>
    514   This clearly shows the non-linearity of the depth value. Objects close by have a much larger effect on the depth value than objects far away. Only moving a few inches can result in the colors going from dark to completely white.
    515 </p>
    516 
    517 <p>
    518   We can however, transform the non-linear depth values of the fragment back to its linear sibling. To achieve this we basically need to reverse the process of projection for the depth values alone. This means we have to first re-transform the depth values from the range <code>[0,1]</code> to normalized device coordinates in the range <code>[-1,1]</code>. Then we want to reverse the non-linear equation (equation 2) as done in the projection matrix and apply this inversed equation to the resulting depth value. The result is then a linear depth value. 
    519 </p>
    520 
    521 <p>
    522   First we transform the depth value to NDC which is not too difficult:
    523 </p>
    524 
    525 <pre><code>
    526 float ndc = depth * 2.0 - 1.0; 
    527 </code></pre>
    528 
    529 <p>
    530   We then take the resulting <var>ndc</var> value and apply the inverse transformation to retrieve its linear depth value:
    531 </p>
    532 
    533 <pre><code>
    534 float linearDepth = (2.0 * near * far) / (far + near - ndc * (far - near));	
    535 </code></pre>
    536 
    537 <p>
    538   This equation is derived from the projection matrix for non-linearizing the depth values, returning depth values between <var>near</var> and <var>far</var>. This <a href="http://www.songho.ca/opengl/gl_projectionmatrix.html" target="_blank">math-heavy article</a> explains the projection matrix in enormous detail for the interested reader; it also shows where the equations come from.
    539 </p>
    540 
    541 <p>
    542   The complete fragment shader that transforms the non-linear depth in screen-space to a linear depth value is then as follows:
    543 </p>
    544 
    545 <pre><code>
    546 #version 330 core
    547 out vec4 FragColor;
    548 
    549 float near = 0.1; 
    550 float far  = 100.0; 
    551   
    552 float LinearizeDepth(float depth) 
    553 {
    554     float z = depth * 2.0 - 1.0; // back to NDC 
    555     return (2.0 * near * far) / (far + near - z * (far - near));	
    556 }
    557 
    558 void main()
    559 {             
    560     float depth = LinearizeDepth(gl_FragCoord.z) / far; // divide by far for demonstration
    561     FragColor = vec4(vec3(depth), 1.0);
    562 }
    563 </code></pre>
    564 
    565 <p>
    566   Because the linearized depth values range from <var>near</var> to <var>far</var> most of its values will be above <code>1.0</code> and displayed as completely white. By dividing the linear depth value by <var>far</var> in the <fun>main</fun> function we convert the linear depth value to the range [<code>0</code>, <code>1</code>]. This way we can gradually see the scene become brighter the closer the fragments are to the projection frustum's far plane, which works better for visualization purposes.
    567 </p>
    568 
    569 <p>
    570   If we'd now run the application we get depth values that are linear over distance. Try moving around the scene to see the depth values change in a linear fashion.
    571 </p>
    572 
    573 <img src="/img/advanced/depth_testing_visible_linear.png" class="clean" alt="Depth buffer visualized in OpenGL and GLSL as linear values"/>
    574 
    575 <p>
    576   The colors are mostly black because the depth values range linearly from the <code>near</code> plane (<code>0.1</code>) to the <code>far</code> plane (<code>100</code>) which is still quite far away from us. The result is that we're relatively close to the near plane and therefore get lower (darker) depth values.
    577 </p>
    578 
    579 <h2>Z-fighting</h2>
    580 <p>
    581   A common visual artifact may occur when two planes or triangles are so closely aligned to each other that the depth buffer does not have enough precision to figure out which one of the two shapes is in front of the other. The result is that the two shapes continually seem to switch order which causes weird glitchy patterns. This is called <def>z-fighting</def>, because it looks like the shapes are fighting over who gets on top.
    582 </p>
    583 
    584 <p>
    585   In the scene we've been using so far there are a few spots where z-fighting can be noticed. The containers were placed at the exact height of the floor which means the bottom plane of the container is coplanar with the floor plane. The depth values of both planes are then the same so the resulting depth test has no way of figuring out which is the right one. 
    586 </p>
    587 
    588 <p>
    589   If you move the camera inside one of the containers the effects are clearly visible, the bottom part of the container is constantly switching between the container's plane and the floor's plane in a zigzag pattern:
    590 </p>
    591 
    592 <img src="/img/advanced/depth_testing_z_fighting.png" class="clean" alt="Demonstration of Z-fighting in OpenGL"/>
    593 
    594 <p>
    595   Z-fighting is a common problem with depth buffers and it's generally more noticeable when objects are further away (because the depth buffer has less precision at larger z-values). Z-fighting can't be completely prevented, but there are a few tricks that will help to mitigate or completely prevent z-fighting in your scene.
    596 </p>
    597 
    598 <h3>Prevent z-fighting</h3>
    599 <p>
    600   The first and most important trick is <em>never place objects too close to each other in a way that some of their triangles closely overlap</em>. By creating a small offset between two objects you can completely remove z-fighting between the two objects. In the case of the containers and the plane we could've easily moved the containers slightly upwards in the positive y direction. The small change of the container's positions would probably not be noticeable at all and would completely reduce the z-fighting. However, this requires manual intervention of each of the objects and thorough testing to make sure no objects in a scene produce z-fighting.
    601 </p>
    602 
    603 <p>
    604   A second trick is to <em>set the near plane as far as possible</em>. In one of the previous sections we've discussed that precision is extremely large when close to the <code>near</code> plane so if we move the <code>near</code> plane away from the viewer, we'll have significantly greater precision over the entire frustum range. However, setting the <code>near</code> plane too far could cause clipping of near objects so it is usually a matter of tweaking and experimentation to figure out the best <code>near</code> distance for your scene. 
    605 </p>
    606 
    607 <p>
    608   Another great trick at the cost of some performance is to <em>use a higher precision depth buffer</em>. Most depth buffers have a precision of <code>24</code> bits, but most GPUs nowadays support <code>32</code> bit depth buffers, increasing the precision by a significant amount. So at the cost of some performance you'll get much more precision with depth testing, reducing z-fighting.
    609 </p>
    610 
    611 <p>
    612   The 3 techniques we've discussed are the most common and easy-to-implement anti z-fighting techniques. There are some other techniques out there that require a lot more work and still won't completely disable z-fighting. Z-fighting is a common issue, but if you use the proper combination of the listed techniques you probably won't need to deal with z-fighting that much.
    613 </p>       
    614 
    615     </div>
    616     
    617 	</main>
    618 </body>
    619 </html>