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/showcase/threading/index.html

109 lines
34 KiB
HTML

<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Multi-threading with Wgpu and Rayon | 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.9afc5d83.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/66.a136cd48.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.5ef2ce85.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.60954390.js"><link rel="prefetch" href="/learn-wgpu/assets/js/27.ba9ff2c4.js"><link rel="prefetch" href="/learn-wgpu/assets/js/28.d9dcc3ca.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.74bc1dea.js"><link rel="prefetch" href="/learn-wgpu/assets/js/32.e6627282.js"><link rel="prefetch" href="/learn-wgpu/assets/js/33.c548d7f9.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.6e9002ae.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.b9820613.js"><link rel="prefetch" href="/learn-wgpu/assets/js/42.4caac867.js"><link rel="prefetch" href="/learn-wgpu/assets/js/43.991fa7d2.js"><link rel="prefetch" href="/learn-wgpu/assets/js/44.89508e56.js"><link rel="prefetch" href="/learn-wgpu/assets/js/45.2ea5b108.js"><link rel="prefetch" href="/learn-wgpu/assets/js/46.bb26f2fc.js"><link rel="prefetch" href="/learn-wgpu/assets/js/47.52c91180.js"><link rel="prefetch" href="/learn-wgpu/assets/js/48.7d70df25.js"><link rel="prefetch" href="/learn-wgpu/assets/js/49.e307b357.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.820d6108.js"><link rel="prefetch" href="/learn-wgpu/assets/js/52.09f16d08.js"><link rel="prefetch" href="/learn-wgpu/assets/js/53.53394024.js"><link rel="prefetch" href="/learn-wgpu/assets/js/54.daee63ce.js"><link rel="prefetch" href="/learn-wgpu/assets/js/55.79d255a9.js"><link rel="prefetch" href="/learn-wgpu/assets/js/56.e9c45fb7.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.5fd53e01.js"><link rel="prefetch" href="/learn-wgpu/assets/js/65.5151244c.js"><link rel="prefetch" href="/learn-wgpu/assets/js/67.cf780dc9.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"><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/" 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="multi-threading-with-wgpu-and-rayon"><a href="#multi-threading-with-wgpu-and-rayon" class="header-anchor">#</a> Multi-threading with Wgpu and Rayon</h1> <div class="warn"><p>This example has not been tested on WASM. Rayon has support for multi threading on WASM via <a href="https://docs.rs/crate/wasm-bindgen-rayon/latest" target="_blank" rel="noopener noreferrer">wasm-bindgen-rayon<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>, though that implementation is only currently working on Chrome-based browsers. Because of this I've elected not to make a WASM version of this tutorial at this time.</p></div> <p>The main selling point of Vulkan, DirectX 12, Metal, and by extension Wgpu is that these APIs is that they designed from the ground up to be thread safe. Up to this point, we have been doing everything on a single thread. That's about to change.</p> <div class="note"><p>This example is based on the code for <a href="../intermediate/tutorial12-camera">tutorial12-camera</a></p></div> <div class="note"><p>I won't go into what threads are in this tutorial. That is a full CS course in and of itself. All we'll be covering is using threading to make loading resources faster.</p> <p>We won't go over multithreading rendering as we don't have enough different types of objects to justify that yet. This will change in a coming tutorial</p></div> <h2 id="parallelizing-loading-models-and-textures"><a href="#parallelizing-loading-models-and-textures" class="header-anchor">#</a> Parallelizing loading models and textures</h2> <p>Currently, we load the materials and meshes of our model one at a time. This is a perfect opportunity for multithreading! All our changes will be in <code>model.rs</code>. Let's first start with the materials. We'll convert the regular for loop into a <code>par_iter().map()</code>.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token comment">// resources.rs</span>
<span class="token attribute attr-name">#[cfg(not(target_arch=<span class="token string">&quot;wasm32&quot;</span>))]</span>
<span class="token keyword">use</span> <span class="token namespace">rayon<span class="token punctuation">::</span>iter<span class="token punctuation">::</span></span><span class="token class-name">IntoParallelIterator</span><span class="token punctuation">;</span>
<span class="token keyword">impl</span> <span class="token class-name">Model</span> <span class="token punctuation">{</span>
<span class="token keyword">pub</span> <span class="token keyword">fn</span> <span class="token function-definition function">load</span><span class="token operator">&lt;</span><span class="token class-name">P</span><span class="token punctuation">:</span> <span class="token class-name">AsRef</span><span class="token operator">&lt;</span><span class="token class-name">Path</span><span class="token operator">&gt;&gt;</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>
queue<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">Queue</span><span class="token punctuation">,</span>
layout<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">BindGroupLayout</span><span class="token punctuation">,</span>
path<span class="token punctuation">:</span> <span class="token class-name">P</span><span class="token punctuation">,</span>
<span class="token punctuation">)</span> <span class="token punctuation">-&gt;</span> <span class="token class-name">Result</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 comment">// ...</span>
<span class="token comment">// UPDATED!</span>
<span class="token keyword">let</span> materials <span class="token operator">=</span> obj_materials<span class="token punctuation">.</span><span class="token function">par_iter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token closure-params"><span class="token closure-punctuation punctuation">|</span>mat<span class="token closure-punctuation punctuation">|</span></span> <span class="token punctuation">{</span>
<span class="token comment">// We can also parallelize loading the textures!</span>
<span class="token keyword">let</span> <span class="token keyword">mut</span> textures <span class="token operator">=</span> <span class="token punctuation">[</span>
<span class="token punctuation">(</span>containing_folder<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>mat<span class="token punctuation">.</span>diffuse_texture<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">(</span>containing_folder<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>mat<span class="token punctuation">.</span>normal_texture<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">par_iter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token closure-params"><span class="token closure-punctuation punctuation">|</span><span class="token punctuation">(</span>texture_path<span class="token punctuation">,</span> is_normal_map<span class="token punctuation">)</span><span class="token closure-punctuation punctuation">|</span></span> <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 function">load</span><span class="token punctuation">(</span>device<span class="token punctuation">,</span> queue<span class="token punctuation">,</span> texture_path<span class="token punctuation">,</span> <span class="token operator">*</span>is_normal_map<span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">collect</span><span class="token punctuation">::</span><span class="token operator">&lt;</span><span class="token class-name">Result</span><span class="token operator">&lt;</span><span class="token class-name">Vec</span><span class="token operator">&lt;</span>_<span class="token operator">&gt;&gt;</span><span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">?</span><span class="token punctuation">;</span>
<span class="token comment">// Pop removes from the end of the list.</span>
<span class="token keyword">let</span> normal_texture <span class="token operator">=</span> textures<span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">unwrap</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> diffuse_texture <span class="token operator">=</span> textures<span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">unwrap</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token class-name">Ok</span><span class="token punctuation">(</span><span class="token class-name">Material</span><span class="token punctuation">::</span><span class="token function">new</span><span class="token punctuation">(</span>
device<span class="token punctuation">,</span>
<span class="token operator">&amp;</span>mat<span class="token punctuation">.</span>name<span class="token punctuation">,</span>
diffuse_texture<span class="token punctuation">,</span>
normal_texture<span class="token punctuation">,</span>
layout<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 function">collect</span><span class="token punctuation">::</span><span class="token operator">&lt;</span><span class="token class-name">Result</span><span class="token operator">&lt;</span><span class="token class-name">Vec</span><span class="token operator">&lt;</span><span class="token class-name">Material</span><span class="token operator">&gt;&gt;</span><span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">?</span><span class="token punctuation">;</span>
<span class="token comment">// ...</span>
<span class="token punctuation">}</span>
<span class="token comment">// ...</span>
<span class="token punctuation">}</span>
</code></pre></div><p>Next, we can update the meshes to be loaded in parallel.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">impl</span> <span class="token class-name">Model</span> <span class="token punctuation">{</span>
<span class="token keyword">pub</span> <span class="token keyword">fn</span> <span class="token function-definition function">load</span><span class="token operator">&lt;</span><span class="token class-name">P</span><span class="token punctuation">:</span> <span class="token class-name">AsRef</span><span class="token operator">&lt;</span><span class="token class-name">Path</span><span class="token operator">&gt;&gt;</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>
queue<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">Queue</span><span class="token punctuation">,</span>
layout<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">BindGroupLayout</span><span class="token punctuation">,</span>
path<span class="token punctuation">:</span> <span class="token class-name">P</span><span class="token punctuation">,</span>
<span class="token punctuation">)</span> <span class="token punctuation">-&gt;</span> <span class="token class-name">Result</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 comment">// ...</span>
<span class="token comment">// UPDATED!</span>
<span class="token keyword">let</span> meshes <span class="token operator">=</span> obj_models<span class="token punctuation">.</span><span class="token function">par_iter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token closure-params"><span class="token closure-punctuation punctuation">|</span>m<span class="token closure-punctuation punctuation">|</span></span> <span class="token punctuation">{</span>
<span class="token keyword">let</span> <span class="token keyword">mut</span> vertices <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">..</span>m<span class="token punctuation">.</span>mesh<span class="token punctuation">.</span>positions<span class="token punctuation">.</span><span class="token function">len</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">into_par_iter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token closure-params"><span class="token closure-punctuation punctuation">|</span>i<span class="token closure-punctuation punctuation">|</span></span> <span class="token punctuation">{</span>
<span class="token class-name">ModelVertex</span> <span class="token punctuation">{</span>
position<span class="token punctuation">:</span> <span class="token punctuation">[</span>
m<span class="token punctuation">.</span>mesh<span class="token punctuation">.</span>positions<span class="token punctuation">[</span>i <span class="token operator">*</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
m<span class="token punctuation">.</span>mesh<span class="token punctuation">.</span>positions<span class="token punctuation">[</span>i <span class="token operator">*</span> <span class="token number">3</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
m<span class="token punctuation">.</span>mesh<span class="token punctuation">.</span>positions<span class="token punctuation">[</span>i <span class="token operator">*</span> <span class="token number">3</span> <span class="token operator">+</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">into</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
tex_coords<span class="token punctuation">:</span> <span class="token punctuation">[</span>
m<span class="token punctuation">.</span>mesh<span class="token punctuation">.</span>texcoords<span class="token punctuation">[</span>i <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
m<span class="token punctuation">.</span>mesh<span class="token punctuation">.</span>texcoords<span class="token punctuation">[</span>i <span class="token operator">*</span> <span class="token number">2</span> <span class="token operator">+</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 function">into</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
normal<span class="token punctuation">:</span> <span class="token punctuation">[</span>
m<span class="token punctuation">.</span>mesh<span class="token punctuation">.</span>normals<span class="token punctuation">[</span>i <span class="token operator">*</span> <span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
m<span class="token punctuation">.</span>mesh<span class="token punctuation">.</span>normals<span class="token punctuation">[</span>i <span class="token operator">*</span> <span class="token number">3</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
m<span class="token punctuation">.</span>mesh<span class="token punctuation">.</span>normals<span class="token punctuation">[</span>i <span class="token operator">*</span> <span class="token number">3</span> <span class="token operator">+</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">into</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token comment">// We'll calculate these later</span>
tangent<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">3</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">into</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
bitangent<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">3</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">into</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 function">collect</span><span class="token punctuation">::</span><span class="token operator">&lt;</span><span class="token class-name">Vec</span><span class="token operator">&lt;</span>_<span class="token operator">&gt;&gt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// ...</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 operator">&amp;</span><span class="token macro property">format!</span><span class="token punctuation">(</span><span class="token string">&quot;{:?} Index Buffer&quot;</span><span class="token punctuation">,</span> m<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token comment">// UPDATED!</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 operator">&amp;</span>m<span class="token punctuation">.</span>mesh<span class="token punctuation">.</span>indices<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 comment">// ...</span>
<span class="token comment">// UPDATED!</span>
<span class="token class-name">Ok</span><span class="token punctuation">(</span><span class="token class-name">Mesh</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><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">collect</span><span class="token punctuation">::</span><span class="token operator">&lt;</span><span class="token class-name">Result</span><span class="token operator">&lt;</span><span class="token class-name">Vec</span><span class="token operator">&lt;</span>_<span class="token operator">&gt;&gt;</span><span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">?</span><span class="token punctuation">;</span>
<span class="token comment">// ...</span>
<span class="token punctuation">}</span>
<span class="token comment">// ...</span>
<span class="token punctuation">}</span>
</code></pre></div><p>We've parallelized loading the meshes, and making the vertex array for them. Probably a bit overkill, but <code>rayon</code> should prevent us from using too many threads.</p> <div class="note"><p>You'll notice that we didn't use <code>rayon</code> for calculating the tangent, and bitangent. I tried to get it to work, but I was having trouble finding a way to do it without multiple mutable references to <code>vertices</code>. I don't feel like introducing a <code>std::sync::Mutex</code>, so I'll leave it for now.</p> <p>This is honestly a better job for a compute shader, as the model data is going to get loaded into a buffer anyway.</p></div> <h2 id="it-s-that-easy"><a href="#it-s-that-easy" class="header-anchor">#</a> It's that easy!</h2> <p>Most of the <code>wgpu</code> types are <code>Send + Sync</code>, so we can use them in threads without much trouble. It was so easy, that I feel like this tutorial is too short! I'll just leave off with a speed comparison between the previous model loading code and the current code.</p> <div class="language- extra-class"><pre class="language-text"><code>Elapsed (Original): 309.596382ms
Elapsed (Threaded): 199.645027ms
</code></pre></div><p>We're not loading that many resources, so the speedup is minimal. We'll be doing more stuff with threading, but this is a good introduction.</p> <div class="auto-github-link"><a href="https://github.com/sotrh/learn-wgpu/tree/master/code/showcase/threading/" 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/28/2023, 12:41:06 AM</span></div></footer> <!----> </main></div></div><div class="global-ui"><!----></div></div>
<script src="/learn-wgpu/assets/js/app.9afc5d83.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/66.a136cd48.js" defer></script><script src="/learn-wgpu/assets/js/37.5ecf7ce2.js" defer></script>
</body>
</html>