You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
learn-wgpu/beginner/tutorial8-depth/index.html

127 lines
37 KiB
HTML

<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>The Depth Buffer | Learn Wgpu</title>
<meta name="generator" content="VuePress 1.9.10">
<meta name="description" content="">
<link rel="preload" href="/learn-wgpu/assets/css/0.styles.81cb5453.css" as="style"><link rel="preload" href="/learn-wgpu/assets/js/app.8ee4646c.js" as="script"><link rel="preload" href="/learn-wgpu/assets/js/2.2ef7287a.js" as="script"><link rel="preload" href="/learn-wgpu/assets/js/1.eaeeb819.js" as="script"><link rel="preload" href="/learn-wgpu/assets/js/43.991fa7d2.js" as="script"><link rel="preload" href="/learn-wgpu/assets/js/33.945dce62.js" as="script"><link rel="preload" href="/learn-wgpu/assets/js/37.5ecf7ce2.js" as="script"><link rel="prefetch" href="/learn-wgpu/assets/js/10.baf5d1fe.js"><link rel="prefetch" href="/learn-wgpu/assets/js/11.b8633c49.js"><link rel="prefetch" href="/learn-wgpu/assets/js/12.0b8835f1.js"><link rel="prefetch" href="/learn-wgpu/assets/js/13.af1bbe85.js"><link rel="prefetch" href="/learn-wgpu/assets/js/14.626c7cb3.js"><link rel="prefetch" href="/learn-wgpu/assets/js/15.5a8ea302.js"><link rel="prefetch" href="/learn-wgpu/assets/js/16.f4e8226b.js"><link rel="prefetch" href="/learn-wgpu/assets/js/17.ea2d3b52.js"><link rel="prefetch" href="/learn-wgpu/assets/js/18.4eb59bb5.js"><link rel="prefetch" href="/learn-wgpu/assets/js/19.48960e96.js"><link rel="prefetch" href="/learn-wgpu/assets/js/20.a01dc53f.js"><link rel="prefetch" href="/learn-wgpu/assets/js/21.5e81f33c.js"><link rel="prefetch" href="/learn-wgpu/assets/js/22.caf73498.js"><link rel="prefetch" href="/learn-wgpu/assets/js/23.ddff5db2.js"><link rel="prefetch" href="/learn-wgpu/assets/js/24.9ed2104b.js"><link rel="prefetch" href="/learn-wgpu/assets/js/25.1676676b.js"><link rel="prefetch" href="/learn-wgpu/assets/js/26.01a5696a.js"><link rel="prefetch" href="/learn-wgpu/assets/js/27.3b14c055.js"><link rel="prefetch" href="/learn-wgpu/assets/js/28.d1a4ff6c.js"><link rel="prefetch" href="/learn-wgpu/assets/js/29.ea2d6bbf.js"><link rel="prefetch" href="/learn-wgpu/assets/js/3.80d94795.js"><link rel="prefetch" href="/learn-wgpu/assets/js/30.f08bd92d.js"><link rel="prefetch" href="/learn-wgpu/assets/js/31.fbafea68.js"><link rel="prefetch" href="/learn-wgpu/assets/js/32.3d0e544d.js"><link rel="prefetch" href="/learn-wgpu/assets/js/34.0fe8e5e4.js"><link rel="prefetch" href="/learn-wgpu/assets/js/35.7c607f94.js"><link rel="prefetch" href="/learn-wgpu/assets/js/36.2e1d433e.js"><link rel="prefetch" href="/learn-wgpu/assets/js/38.b0253733.js"><link rel="prefetch" href="/learn-wgpu/assets/js/39.73123b03.js"><link rel="prefetch" href="/learn-wgpu/assets/js/4.ff267fdb.js"><link rel="prefetch" href="/learn-wgpu/assets/js/40.30864a0f.js"><link rel="prefetch" href="/learn-wgpu/assets/js/41.0b7d478f.js"><link rel="prefetch" href="/learn-wgpu/assets/js/42.4caac867.js"><link rel="prefetch" href="/learn-wgpu/assets/js/44.27513d85.js"><link rel="prefetch" href="/learn-wgpu/assets/js/45.2ea5b108.js"><link rel="prefetch" href="/learn-wgpu/assets/js/46.61045c81.js"><link rel="prefetch" href="/learn-wgpu/assets/js/47.ea92b080.js"><link rel="prefetch" href="/learn-wgpu/assets/js/48.cc620f49.js"><link rel="prefetch" href="/learn-wgpu/assets/js/49.6426e080.js"><link rel="prefetch" href="/learn-wgpu/assets/js/5.250d79d3.js"><link rel="prefetch" href="/learn-wgpu/assets/js/50.05fd19ce.js"><link rel="prefetch" href="/learn-wgpu/assets/js/51.47410096.js"><link rel="prefetch" href="/learn-wgpu/assets/js/52.ecbe158e.js"><link rel="prefetch" href="/learn-wgpu/assets/js/53.8c976652.js"><link rel="prefetch" href="/learn-wgpu/assets/js/54.daee63ce.js"><link rel="prefetch" href="/learn-wgpu/assets/js/55.3799ddaa.js"><link rel="prefetch" href="/learn-wgpu/assets/js/56.74e5dcef.js"><link rel="prefetch" href="/learn-wgpu/assets/js/57.9cdfcb79.js"><link rel="prefetch" href="/learn-wgpu/assets/js/58.35b75a7b.js"><link rel="prefetch" href="/learn-wgpu/assets/js/59.5dd82339.js"><link rel="prefetch" href="/learn-wgpu/assets/js/60.1ced8124.js"><link rel="prefetch" href="/learn-wgpu/assets/js/61.f10516d3.js"><link rel="prefetch" href="/learn-wgpu/assets/js/62.fc721fd9.js"><link rel="prefetch" href="/learn-wgpu/assets/js/63.68526f40.js"><link rel="prefetch" href="/learn-wgpu/assets/js/64.b9a310af.js"><link rel="prefetch" href="/learn-wgpu/assets/js/65.e23a076d.js"><link rel="prefetch" href="/learn-wgpu/assets/js/66.19a033d1.js"><link rel="prefetch" href="/learn-wgpu/assets/js/67.ab338058.js"><link rel="prefetch" href="/learn-wgpu/assets/js/68.d785413d.js"><link rel="prefetch" href="/learn-wgpu/assets/js/8.2c0d831a.js"><link rel="prefetch" href="/learn-wgpu/assets/js/9.985bc61a.js"><link rel="prefetch" href="/learn-wgpu/assets/js/vendors~docsearch.efa6f8ef.js">
<link rel="stylesheet" href="/learn-wgpu/assets/css/0.styles.81cb5453.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="inner"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/learn-wgpu/" class="home-link router-link-active"><!----> <span class="site-name">Learn Wgpu</span></a> <div class="links"><!----> <div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div></div></div></header> <div class="sidebar-mask"></div> <div class="docs-layout"><aside class="sidebar"><!----> <ul class="sidebar-links"><li><a href="/learn-wgpu/" aria-current="page" class="sidebar-link">Introduction</a></li><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>Beginner</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/learn-wgpu/beginner/tutorial1-window/" class="sidebar-link">Dependencies and the window</a></li><li><a href="/learn-wgpu/beginner/tutorial2-surface/" class="sidebar-link">The Surface</a></li><li><a href="/learn-wgpu/beginner/tutorial3-pipeline/" class="sidebar-link">The Pipeline</a></li><li><a href="/learn-wgpu/beginner/tutorial4-buffer/" class="sidebar-link">Buffers and Indices</a></li><li><a href="/learn-wgpu/beginner/tutorial5-textures/" class="sidebar-link">Textures and bind groups</a></li><li><a href="/learn-wgpu/beginner/tutorial6-uniforms/" class="sidebar-link">Uniform buffers and a 3d camera</a></li><li><a href="/learn-wgpu/beginner/tutorial7-instancing/" class="sidebar-link">Instancing</a></li><li><a href="/learn-wgpu/beginner/tutorial8-depth/" aria-current="page" class="active sidebar-link">The Depth Buffer</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/learn-wgpu/beginner/tutorial8-depth/#sorting-from-back-to-front" class="sidebar-link">Sorting from back to front</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/beginner/tutorial8-depth/#a-pixels-depth" class="sidebar-link">A pixels depth</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/beginner/tutorial8-depth/#challenge" class="sidebar-link">Challenge</a></li></ul></li><li><a href="/learn-wgpu/beginner/tutorial9-models/" class="sidebar-link">Model Loading</a></li></ul></section></li><li><section class="sidebar-group depth-0"><p class="sidebar-heading"><span>Intermediate</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/learn-wgpu/intermediate/tutorial10-lighting/" class="sidebar-link">Working with Lights</a></li><li><a href="/learn-wgpu/intermediate/tutorial11-normals/" class="sidebar-link">Normal Mapping</a></li><li><a href="/learn-wgpu/intermediate/tutorial12-camera/" class="sidebar-link">A Better Camera</a></li><li><a href="/learn-wgpu/intermediate/tutorial13-hdr/" class="sidebar-link">High Dynamic Range Rendering</a></li></ul></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>Showcase</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>News</span> <span class="arrow right"></span></p> <!----></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="the-depth-buffer"><a href="#the-depth-buffer" class="header-anchor">#</a> The Depth Buffer</h1> <p>Let's take a closer look at the last example at an angle.</p> <p><img src="/learn-wgpu/assets/img/depth_problems.fde54cff.png" alt="depth_problems.png"></p> <p>Models that should be in the back are getting rendered ahead of ones that should be in the front. This is caused by the draw order. By default, pixel data from a new object will replace old pixel data.</p> <p>There are two ways to solve this: sort the data from back to front, or use what's known as a depth buffer.</p> <h2 id="sorting-from-back-to-front"><a href="#sorting-from-back-to-front" class="header-anchor">#</a> Sorting from back to front</h2> <p>This is the go-to method for 2d rendering as it's pretty easy to know what's supposed to go in front of what. You can just use the z order. In 3d rendering, it gets a little trickier because the order of the objects changes based on the camera angle.</p> <p>A simple way of doing this is to sort all the objects by their distance to the camera's position. There are flaws with this method though as when a large object is behind a small object, parts of the large object that should be in front of the small object will be rendered behind it. We'll also run into issues with objects that overlap <em>themselves</em>.</p> <p>If we want to do this properly we need to have pixel-level precision. That's where a <em>depth buffer</em> comes in.</p> <h2 id="a-pixels-depth"><a href="#a-pixels-depth" class="header-anchor">#</a> A pixels depth</h2> <p>A depth buffer is a black and white texture that stores the z-coordinate of rendered pixels. Wgpu can use this when drawing new pixels to determine whether to replace the data or keep it. This technique is called depth testing. This will fix our draw order problem without needing us to sort our objects!</p> <p>Let's make a function to create the depth texture in <code>texture.rs</code>.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">impl</span> <span class="token class-name">Texture</span> <span class="token punctuation">{</span>
<span class="token keyword">pub</span> <span class="token keyword">const</span> <span class="token constant">DEPTH_FORMAT</span><span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">TextureFormat</span> <span class="token operator">=</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">TextureFormat</span><span class="token punctuation">::</span><span class="token class-name">Depth32Float</span><span class="token punctuation">;</span> <span class="token comment">// 1.</span>
<span class="token keyword">pub</span> <span class="token keyword">fn</span> <span class="token function-definition function">create_depth_texture</span><span class="token punctuation">(</span>device<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">Device</span><span class="token punctuation">,</span> config<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">SurfaceConfiguration</span><span class="token punctuation">,</span> label<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token keyword">str</span><span class="token punctuation">)</span> <span class="token punctuation">-&gt;</span> <span class="token keyword">Self</span> <span class="token punctuation">{</span>
<span class="token keyword">let</span> size <span class="token operator">=</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">Extent3d</span> <span class="token punctuation">{</span> <span class="token comment">// 2.</span>
width<span class="token punctuation">:</span> config<span class="token punctuation">.</span>width<span class="token punctuation">,</span>
height<span class="token punctuation">:</span> config<span class="token punctuation">.</span>height<span class="token punctuation">,</span>
depth_or_array_layers<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> desc <span class="token operator">=</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">TextureDescriptor</span> <span class="token punctuation">{</span>
label<span class="token punctuation">:</span> <span class="token class-name">Some</span><span class="token punctuation">(</span>label<span class="token punctuation">)</span><span class="token punctuation">,</span>
size<span class="token punctuation">,</span>
mip_level_count<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
sample_count<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
dimension<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">TextureDimension</span><span class="token punctuation">::</span><span class="token constant">D2</span><span class="token punctuation">,</span>
format<span class="token punctuation">:</span> <span class="token keyword">Self</span><span class="token punctuation">::</span><span class="token constant">DEPTH_FORMAT</span><span class="token punctuation">,</span>
usage<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">TextureUsages</span><span class="token punctuation">::</span><span class="token constant">RENDER_ATTACHMENT</span> <span class="token comment">// 3.</span>
<span class="token operator">|</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">TextureUsages</span><span class="token punctuation">::</span><span class="token constant">TEXTURE_BINDING</span><span class="token punctuation">,</span>
view_formats<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> texture <span class="token operator">=</span> device<span class="token punctuation">.</span><span class="token function">create_texture</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>desc<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> view <span class="token operator">=</span> texture<span class="token punctuation">.</span><span class="token function">create_view</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">TextureViewDescriptor</span><span class="token punctuation">::</span><span class="token function">default</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> sampler <span class="token operator">=</span> device<span class="token punctuation">.</span><span class="token function">create_sampler</span><span class="token punctuation">(</span>
<span class="token operator">&amp;</span><span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">SamplerDescriptor</span> <span class="token punctuation">{</span> <span class="token comment">// 4.</span>
address_mode_u<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">AddressMode</span><span class="token punctuation">::</span><span class="token class-name">ClampToEdge</span><span class="token punctuation">,</span>
address_mode_v<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">AddressMode</span><span class="token punctuation">::</span><span class="token class-name">ClampToEdge</span><span class="token punctuation">,</span>
address_mode_w<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">AddressMode</span><span class="token punctuation">::</span><span class="token class-name">ClampToEdge</span><span class="token punctuation">,</span>
mag_filter<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">FilterMode</span><span class="token punctuation">::</span><span class="token class-name">Linear</span><span class="token punctuation">,</span>
min_filter<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">FilterMode</span><span class="token punctuation">::</span><span class="token class-name">Linear</span><span class="token punctuation">,</span>
mipmap_filter<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">FilterMode</span><span class="token punctuation">::</span><span class="token class-name">Nearest</span><span class="token punctuation">,</span>
compare<span class="token punctuation">:</span> <span class="token class-name">Some</span><span class="token punctuation">(</span><span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">CompareFunction</span><span class="token punctuation">::</span><span class="token class-name">LessEqual</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token comment">// 5.</span>
lod_min_clamp<span class="token punctuation">:</span> <span class="token number">0.0</span><span class="token punctuation">,</span>
lod_max_clamp<span class="token punctuation">:</span> <span class="token number">100.0</span><span class="token punctuation">,</span>
<span class="token punctuation">..</span><span class="token class-name">Default</span><span class="token punctuation">::</span><span class="token function">default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">Self</span> <span class="token punctuation">{</span> texture<span class="token punctuation">,</span> view<span class="token punctuation">,</span> sampler <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><ol><li>We need the DEPTH_FORMAT for when we create the depth stage of the <code>render_pipeline</code> and for creating the depth texture itself.</li> <li>Our depth texture needs to be the same size as our screen if we want things to render correctly. We can use our <code>config</code> to make sure that our depth texture is the same size as our surface textures.</li> <li>Since we are rendering to this texture, we need to add the <code>RENDER_ATTACHMENT</code> flag to it.</li> <li>We technically don't <em>need</em> a sampler for a depth texture, but our <code>Texture</code> struct requires it, and we need one if we ever want to sample it.</li> <li>If we do decide to render our depth texture, we need to use <code>CompareFunction::LessEqual</code>. This is due to how the <code>sampler_comparison</code> and <code>textureSampleCompare()</code> interacts with the <code>texture()</code> function in GLSL.</li></ol> <p>We create our <code>depth_texture</code> in <code>State::new()</code>.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">let</span> depth_texture <span class="token operator">=</span> <span class="token namespace">texture<span class="token punctuation">::</span></span><span class="token class-name">Texture</span><span class="token punctuation">::</span><span class="token function">create_depth_texture</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>device<span class="token punctuation">,</span> <span class="token operator">&amp;</span>config<span class="token punctuation">,</span> <span class="token string">&quot;depth_texture&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>We need to modify our <code>render_pipeline</code> to allow depth testing.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">let</span> render_pipeline <span class="token operator">=</span> device<span class="token punctuation">.</span><span class="token function">create_render_pipeline</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">RenderPipelineDescriptor</span> <span class="token punctuation">{</span>
<span class="token comment">// ...</span>
depth_stencil<span class="token punctuation">:</span> <span class="token class-name">Some</span><span class="token punctuation">(</span><span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">DepthStencilState</span> <span class="token punctuation">{</span>
format<span class="token punctuation">:</span> <span class="token namespace">texture<span class="token punctuation">::</span></span><span class="token class-name">Texture</span><span class="token punctuation">::</span><span class="token constant">DEPTH_FORMAT</span><span class="token punctuation">,</span>
depth_write_enabled<span class="token punctuation">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
depth_compare<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">CompareFunction</span><span class="token punctuation">::</span><span class="token class-name">Less</span><span class="token punctuation">,</span> <span class="token comment">// 1.</span>
stencil<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">StencilState</span><span class="token punctuation">::</span><span class="token function">default</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token comment">// 2.</span>
bias<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">DepthBiasState</span><span class="token punctuation">::</span><span class="token function">default</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token comment">// ...</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><ol><li>The <code>depth_compare</code> function tells us when to discard a new pixel. Using <code>LESS</code> means pixels will be drawn front to back. Here are the other possible values for a <a href="https://docs.rs/wgpu/latest/wgpu/enum.CompareFunction.html" target="_blank" rel="noopener noreferrer">CompareFunction<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> that you can use:</li></ol> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token attribute attr-name">#[repr(C)]</span>
<span class="token attribute attr-name">#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]</span>
<span class="token attribute attr-name">#[cfg_attr(feature = <span class="token string">&quot;serde&quot;</span>, derive(Serialize, Deserialize))]</span>
<span class="token keyword">pub</span> <span class="token keyword">enum</span> <span class="token type-definition class-name">CompareFunction</span> <span class="token punctuation">{</span>
<span class="token class-name">Undefined</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span>
<span class="token class-name">Never</span> <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">,</span>
<span class="token class-name">Less</span> <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">,</span>
<span class="token class-name">Equal</span> <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">,</span>
<span class="token class-name">LessEqual</span> <span class="token operator">=</span> <span class="token number">4</span><span class="token punctuation">,</span>
<span class="token class-name">Greater</span> <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">,</span>
<span class="token class-name">NotEqual</span> <span class="token operator">=</span> <span class="token number">6</span><span class="token punctuation">,</span>
<span class="token class-name">GreaterEqual</span> <span class="token operator">=</span> <span class="token number">7</span><span class="token punctuation">,</span>
<span class="token class-name">Always</span> <span class="token operator">=</span> <span class="token number">8</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
</code></pre></div><ol start="2"><li>There's another type of buffer called a stencil buffer. It's common practice to store the stencil buffer and depth buffer in the same texture. These fields control values for stencil testing. Since we aren't using a stencil buffer, we'll use default values. We'll cover stencil buffers <a href="../../todo">later</a>.</li></ol> <p>Don't forget to store the <code>depth_texture</code> in <code>State</code>.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">struct</span> <span class="token type-definition class-name">State</span> <span class="token punctuation">{</span>
<span class="token comment">// ...</span>
depth_texture<span class="token punctuation">:</span> <span class="token class-name">Texture</span><span class="token punctuation">,</span>
<span class="token comment">// ...</span>
<span class="token punctuation">}</span>
<span class="token keyword">async</span> <span class="token keyword">fn</span> <span class="token function-definition function">new</span><span class="token punctuation">(</span>window<span class="token punctuation">:</span> <span class="token class-name">Window</span><span class="token punctuation">)</span> <span class="token punctuation">-&gt;</span> <span class="token keyword">Self</span> <span class="token punctuation">{</span>
<span class="token comment">// ...</span>
<span class="token keyword">Self</span> <span class="token punctuation">{</span>
<span class="token comment">// ...</span>
depth_texture<span class="token punctuation">,</span>
<span class="token comment">// ...</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>We need to remember to change the <code>resize()</code> method to create a new <code>depth_texture</code> and <code>depth_texture_view</code>.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">fn</span> <span class="token function-definition function">resize</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token keyword">mut</span> <span class="token keyword">self</span><span class="token punctuation">,</span> new_size<span class="token punctuation">:</span> <span class="token namespace">winit<span class="token punctuation">::</span>dpi<span class="token punctuation">::</span></span><span class="token class-name">PhysicalSize</span><span class="token operator">&lt;</span><span class="token keyword">u32</span><span class="token operator">&gt;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// ...</span>
<span class="token keyword">self</span><span class="token punctuation">.</span>depth_texture <span class="token operator">=</span> <span class="token namespace">texture<span class="token punctuation">::</span></span><span class="token class-name">Texture</span><span class="token punctuation">::</span><span class="token function">create_depth_texture</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token keyword">self</span><span class="token punctuation">.</span>device<span class="token punctuation">,</span> <span class="token operator">&amp;</span><span class="token keyword">self</span><span class="token punctuation">.</span>config<span class="token punctuation">,</span> <span class="token string">&quot;depth_texture&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// ...</span>
<span class="token punctuation">}</span>
</code></pre></div><p>Make sure you update the <code>depth_texture</code> <em>after</em> you update <code>config</code>. If you don't, your program will crash as the <code>depth_texture</code> will be a different size than the <code>surface</code> texture.</p> <p>The last change we need to make is in the <code>render()</code> function. We've created the <code>depth_texture</code>, but we're not currently using it. We use it by attaching it to the <code>depth_stencil_attachment</code> of a render pass.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">let</span> <span class="token keyword">mut</span> render_pass <span class="token operator">=</span> encoder<span class="token punctuation">.</span><span class="token function">begin_render_pass</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">RenderPassDescriptor</span> <span class="token punctuation">{</span>
<span class="token comment">// ...</span>
depth_stencil_attachment<span class="token punctuation">:</span> <span class="token class-name">Some</span><span class="token punctuation">(</span><span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">RenderPassDepthStencilAttachment</span> <span class="token punctuation">{</span>
view<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token keyword">self</span><span class="token punctuation">.</span>depth_texture<span class="token punctuation">.</span>view<span class="token punctuation">,</span>
depth_ops<span class="token punctuation">:</span> <span class="token class-name">Some</span><span class="token punctuation">(</span><span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">Operations</span> <span class="token punctuation">{</span>
load<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">LoadOp</span><span class="token punctuation">::</span><span class="token class-name">Clear</span><span class="token punctuation">(</span><span class="token number">1.0</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
store<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">StoreOp</span><span class="token punctuation">::</span><span class="token class-name">Store</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
stencil_ops<span class="token punctuation">:</span> <span class="token class-name">None</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>And that's all we have to do! No shader code needed! If you run the application, the depth issues will be fixed.</p> <p><img src="/learn-wgpu/assets/img/forest_fixed.a77f70f6.png" alt="forest_fixed.png"></p> <h2 id="challenge"><a href="#challenge" class="header-anchor">#</a> Challenge</h2> <p>Since the depth buffer is a texture, we can sample it in the shader. Because it's a depth texture, we'll have to use the <code>sampler_comparison</code> uniform type and the <code>textureSampleCompare</code> function instead of <code>sampler</code>, and <code>sampler2D</code> respectively. Create a bind group for the depth texture (or reuse an existing one), and render it to the screen.</p> <div id="wasm-example"><!----> <button>Try Tutorial8_depth!</button></div> <div class="auto-github-link"><a href="https://github.com/sotrh/learn-wgpu/tree/master/code/beginner/tutorial8-depth/" target="_blank" rel="noopener noreferrer">Check out the code!</a> <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></div></div> <footer class="page-edit"><!----> <div class="last-updated"><span class="prefix">Last Updated: </span> <span class="time">11/27/2023, 10:42:27 PM</span></div></footer> <div class="page-nav"><p class="inner"><span class="prev">
<a href="/learn-wgpu/beginner/tutorial7-instancing/" class="prev">
Instancing
</a></span> <span class="next"><a href="/learn-wgpu/beginner/tutorial9-models/">
Model Loading
</a>
</span></p></div> </main></div></div><div class="global-ui"><!----></div></div>
<script src="/learn-wgpu/assets/js/app.8ee4646c.js" defer></script><script src="/learn-wgpu/assets/js/2.2ef7287a.js" defer></script><script src="/learn-wgpu/assets/js/1.eaeeb819.js" defer></script><script src="/learn-wgpu/assets/js/43.991fa7d2.js" defer></script><script src="/learn-wgpu/assets/js/33.945dce62.js" defer></script><script src="/learn-wgpu/assets/js/37.5ecf7ce2.js" defer></script>
</body>
</html>