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/tutorial4-buffer/index.html

274 lines
98 KiB
HTML

<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Buffers and Indices | 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.842fd276.js" as="script"><link rel="preload" href="/learn-wgpu/assets/js/2.7dc9d716.js" as="script"><link rel="preload" href="/learn-wgpu/assets/js/1.eaeeb819.js" as="script"><link rel="preload" href="/learn-wgpu/assets/js/30.12d50dcb.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.82969053.js"><link rel="prefetch" href="/learn-wgpu/assets/js/11.aa0f7418.js"><link rel="prefetch" href="/learn-wgpu/assets/js/12.c451dcd5.js"><link rel="prefetch" href="/learn-wgpu/assets/js/13.5da78eab.js"><link rel="prefetch" href="/learn-wgpu/assets/js/14.5e01b032.js"><link rel="prefetch" href="/learn-wgpu/assets/js/15.0b975c05.js"><link rel="prefetch" href="/learn-wgpu/assets/js/16.af1799fe.js"><link rel="prefetch" href="/learn-wgpu/assets/js/17.0423b92c.js"><link rel="prefetch" href="/learn-wgpu/assets/js/18.bde3a2c3.js"><link rel="prefetch" href="/learn-wgpu/assets/js/19.e34dfafc.js"><link rel="prefetch" href="/learn-wgpu/assets/js/20.8d8f4a96.js"><link rel="prefetch" href="/learn-wgpu/assets/js/21.56ba867c.js"><link rel="prefetch" href="/learn-wgpu/assets/js/22.44a48b8b.js"><link rel="prefetch" href="/learn-wgpu/assets/js/23.8ac3a76f.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.90f40f03.js"><link rel="prefetch" href="/learn-wgpu/assets/js/27.c755f80e.js"><link rel="prefetch" href="/learn-wgpu/assets/js/28.ca7a4cc7.js"><link rel="prefetch" href="/learn-wgpu/assets/js/29.ea2d6bbf.js"><link rel="prefetch" href="/learn-wgpu/assets/js/3.6221c182.js"><link rel="prefetch" href="/learn-wgpu/assets/js/31.bcaf5c7c.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.275ea4aa.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.9218ac5e.js"><link rel="prefetch" href="/learn-wgpu/assets/js/42.08068df5.js"><link rel="prefetch" href="/learn-wgpu/assets/js/43.ddac8e2c.js"><link rel="prefetch" href="/learn-wgpu/assets/js/44.f7f124ac.js"><link rel="prefetch" href="/learn-wgpu/assets/js/45.2ea5b108.js"><link rel="prefetch" href="/learn-wgpu/assets/js/46.85709c9f.js"><link rel="prefetch" href="/learn-wgpu/assets/js/47.22e16c22.js"><link rel="prefetch" href="/learn-wgpu/assets/js/48.7d70df25.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.e101ca0a.js"><link rel="prefetch" href="/learn-wgpu/assets/js/51.f9c8041f.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.461095bb.js"><link rel="prefetch" href="/learn-wgpu/assets/js/56.74e5dcef.js"><link rel="prefetch" href="/learn-wgpu/assets/js/57.22981293.js"><link rel="prefetch" href="/learn-wgpu/assets/js/58.35b75a7b.js"><link rel="prefetch" href="/learn-wgpu/assets/js/59.302e302d.js"><link rel="prefetch" href="/learn-wgpu/assets/js/60.bca5b731.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.f4cb43e2.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.e648abec.js"><link rel="prefetch" href="/learn-wgpu/assets/js/9.4760ec68.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/" aria-current="page" class="active sidebar-link">Buffers and Indices</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/learn-wgpu/beginner/tutorial4-buffer/#we-re-finally-talking-about-them" class="sidebar-link">We're finally talking about them!</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/beginner/tutorial4-buffer/#what-is-a-buffer" class="sidebar-link">What is a buffer?</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/beginner/tutorial4-buffer/#the-vertex-buffer" class="sidebar-link">The vertex buffer</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/beginner/tutorial4-buffer/#so-what-do-i-do-with-it" class="sidebar-link">So, what do I do with it?</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/beginner/tutorial4-buffer/#the-index-buffer" class="sidebar-link">The index buffer</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/beginner/tutorial4-buffer/#color-correction" class="sidebar-link">Color Correction</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/beginner/tutorial4-buffer/#challenge" class="sidebar-link">Challenge</a></li></ul></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/" class="sidebar-link">The Depth Buffer</a></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="buffers-and-indices"><a href="#buffers-and-indices" class="header-anchor">#</a> Buffers and Indices</h1> <h2 id="we-re-finally-talking-about-them"><a href="#we-re-finally-talking-about-them" class="header-anchor">#</a> We're finally talking about them!</h2> <p>You were probably getting sick of me saying stuff like, &quot;We'll get to that when we talk about buffers&quot;. Well, now's the time to finally talk about buffers, but first...</p> <h2 id="what-is-a-buffer"><a href="#what-is-a-buffer" class="header-anchor">#</a> What is a buffer?</h2> <p>A buffer is a blob of data on the GPU. A buffer is guaranteed to be contiguous, meaning that all the data is stored sequentially in memory. Buffers are generally used to store simple things like structs or arrays, but they can store more complex stuff such as graph structures like trees (provided all the nodes are stored together and don't reference anything outside the buffer). We are going to use buffers a lot, so let's get started with two of the most important ones: the vertex buffer and the index buffer.</p> <h2 id="the-vertex-buffer"><a href="#the-vertex-buffer" class="header-anchor">#</a> The vertex buffer</h2> <p>Previously, we've stored vertex data directly in the vertex shader. While that worked fine to get our bootstraps on, it simply won't do for the long term. The types of objects we need to draw will vary in size, and recompiling the shader whenever we need to update the model would massively slow down our program. Instead, we are going to use buffers to store the vertex data we want to draw. Before we do that, though, we need to describe what a vertex looks like. We'll do this by creating a new struct.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token comment">// lib.rs</span>
<span class="token attribute attr-name">#[repr(C)]</span>
<span class="token attribute attr-name">#[derive(Copy, Clone, Debug)]</span>
<span class="token keyword">struct</span> <span class="token type-definition class-name">Vertex</span> <span class="token punctuation">{</span>
position<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token keyword">f32</span><span class="token punctuation">;</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
color<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token keyword">f32</span><span class="token punctuation">;</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
</code></pre></div><p>Our vertices will all have a position and a color. The position represents the x, y, and z of the vertex in 3d space. The color is the red, green, and blue values for the vertex. We need the <code>Vertex</code> to be <code>Copy</code> so we can create a buffer with it.</p> <p>Next, we need the actual data that will make up our triangle. Below <code>Vertex</code>, add the following.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token comment">// lib.rs</span>
<span class="token keyword">const</span> <span class="token constant">VERTICES</span><span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token punctuation">[</span><span class="token class-name">Vertex</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">&amp;</span><span class="token punctuation">[</span>
<span class="token class-name">Vertex</span> <span class="token punctuation">{</span> position<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">0.0</span><span class="token punctuation">,</span> <span class="token number">0.5</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> color<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">1.0</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token class-name">Vertex</span> <span class="token punctuation">{</span> position<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">0.5</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">0.5</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> color<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">0.0</span><span class="token punctuation">,</span> <span class="token number">1.0</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token class-name">Vertex</span> <span class="token punctuation">{</span> position<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">0.5</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">0.5</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> color<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">0.0</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">,</span> <span class="token number">1.0</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>We arrange the vertices in counter-clockwise order: top, bottom left, bottom right. We do it this way partially out of tradition, but mostly because we specified in the <code>primitive</code> of the <code>render_pipeline</code> that we want the <code>front_face</code> of our triangle to be <code>wgpu::FrontFace::Ccw</code> so that we cull the back face. This means that any triangle that should be facing us should have its vertices in counter-clockwise order.</p> <p>Now that we have our vertex data, we need to store it in a buffer. Let's add a <code>vertex_buffer</code> field to <code>State</code>.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token comment">// lib.rs</span>
<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>
render_pipeline<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">RenderPipeline</span><span class="token punctuation">,</span>
<span class="token comment">// NEW!</span>
vertex_buffer<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">Buffer</span><span class="token punctuation">,</span>
<span class="token comment">// ...</span>
<span class="token punctuation">}</span>
</code></pre></div><p>Now let's create the buffer in <code>new()</code>.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token comment">// new()</span>
<span class="token keyword">let</span> vertex_buffer <span class="token operator">=</span> device<span class="token punctuation">.</span><span class="token function">create_buffer_init</span><span class="token punctuation">(</span>
<span class="token operator">&amp;</span><span class="token namespace">wgpu<span class="token punctuation">::</span>util<span class="token punctuation">::</span></span><span class="token class-name">BufferInitDescriptor</span> <span class="token punctuation">{</span>
label<span class="token punctuation">:</span> <span class="token class-name">Some</span><span class="token punctuation">(</span><span class="token string">&quot;Vertex Buffer&quot;</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
contents<span class="token punctuation">:</span> <span class="token namespace">bytemuck<span class="token punctuation">::</span></span><span class="token function">cast_slice</span><span class="token punctuation">(</span><span class="token constant">VERTICES</span><span class="token punctuation">)</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">BufferUsages</span><span class="token punctuation">::</span><span class="token constant">VERTEX</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>To access the <code>create_buffer_init</code> method on <code>wgpu::Device</code>, we'll have to import the <a href="https://docs.rs/wgpu/latest/wgpu/util/trait.DeviceExt.html#tymethod.create_buffer_init" target="_blank" rel="noopener noreferrer">DeviceExt<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> extension trait. For more information on extension traits, check out <a href="http://xion.io/post/code/rust-extension-traits.html" target="_blank" rel="noopener noreferrer">this article<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>.</p> <p>To import the extension trait, put this line somewhere near the top of <code>lib.rs</code>.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">use</span> <span class="token namespace">wgpu<span class="token punctuation">::</span>util<span class="token punctuation">::</span></span><span class="token class-name">DeviceExt</span><span class="token punctuation">;</span>
</code></pre></div><p>You'll note that we're using <a href="https://docs.rs/bytemuck/latest/bytemuck/" target="_blank" rel="noopener noreferrer">bytemuck<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> to cast our <code>VERTICES</code> as a <code>&amp;[u8]</code>. The <code>create_buffer_init()</code> method expects a <code>&amp;[u8]</code>, and <code>bytemuck::cast_slice</code> does that for us. Add the following to your <code>Cargo.toml</code>.</p> <div class="language-toml extra-class"><pre class="language-toml"><code><span class="token key property">bytemuck</span> <span class="token punctuation">=</span> <span class="token punctuation">{</span> <span class="token key property">version</span> <span class="token punctuation">=</span> <span class="token string">&quot;1.12&quot;</span><span class="token punctuation">,</span> <span class="token key property">features</span> <span class="token punctuation">=</span> <span class="token punctuation">[</span> <span class="token string">&quot;derive&quot;</span> <span class="token punctuation">]</span> <span class="token punctuation">}</span>
</code></pre></div><p>We're also going to need to implement two traits to get <code>bytemuck</code> to work. These are <a href="https://docs.rs/bytemuck/latest/bytemuck/trait.Pod.html" target="_blank" rel="noopener noreferrer">bytemuck::Pod<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> and <a href="https://docs.rs/bytemuck/latest/bytemuck/trait.Zeroable.html" target="_blank" rel="noopener noreferrer">bytemuck::Zeroable<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>. <code>Pod</code> indicates that our <code>Vertex</code> is &quot;Plain Old Data&quot;, and thus can be interpreted as a <code>&amp;[u8]</code>. <code>Zeroable</code> indicates that we can use <code>std::mem::zeroed()</code>. We can modify our <code>Vertex</code> struct to derive these methods.</p> <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, bytemuck::Pod, bytemuck::Zeroable)]</span>
<span class="token keyword">struct</span> <span class="token type-definition class-name">Vertex</span> <span class="token punctuation">{</span>
position<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token keyword">f32</span><span class="token punctuation">;</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
color<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token keyword">f32</span><span class="token punctuation">;</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
</code></pre></div><div class="note"><p>If your struct includes types that don't implement <code>Pod</code> and <code>Zeroable</code>, you'll need to implement these traits manually. These traits don't require us to implement any methods, so we just need to use the following to get our code to work.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">unsafe</span> <span class="token keyword">impl</span> <span class="token namespace">bytemuck<span class="token punctuation">::</span></span><span class="token class-name">Pod</span> <span class="token keyword">for</span> <span class="token class-name">Vertex</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token keyword">unsafe</span> <span class="token keyword">impl</span> <span class="token namespace">bytemuck<span class="token punctuation">::</span></span><span class="token class-name">Zeroable</span> <span class="token keyword">for</span> <span class="token class-name">Vertex</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
</code></pre></div></div> <p>Finally, we can add our <code>vertex_buffer</code> to our <code>State</code> struct.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">Self</span> <span class="token punctuation">{</span>
surface<span class="token punctuation">,</span>
device<span class="token punctuation">,</span>
queue<span class="token punctuation">,</span>
config<span class="token punctuation">,</span>
size<span class="token punctuation">,</span>
render_pipeline<span class="token punctuation">,</span>
vertex_buffer<span class="token punctuation">,</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="so-what-do-i-do-with-it"><a href="#so-what-do-i-do-with-it" class="header-anchor">#</a> So, what do I do with it?</h2> <p>We need to tell the <code>render_pipeline</code> to use this buffer when we are drawing, but first, we need to tell the <code>render_pipeline</code> how to read the buffer. We do this using <code>VertexBufferLayout</code>s and the <code>vertex_buffers</code> field that I promised we'd talk about when we created the <code>render_pipeline</code>.</p> <p>A <code>VertexBufferLayout</code> defines how a buffer is represented in memory. Without this, the render_pipeline has no idea how to map the buffer in the shader. Here's what the descriptor for a buffer full of <code>Vertex</code> would look like.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">VertexBufferLayout</span> <span class="token punctuation">{</span>
array_stride<span class="token punctuation">:</span> <span class="token namespace">std<span class="token punctuation">::</span>mem<span class="token punctuation">::</span></span><span class="token function">size_of</span><span class="token punctuation">::</span><span class="token operator">&lt;</span><span class="token class-name">Vertex</span><span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">as</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">BufferAddress</span><span class="token punctuation">,</span> <span class="token comment">// 1.</span>
step_mode<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">VertexStepMode</span><span class="token punctuation">::</span><span class="token class-name">Vertex</span><span class="token punctuation">,</span> <span class="token comment">// 2.</span>
attributes<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token punctuation">[</span> <span class="token comment">// 3.</span>
<span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">VertexAttribute</span> <span class="token punctuation">{</span>
offset<span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token comment">// 4.</span>
shader_location<span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token comment">// 5.</span>
format<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">VertexFormat</span><span class="token punctuation">::</span><span class="token class-name">Float32x3</span><span class="token punctuation">,</span> <span class="token comment">// 6.</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">VertexAttribute</span> <span class="token punctuation">{</span>
offset<span class="token punctuation">:</span> <span class="token namespace">std<span class="token punctuation">::</span>mem<span class="token punctuation">::</span></span><span class="token function">size_of</span><span class="token punctuation">::</span><span class="token operator">&lt;</span><span class="token punctuation">[</span><span class="token keyword">f32</span><span class="token punctuation">;</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">as</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">BufferAddress</span><span class="token punctuation">,</span>
shader_location<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
format<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">VertexFormat</span><span class="token punctuation">::</span><span class="token class-name">Float32x3</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
<span class="token punctuation">]</span>
<span class="token punctuation">}</span>
</code></pre></div><ol><li>The <code>array_stride</code> defines how wide a vertex is. When the shader goes to read the next vertex, it will skip over the <code>array_stride</code> number of bytes. In our case, array_stride will probably be 24 bytes.</li> <li><code>step_mode</code> tells the pipeline whether each element of the array in this buffer represents per-vertex data or per-instance data. We can specify <code>wgpu::VertexStepMode::Instance</code> if we only want to change vertices when we start drawing a new instance. We'll cover instancing in a later tutorial.</li> <li>Vertex attributes describe the individual parts of the vertex. Generally, this is a 1:1 mapping with a struct's fields, which is true in our case.</li> <li>This defines the <code>offset</code> in bytes until the attribute starts. For the first attribute, the offset is usually zero. For any later attributes, the offset is the sum over <code>size_of</code> of the previous attributes' data.</li> <li>This tells the shader what location to store this attribute at. For example, <code>@location(0) x: vec3&lt;f32&gt;</code> in the vertex shader would correspond to the <code>position</code> field of the <code>Vertex</code> struct, while <code>@location(1) x: vec3&lt;f32&gt;</code> would be the <code>color</code> field.</li> <li><code>format</code> tells the shader the shape of the attribute. <code>Float32x3</code> corresponds to <code>vec3&lt;f32&gt;</code> in shader code. The max value we can store in an attribute is <code>Float32x4</code> (<code>Uint32x4</code>, and <code>Sint32x4</code> work as well). We'll keep this in mind for when we have to store things that are bigger than <code>Float32x4</code>.</li></ol> <p>For you visual learners, our vertex buffer looks like this.</p> <p><img src="/learn-wgpu/assets/img/vb_desc.63afb652.png" alt="A figure of the VertexBufferLayout"></p> <p>Let's create a static method on <code>Vertex</code> that returns this descriptor.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token comment">// lib.rs</span>
<span class="token keyword">impl</span> <span class="token class-name">Vertex</span> <span class="token punctuation">{</span>
<span class="token keyword">fn</span> <span class="token function-definition function">desc</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">-&gt;</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">VertexBufferLayout</span><span class="token operator">&lt;</span><span class="token lifetime-annotation symbol">'static</span><span class="token operator">&gt;</span> <span class="token punctuation">{</span>
<span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">VertexBufferLayout</span> <span class="token punctuation">{</span>
array_stride<span class="token punctuation">:</span> <span class="token namespace">std<span class="token punctuation">::</span>mem<span class="token punctuation">::</span></span><span class="token function">size_of</span><span class="token punctuation">::</span><span class="token operator">&lt;</span><span class="token class-name">Vertex</span><span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">as</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">BufferAddress</span><span class="token punctuation">,</span>
step_mode<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">VertexStepMode</span><span class="token punctuation">::</span><span class="token class-name">Vertex</span><span class="token punctuation">,</span>
attributes<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token punctuation">[</span>
<span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">VertexAttribute</span> <span class="token punctuation">{</span>
offset<span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">,</span>
shader_location<span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">,</span>
format<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">VertexFormat</span><span class="token punctuation">::</span><span class="token class-name">Float32x3</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">VertexAttribute</span> <span class="token punctuation">{</span>
offset<span class="token punctuation">:</span> <span class="token namespace">std<span class="token punctuation">::</span>mem<span class="token punctuation">::</span></span><span class="token function">size_of</span><span class="token punctuation">::</span><span class="token operator">&lt;</span><span class="token punctuation">[</span><span class="token keyword">f32</span><span class="token punctuation">;</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">as</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">BufferAddress</span><span class="token punctuation">,</span>
shader_location<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
format<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">VertexFormat</span><span class="token punctuation">::</span><span class="token class-name">Float32x3</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><div class="note"><p>Specifying the attributes as we did now is quite verbose. We could use the <code>vertex_attr_array</code> macro provided by wgpu to clean things up a bit. With it, our <code>VertexBufferLayout</code> becomes</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">VertexBufferLayout</span> <span class="token punctuation">{</span>
array_stride<span class="token punctuation">:</span> <span class="token namespace">std<span class="token punctuation">::</span>mem<span class="token punctuation">::</span></span><span class="token function">size_of</span><span class="token punctuation">::</span><span class="token operator">&lt;</span><span class="token class-name">Vertex</span><span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">as</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">BufferAddress</span><span class="token punctuation">,</span>
step_mode<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">VertexStepMode</span><span class="token punctuation">::</span><span class="token class-name">Vertex</span><span class="token punctuation">,</span>
attributes<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 macro property">vertex_attr_array!</span><span class="token punctuation">[</span><span class="token number">0</span> <span class="token operator">=&gt;</span> <span class="token class-name">Float32x3</span><span class="token punctuation">,</span> <span class="token number">1</span> <span class="token operator">=&gt;</span> <span class="token class-name">Float32x3</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
</code></pre></div><p>While this is definitely nice, Rust sees the result of <code>vertex_attr_array</code> as a temporary value, so a tweak is required to return it from a function. We could <a href="https://github.com/gfx-rs/wgpu/discussions/1790#discussioncomment-1160378" target="_blank" rel="noopener noreferrer">make it <code>const</code><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>, as in the example below:</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">impl</span> <span class="token class-name">Vertex</span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> <span class="token constant">ATTRIBS</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">VertexAttribute</span><span class="token punctuation">;</span> <span class="token number">2</span><span class="token punctuation">]</span> <span class="token operator">=</span>
<span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token macro property">vertex_attr_array!</span><span class="token punctuation">[</span><span class="token number">0</span> <span class="token operator">=&gt;</span> <span class="token class-name">Float32x3</span><span class="token punctuation">,</span> <span class="token number">1</span> <span class="token operator">=&gt;</span> <span class="token class-name">Float32x3</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">fn</span> <span class="token function-definition function">desc</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">-&gt;</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">VertexBufferLayout</span><span class="token operator">&lt;</span><span class="token lifetime-annotation symbol">'static</span><span class="token operator">&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword">use</span> <span class="token namespace">std<span class="token punctuation">::</span></span>mem<span class="token punctuation">;</span>
<span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">VertexBufferLayout</span> <span class="token punctuation">{</span>
array_stride<span class="token punctuation">:</span> <span class="token namespace">mem<span class="token punctuation">::</span></span><span class="token function">size_of</span><span class="token punctuation">::</span><span class="token operator">&lt;</span><span class="token keyword">Self</span><span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">as</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">BufferAddress</span><span class="token punctuation">,</span>
step_mode<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">VertexStepMode</span><span class="token punctuation">::</span><span class="token class-name">Vertex</span><span class="token punctuation">,</span>
attributes<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token keyword">Self</span><span class="token punctuation">::</span><span class="token constant">ATTRIBS</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>Regardless, I feel it's good to show how the data gets mapped, so I'll forgo using this macro for now.</p></div> <p>Now, we can use it when we create the <code>render_pipeline</code>.</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>
vertex<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">VertexState</span> <span class="token punctuation">{</span>
<span class="token comment">// ...</span>
buffers<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token punctuation">[</span>
<span class="token class-name">Vertex</span><span class="token punctuation">::</span><span class="token function">desc</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>
<span class="token comment">// ...</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>One more thing: we need to actually set the vertex buffer in the render method. Otherwise, our program will crash.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token comment">// render()</span>
render_pass<span class="token punctuation">.</span><span class="token function">set_pipeline</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token keyword">self</span><span class="token punctuation">.</span>render_pipeline<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// NEW!</span>
render_pass<span class="token punctuation">.</span><span class="token function">set_vertex_buffer</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">self</span><span class="token punctuation">.</span>vertex_buffer<span class="token punctuation">.</span><span class="token function">slice</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>
render_pass<span class="token punctuation">.</span><span class="token function">draw</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">..</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">..</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p><code>set_vertex_buffer</code> takes two parameters. The first is what buffer slot to use for this vertex buffer. You can have multiple vertex buffers set at a time.</p> <p>The second parameter is the slice of the buffer to use. You can store as many objects in a buffer as your hardware allows, so <code>slice</code> allows us to specify which portion of the buffer to use. We use <code>..</code> to specify the entire buffer.</p> <p>Before we continue, we should change the <code>render_pass.draw()</code> call to use the number of vertices specified by <code>VERTICES</code>. Add a <code>num_vertices</code> to <code>State</code>, and set it to be equal to <code>VERTICES.len()</code>.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token comment">// lib.rs</span>
<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>
num_vertices<span class="token punctuation">:</span> <span class="token keyword">u32</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
<span class="token keyword">impl</span> <span class="token class-name">State</span> <span class="token punctuation">{</span>
<span class="token comment">// ...</span>
<span class="token keyword">fn</span> <span class="token function-definition function">new</span><span class="token punctuation">(</span><span class="token punctuation">...</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">let</span> num_vertices <span class="token operator">=</span> <span class="token constant">VERTICES</span><span class="token punctuation">.</span><span class="token function">len</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">as</span> <span class="token keyword">u32</span><span class="token punctuation">;</span>
<span class="token keyword">Self</span> <span class="token punctuation">{</span>
surface<span class="token punctuation">,</span>
device<span class="token punctuation">,</span>
queue<span class="token punctuation">,</span>
config<span class="token punctuation">,</span>
render_pipeline<span class="token punctuation">,</span>
vertex_buffer<span class="token punctuation">,</span>
num_vertices<span class="token punctuation">,</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>Then, use it in the draw call.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token comment">// render</span>
render_pass<span class="token punctuation">.</span><span class="token function">draw</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">..</span><span class="token keyword">self</span><span class="token punctuation">.</span>num_vertices<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">..</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>Before our changes will have any effect, we need to update our vertex shader to get its data from the vertex buffer. We'll also have it include the vertex color as well.</p> <div class="language-wgsl extra-class"><pre class="language-wgsl"><code><span class="token comment">// Vertex shader</span>
<span class="token keyword">struct</span> <span class="token class-name">VertexInput</span> <span class="token punctuation">{</span>
<span class="token punctuation">@</span><span class="token attributes attr-name">location</span><span class="token punctuation">(</span><span class="token int-literal number">0</span><span class="token punctuation">)</span> position<span class="token punctuation">:</span> <span class="token builtin">vec3</span><span class="token punctuation">&lt;</span><span class="token builtin">f32</span><span class="token punctuation">&gt;</span><span class="token punctuation">,</span>
<span class="token punctuation">@</span><span class="token attributes attr-name">location</span><span class="token punctuation">(</span><span class="token int-literal number">1</span><span class="token punctuation">)</span> color<span class="token punctuation">:</span> <span class="token builtin">vec3</span><span class="token punctuation">&lt;</span><span class="token builtin">f32</span><span class="token punctuation">&gt;</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">struct</span> <span class="token class-name">VertexOutput</span> <span class="token punctuation">{</span>
<span class="token punctuation">@</span><span class="token builtin-attribute"><span class="token attribute attr-name">builtin</span><span class="token punctuation">(</span><span class="token built-in-values attr-value">position</span><span class="token punctuation">)</span></span> clip_position<span class="token punctuation">:</span> <span class="token builtin">vec4</span><span class="token punctuation">&lt;</span><span class="token builtin">f32</span><span class="token punctuation">&gt;</span><span class="token punctuation">,</span>
<span class="token punctuation">@</span><span class="token attributes attr-name">location</span><span class="token punctuation">(</span><span class="token int-literal number">0</span><span class="token punctuation">)</span> color<span class="token punctuation">:</span> <span class="token builtin">vec3</span><span class="token punctuation">&lt;</span><span class="token builtin">f32</span><span class="token punctuation">&gt;</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">@</span><span class="token attributes attr-name">vertex</span>
<span class="token keyword">fn</span> <span class="token functions function">vs_main</span><span class="token punctuation">(</span>
model<span class="token punctuation">:</span> <span class="token class-name">VertexInput</span><span class="token punctuation">,</span>
<span class="token punctuation">)</span> <span class="token operator">-&gt;</span> <span class="token class-name">VertexOutput</span> <span class="token punctuation">{</span>
<span class="token keyword">var</span> out<span class="token punctuation">:</span> <span class="token class-name">VertexOutput</span><span class="token punctuation">;</span>
out<span class="token punctuation">.</span>color <span class="token operator">=</span> model<span class="token punctuation">.</span>color<span class="token punctuation">;</span>
out<span class="token punctuation">.</span>clip_position <span class="token operator">=</span> <span class="token builtin">vec4</span><span class="token punctuation">&lt;</span><span class="token builtin">f32</span><span class="token punctuation">&gt;</span><span class="token punctuation">(</span>model<span class="token punctuation">.</span>position<span class="token punctuation">,</span> <span class="token decimal-float-literal number">1.0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> out<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// Fragment shader</span>
<span class="token punctuation">@</span><span class="token attributes attr-name">fragment</span>
<span class="token keyword">fn</span> <span class="token functions function">fs_main</span><span class="token punctuation">(</span>in<span class="token punctuation">:</span> <span class="token class-name">VertexOutput</span><span class="token punctuation">)</span> <span class="token operator">-&gt;</span> <span class="token punctuation">@</span><span class="token attributes attr-name">location</span><span class="token punctuation">(</span><span class="token int-literal number">0</span><span class="token punctuation">)</span> <span class="token builtin">vec4</span><span class="token punctuation">&lt;</span><span class="token builtin">f32</span><span class="token punctuation">&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token builtin">vec4</span><span class="token punctuation">&lt;</span><span class="token builtin">f32</span><span class="token punctuation">&gt;</span><span class="token punctuation">(</span>in<span class="token punctuation">.</span>color<span class="token punctuation">,</span> <span class="token decimal-float-literal number">1.0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>If you've done things correctly, you should see a triangle that looks something like this.</p> <p><img src="/learn-wgpu/assets/img/triangle.11560f32.png" alt="A colorful triangle"></p> <h2 id="the-index-buffer"><a href="#the-index-buffer" class="header-anchor">#</a> The index buffer</h2> <p>We technically don't <em>need</em> an index buffer, but they still are plenty useful. An index buffer comes into play when we start using models with a lot of triangles. Consider this pentagon.</p> <p><img src="/learn-wgpu/assets/img/pentagon.2c2be93b.png" alt="A pentagon made of 3 triangles"></p> <p>It has a total of 5 vertices and 3 triangles. Now, if we wanted to display something like this using just vertices, we would need something like the following.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">const</span> <span class="token constant">VERTICES</span><span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token punctuation">[</span><span class="token class-name">Vertex</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">&amp;</span><span class="token punctuation">[</span>
<span class="token class-name">Vertex</span> <span class="token punctuation">{</span> position<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">0.0868241</span><span class="token punctuation">,</span> <span class="token number">0.49240386</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> color<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">0.5</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">,</span> <span class="token number">0.5</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment">// A</span>
<span class="token class-name">Vertex</span> <span class="token punctuation">{</span> position<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">0.49513406</span><span class="token punctuation">,</span> <span class="token number">0.06958647</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> color<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">0.5</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">,</span> <span class="token number">0.5</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment">// B</span>
<span class="token class-name">Vertex</span> <span class="token punctuation">{</span> position<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">0.44147372</span><span class="token punctuation">,</span> <span class="token number">0.2347359</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> color<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">0.5</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">,</span> <span class="token number">0.5</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment">// E</span>
<span class="token class-name">Vertex</span> <span class="token punctuation">{</span> position<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">0.49513406</span><span class="token punctuation">,</span> <span class="token number">0.06958647</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> color<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">0.5</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">,</span> <span class="token number">0.5</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment">// B</span>
<span class="token class-name">Vertex</span> <span class="token punctuation">{</span> position<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">0.21918549</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">0.44939706</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> color<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">0.5</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">,</span> <span class="token number">0.5</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment">// C</span>
<span class="token class-name">Vertex</span> <span class="token punctuation">{</span> position<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">0.44147372</span><span class="token punctuation">,</span> <span class="token number">0.2347359</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> color<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">0.5</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">,</span> <span class="token number">0.5</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment">// E</span>
<span class="token class-name">Vertex</span> <span class="token punctuation">{</span> position<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">0.21918549</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">0.44939706</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> color<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">0.5</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">,</span> <span class="token number">0.5</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment">// C</span>
<span class="token class-name">Vertex</span> <span class="token punctuation">{</span> position<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">0.35966998</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">0.3473291</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> color<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">0.5</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">,</span> <span class="token number">0.5</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment">// D</span>
<span class="token class-name">Vertex</span> <span class="token punctuation">{</span> position<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">0.44147372</span><span class="token punctuation">,</span> <span class="token number">0.2347359</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> color<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">0.5</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">,</span> <span class="token number">0.5</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment">// E</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span>
</code></pre></div><p>You'll note, though, that some of the vertices are used more than once. C and B are used twice, and E is repeated three times. Assuming that each float is 4 bytes, then that means of the 216 bytes we use for <code>VERTICES</code>, 96 of them are duplicate data. Wouldn't it be nice if we could list these vertices once? Well, we can! That's where an index buffer comes into play.</p> <p>Basically, we store all the unique vertices in <code>VERTICES</code>, and we create another buffer that stores indices to elements in <code>VERTICES</code> to create the triangles. Here's an example of that with our pentagon.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token comment">// lib.rs</span>
<span class="token keyword">const</span> <span class="token constant">VERTICES</span><span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token punctuation">[</span><span class="token class-name">Vertex</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">&amp;</span><span class="token punctuation">[</span>
<span class="token class-name">Vertex</span> <span class="token punctuation">{</span> position<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">0.0868241</span><span class="token punctuation">,</span> <span class="token number">0.49240386</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> color<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">0.5</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">,</span> <span class="token number">0.5</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment">// A</span>
<span class="token class-name">Vertex</span> <span class="token punctuation">{</span> position<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">0.49513406</span><span class="token punctuation">,</span> <span class="token number">0.06958647</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> color<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">0.5</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">,</span> <span class="token number">0.5</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment">// B</span>
<span class="token class-name">Vertex</span> <span class="token punctuation">{</span> position<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">0.21918549</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">0.44939706</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> color<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">0.5</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">,</span> <span class="token number">0.5</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment">// C</span>
<span class="token class-name">Vertex</span> <span class="token punctuation">{</span> position<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">0.35966998</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">0.3473291</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> color<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">0.5</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">,</span> <span class="token number">0.5</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment">// D</span>
<span class="token class-name">Vertex</span> <span class="token punctuation">{</span> position<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">0.44147372</span><span class="token punctuation">,</span> <span class="token number">0.2347359</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> color<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">0.5</span><span class="token punctuation">,</span> <span class="token number">0.0</span><span class="token punctuation">,</span> <span class="token number">0.5</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token comment">// E</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> <span class="token constant">INDICES</span><span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token punctuation">[</span><span class="token keyword">u16</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">&amp;</span><span class="token punctuation">[</span>
<span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span>
<span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span>
<span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">;</span>
</code></pre></div><p>Now, with this setup, our <code>VERTICES</code> take up about 120 bytes and <code>INDICES</code> is just 18 bytes, given that <code>u16</code> is 2 bytes wide. In this case, wgpu automatically adds 2 extra bytes of padding to make sure the buffer is aligned to 4 bytes, but it's still just 20 bytes. Altogether, our pentagon is 140 bytes in total. That means we saved 76 bytes! It may not seem like much, but when dealing with tri counts in the hundreds of thousands, indexing saves a lot of memory.</p> <p>There are a couple of things we need to change in order to use indexing. The first is we need to create a buffer to store the indices. In <code>State</code>'s <code>new()</code> method, create the <code>index_buffer</code> after you create the <code>vertex_buffer</code>. Also, change <code>num_vertices</code> to <code>num_indices</code> and set it equal to <code>INDICES.len()</code>.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">let</span> vertex_buffer <span class="token operator">=</span> device<span class="token punctuation">.</span><span class="token function">create_buffer_init</span><span class="token punctuation">(</span>
<span class="token operator">&amp;</span><span class="token namespace">wgpu<span class="token punctuation">::</span>util<span class="token punctuation">::</span></span><span class="token class-name">BufferInitDescriptor</span> <span class="token punctuation">{</span>
label<span class="token punctuation">:</span> <span class="token class-name">Some</span><span class="token punctuation">(</span><span class="token string">&quot;Vertex Buffer&quot;</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
contents<span class="token punctuation">:</span> <span class="token namespace">bytemuck<span class="token punctuation">::</span></span><span class="token function">cast_slice</span><span class="token punctuation">(</span><span class="token constant">VERTICES</span><span class="token punctuation">)</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">BufferUsages</span><span class="token punctuation">::</span><span class="token constant">VERTEX</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">// NEW!</span>
<span class="token keyword">let</span> index_buffer <span class="token operator">=</span> device<span class="token punctuation">.</span><span class="token function">create_buffer_init</span><span class="token punctuation">(</span>
<span class="token operator">&amp;</span><span class="token namespace">wgpu<span class="token punctuation">::</span>util<span class="token punctuation">::</span></span><span class="token class-name">BufferInitDescriptor</span> <span class="token punctuation">{</span>
label<span class="token punctuation">:</span> <span class="token class-name">Some</span><span class="token punctuation">(</span><span class="token string">&quot;Index Buffer&quot;</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
contents<span class="token punctuation">:</span> <span class="token namespace">bytemuck<span class="token punctuation">::</span></span><span class="token function">cast_slice</span><span class="token punctuation">(</span><span class="token constant">INDICES</span><span class="token punctuation">)</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">BufferUsages</span><span class="token punctuation">::</span><span class="token constant">INDEX</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> num_indices <span class="token operator">=</span> <span class="token constant">INDICES</span><span class="token punctuation">.</span><span class="token function">len</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">as</span> <span class="token keyword">u32</span><span class="token punctuation">;</span>
</code></pre></div><p>We don't need to implement <code>Pod</code> and <code>Zeroable</code> for our indices because <code>bytemuck</code> has already implemented them for basic types such as <code>u16</code>. That means we can just add <code>index_buffer</code> and <code>num_indices</code> to the <code>State</code> struct.</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>
surface<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">Surface</span><span class="token punctuation">,</span>
device<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">Device</span><span class="token punctuation">,</span>
queue<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">Queue</span><span class="token punctuation">,</span>
config<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">SurfaceConfiguration</span><span class="token punctuation">,</span>
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>
render_pipeline<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">RenderPipeline</span><span class="token punctuation">,</span>
vertex_buffer<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">Buffer</span><span class="token punctuation">,</span>
<span class="token comment">// NEW!</span>
index_buffer<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">Buffer</span><span class="token punctuation">,</span>
num_indices<span class="token punctuation">:</span> <span class="token keyword">u32</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
</code></pre></div><p>And then populate these fields in the constructor:</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">Self</span> <span class="token punctuation">{</span>
surface<span class="token punctuation">,</span>
device<span class="token punctuation">,</span>
queue<span class="token punctuation">,</span>
config<span class="token punctuation">,</span>
size<span class="token punctuation">,</span>
render_pipeline<span class="token punctuation">,</span>
vertex_buffer<span class="token punctuation">,</span>
<span class="token comment">// NEW!</span>
index_buffer<span class="token punctuation">,</span>
num_indices<span class="token punctuation">,</span>
<span class="token punctuation">}</span>
</code></pre></div><p>All we have to do now is update the <code>render()</code> method to use the <code>index_buffer</code>.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token comment">// render()</span>
render_pass<span class="token punctuation">.</span><span class="token function">set_pipeline</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token keyword">self</span><span class="token punctuation">.</span>render_pipeline<span class="token punctuation">)</span><span class="token punctuation">;</span>
render_pass<span class="token punctuation">.</span><span class="token function">set_vertex_buffer</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">self</span><span class="token punctuation">.</span>vertex_buffer<span class="token punctuation">.</span><span class="token function">slice</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>
render_pass<span class="token punctuation">.</span><span class="token function">set_index_buffer</span><span class="token punctuation">(</span><span class="token keyword">self</span><span class="token punctuation">.</span>index_buffer<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token punctuation">..</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">IndexFormat</span><span class="token punctuation">::</span><span class="token class-name">Uint16</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 1.</span>
render_pass<span class="token punctuation">.</span><span class="token function">draw_indexed</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">..</span><span class="token keyword">self</span><span class="token punctuation">.</span>num_indices<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">..</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2.</span>
</code></pre></div><p>A couple of things to note:</p> <ol><li>The method name is <code>set_index_buffer</code>, not <code>set_index_buffers</code>. You can only have one index buffer set at a time.</li> <li>When using an index buffer, you need to use <code>draw_indexed</code>. The <code>draw</code> method ignores the index buffer. Also, make sure you use the number of indices (<code>num_indices</code>), not vertices, as your model will either draw wrong or the method will <code>panic</code> because there are not enough indices.</li></ol> <p>With all that you should have a garishly magenta pentagon in your window.</p> <p><img src="data:image/png;base64,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EAEqzVSkP4QGAP0mRIDKEyOLIzYAGCQhAlBTQgOAMhMiQC00dSoiNgCoKiEC1EYdY0RoAFBXQgSolSrGiNgAoImECECfCQ0AuJIQAWoneyoiNABg4YQIUEu9jhGxAQC9JUQAQmgAQDYhAtTW5VMRsQEA5SFEgFoTHwBQTu1BLwAAAGgeIQIAAKQTIgAAQDohAgAApBMiAABAOiECAACkEyIAAEA6IQIAAKQTIgAAQDohAgAApBMiAABAOiECAACkEyIAAEA6IQIAAKQTIgAAQDohAgAApBMiAABAOiECAACkEyIAAEA6IQIAAKQTIgAAQDohAgAApBMiAABAOiECAACkEyIAAEA6IQIAAKQTIgAAQDohAgAApBMiAABAOiECAACkEyIAAEA6IQIAAKQTIgAAQDohAgAApBMiAABAOiECAACkEyIAAEA6IQIAAKQTIgAAQDohAgAApBMiAABAOiECAACkEyIAAEA6IQIAAKQTIgAAQDohAgAApBMiAABAOiECAACkEyIAAEA6IQIAAKQTIgAAQDohAgAApBMiAABAOiECAACkEyIAAEA6IQIAAKQTIgAAQDohAgAApBMiAABAOiECAACkEyIAAEA6IQIAAKQTIgAAQDohAgAApBMiAABAOiECAACkEyIAAEA6IQIAAKQTIgAAQDohAgAApBMiAABAOiECAACkEyIAAEA6IQIAAKQTIgAAQDohAgAApBMiAABAOiECAACkEyIAAEA6IQIAAKQTIgAAQDohAgAApBMiAABAOiECAACkEyIAAEA6IQIAAKQTIgAAQDohAgAApBMiAABAOiECAACkEyIAAEA6IQIAAKQTIgAAQDohAgAApBMiAABAOiECAACkEyIAAEA6IQIAAKQTIgAAQDohAgAApBMiAABAOiECAACkEyIAAEA6IQIAAKQTIgAAQDohAgAApBMiAABAOiECAACkEyIAAEA6IQIAAKQTIgAAQDohAgAApBMiAABAOiECAACkEyIAAEA6IQIAAKQTIgAAQDohAgAApBMiAABAOiECAACkEyIAAEA6IQIAAKQTIgAAQDohAgAApBMiAABAOiECAACkEyIAAEA6IQIAAKQTIgAAQDohAgAApBMiAABAOiECAACkEyIAAEA6IQIAAKQTIgAAQDohAgAApBMiAABAOiECAACkEyIAAEA6IQIAAKQTIgAAQDohAgAApBMiAABAOiECAACkEyIAAEA6IQIAAKQTIgAAQDohAgAApBMiAABAOiECAACkEyIAAEA6IQIAAKQTIgAAQDohAgAApBMiAABAOiECAACkEyIAAEA6IQIAAKQTIgAAQDohAgAApBMiAABAOiECAACkEyIAAEA6IQIAAKQbjoh4ZH1r0OsAAAAa5P8D75CpLfCP/NcAAAAASUVORK5CYII=" alt="Magenta pentagon in window"></p> <h2 id="color-correction"><a href="#color-correction" class="header-anchor">#</a> Color Correction</h2> <p>If you use a color picker on the magenta pentagon, you'll get a hex value of #BC00BC. If you convert this to RGB values, you'll get (188, 0, 188). Dividing these values by 255 to get them into the [0, 1] range, we get roughly (0.737254902, 0, 0.737254902). This is not the same as what we are using for our vertex colors, which is (0.5, 0.0, 0.5). The reason for this has to do with color spaces.</p> <p>Most monitors use a color space known as sRGB. Our surface is (most likely depending on what is returned from <code>surface.get_preferred_format()</code>) using an sRGB texture format. The sRGB format stores colors according to their relative brightness instead of their actual brightness. The reason for this is that our eyes don't perceive light linearly. We notice more differences in darker colors than in lighter colors.</p> <p>You get the correct color using the following formula: <code>srgb_color = ((rgb_color / 255 + 0.055) / 1.055) ^ 2.4</code>. Doing this with an RGB value of (188, 0, 188) will give us (0.5028864580325687, 0.0, 0.5028864580325687). A little off from our (0.5, 0.0, 0.5). Instead of doing a manual color conversion, you'll likely save a lot of time by using textures instead, as they are stored as sRGB by default, so they don't suffer from the same color inaccuracies that vertex colors do. We'll cover textures in the next lesson.</p> <h2 id="challenge"><a href="#challenge" class="header-anchor">#</a> Challenge</h2> <p>Create a more complex shape than the one we made (aka. more than three triangles) using a vertex buffer and an index buffer. Toggle between the two with the space key.</p> <div id="wasm-example"><!----> <button>Try Tutorial4_buffer!</button></div> <div class="auto-github-link"><a href="https://github.com/sotrh/learn-wgpu/tree/master/code/beginner/tutorial4-buffer/" 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">12/1/2023, 2:10:48 AM</span></div></footer> <div class="page-nav"><p class="inner"><span class="prev">
<a href="/learn-wgpu/beginner/tutorial3-pipeline/" class="prev">
The Pipeline
</a></span> <span class="next"><a href="/learn-wgpu/beginner/tutorial5-textures/">
Textures and bind groups
</a>
</span></p></div> </main></div></div><div class="global-ui"><!----></div></div>
<script src="/learn-wgpu/assets/js/app.842fd276.js" defer></script><script src="/learn-wgpu/assets/js/2.7dc9d716.js" defer></script><script src="/learn-wgpu/assets/js/1.eaeeb819.js" defer></script><script src="/learn-wgpu/assets/js/30.12d50dcb.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>