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

30 lines
22 KiB
HTML

<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>News | Learn Wgpu</title>
<meta name="description" content="">
<meta name="generator" content="VuePress 1.4.0">
<meta property="article:modified_time" content="2021-03-11T03:19:09.000Z"><meta property="og:site_name" content="Learn Wgpu"><meta property="og:title" content="News"><meta property="og:type" content="website"><meta property="og:url" content="/news/"><meta name="twitter:title" content="News"><meta name="twitter:url" content="/news/"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:label1" content="Written by"><meta name="twitter:data2" content="Benjamin R Hansen"><meta name="twitter:creator" content="https://twitter.com/sotrh760">
<link rel="preload" href="/learn-wgpu/assets/css/0.styles.7acc6ef6.css" as="style"><link rel="preload" href="/learn-wgpu/assets/js/app.da448c16.js" as="script"><link rel="preload" href="/learn-wgpu/assets/js/2.da3fd46f.js" as="script"><link rel="preload" href="/learn-wgpu/assets/js/17.f03fd0c9.js" as="script"><link rel="preload" href="/learn-wgpu/assets/js/9.ecb6e79c.js" as="script"><link rel="prefetch" href="/learn-wgpu/assets/js/10.de8cadfb.js"><link rel="prefetch" href="/learn-wgpu/assets/js/11.65c8dcc2.js"><link rel="prefetch" href="/learn-wgpu/assets/js/12.26aabcb1.js"><link rel="prefetch" href="/learn-wgpu/assets/js/13.7cd9aa08.js"><link rel="prefetch" href="/learn-wgpu/assets/js/14.b2a56b9f.js"><link rel="prefetch" href="/learn-wgpu/assets/js/15.057386b5.js"><link rel="prefetch" href="/learn-wgpu/assets/js/16.9abecf13.js"><link rel="prefetch" href="/learn-wgpu/assets/js/18.d3691f26.js"><link rel="prefetch" href="/learn-wgpu/assets/js/19.e9350ae9.js"><link rel="prefetch" href="/learn-wgpu/assets/js/20.70e640cc.js"><link rel="prefetch" href="/learn-wgpu/assets/js/21.19d2890c.js"><link rel="prefetch" href="/learn-wgpu/assets/js/22.2132e362.js"><link rel="prefetch" href="/learn-wgpu/assets/js/23.1a88f225.js"><link rel="prefetch" href="/learn-wgpu/assets/js/24.6ef5d54e.js"><link rel="prefetch" href="/learn-wgpu/assets/js/25.b4a2e728.js"><link rel="prefetch" href="/learn-wgpu/assets/js/26.f5a0678a.js"><link rel="prefetch" href="/learn-wgpu/assets/js/27.04f788d9.js"><link rel="prefetch" href="/learn-wgpu/assets/js/28.a3ac06e2.js"><link rel="prefetch" href="/learn-wgpu/assets/js/29.281013fa.js"><link rel="prefetch" href="/learn-wgpu/assets/js/3.2d0dff45.js"><link rel="prefetch" href="/learn-wgpu/assets/js/30.dc887be9.js"><link rel="prefetch" href="/learn-wgpu/assets/js/4.430752ae.js"><link rel="prefetch" href="/learn-wgpu/assets/js/5.5e4953de.js"><link rel="prefetch" href="/learn-wgpu/assets/js/6.cc40d32a.js"><link rel="prefetch" href="/learn-wgpu/assets/js/7.88810c81.js"><link rel="prefetch" href="/learn-wgpu/assets/js/8.de43c958.js">
<link rel="stylesheet" href="/learn-wgpu/assets/css/0.styles.7acc6ef6.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/" 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-swapchain/" class="sidebar-link">The Swapchain</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-threading/" class="sidebar-link">Multi-threading with Wgpu and Rayon</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><a href="/learn-wgpu/news/" class="active sidebar-link">News</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/learn-wgpu/news/#_0-7" class="sidebar-link">0.7</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/news/#november-2020-cleanup-content-freeze-and-patreon" class="sidebar-link">November 2020 Cleanup, Content Freeze, and Patreon</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/news/#_0-6" class="sidebar-link">0.6</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/news/#added-pong-showcase" class="sidebar-link">Added Pong Showcase</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/news/#normal-mapping" class="sidebar-link">Normal mapping</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/news/#_0-5" class="sidebar-link">0.5!</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/news/#reworked-lighting-tutorial" class="sidebar-link">Reworked lighting tutorial</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/news/#added-gif-showcase" class="sidebar-link">Added GIF showcase</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/news/#updated-texture-tutorials" class="sidebar-link">Updated texture tutorials</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/news/#fixed-panics-do-to-not-specifying-the-correct-usage" class="sidebar-link">Fixed panics do to not specifying the correct usage</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/news/#updating-winit-from-0-20-0-alpha5-to-0-20" class="sidebar-link">Updating Winit from 0.20.0-alpha5 to 0.20</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/news/#changed-tutorial-examples-to-use-a-src-directory" class="sidebar-link">Changed tutorial examples to use a src directory</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/news/#updating-to-0-4-from-0-3" class="sidebar-link">Updating to 0.4 from 0.3</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/news/#new-recent-articles" class="sidebar-link">New/Recent Articles</a></li></ul></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="news"><a href="#news" class="header-anchor">#</a> News</h1> <h2 id="_0-7"><a href="#_0-7" class="header-anchor">#</a> 0.7</h2> <p>There were a lot of changes particularly to the <code>RenderPipelineDescriptor</code>. Most other things have not changed. You can check out the <a href="https://github.com/sotrh/learn-wgpu/pull/140" target="_blank" rel="noopener noreferrer">0.9 PR<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" 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></a> for the full details.</p> <h2 id="november-2020-cleanup-content-freeze-and-patreon"><a href="#november-2020-cleanup-content-freeze-and-patreon" class="header-anchor">#</a> November 2020 Cleanup, Content Freeze, and Patreon</h2> <p>School is starting to ramp up, so I haven't had as much time to work on the site as I would like to. Because of that there were some issues piling up. I decided to tackle a bunch of them in one go. Here's a snapshot of what I did:</p> <ul><li>The tutorial now handles <code>SwapChainError</code> properly</li> <li>I'm now using bytemuck's derive feature on all buffer data structs.</li> <li>The <a href="../beginner/tutorial7-instancing">instancing tutorial</a> now uses vertex buffers instead of storage buffers.</li> <li><code>build.rs</code> now updates when individual shaders are changed, not whenever <code>/src</code> is changed.</li> <li>Had some help from Github user @kanerogers to clean up the <a href="../beginner/tutorial5-textures">texturing tutorial</a>.</li> <li>I made a <a href="../showcase/compute">compute pipeline showcase</a> that computes the tangent and bitangent for each vertex in a model.</li> <li>I made a <a href="../showcase/imgui-demo">imgui showcase</a>. It's very basic, but it should be a good starting point.</li></ul> <p>Now in the headline I mentioned a &quot;Content Freeze&quot;. Wgpu is still a moving target. The migration from <code>0.4</code> to <code>0.5</code> was lot of work. The same goes for <code>0.5</code> to <code>0.6</code>. I'm expected the next migration to be just as much work. As such, I won't be added much content until the API becomes a bit more stable. That being said, I still plan on resolving any issues with the content.</p> <p>One more thing. This is actually quite awkward for me (especially since I'll be slowing down development), but I've started a <a href="https://www.patreon.com/sotrh" target="_blank" rel="noopener noreferrer">patreon<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" 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></a>. My job doesn't give me a ton of hours, so things are a bit tight. You are by no means obligated to donate, but I would appreciate it.</p> <p>You can find out more about contributing to this project on the <a href="/learn-wgpu/#contribution-and-support">introduction page</a></p> <h2 id="_0-6"><a href="#_0-6" class="header-anchor">#</a> 0.6</h2> <p>This took me way too long. The changes weren't difficult, but I had to do a lot of copy pasting. The main changes are using <code>queue.write_buffer()</code> and <code>queue.write_texture()</code> everywhere. I won't get into the nitty gritty, but you can checkout the <a href="https://github.com/sotrh/learn-wgpu/pull/90" target="_blank" rel="noopener noreferrer">pull request<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" 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></a> if you're interested.</p> <h2 id="added-pong-showcase"><a href="#added-pong-showcase" class="header-anchor">#</a> Added Pong Showcase</h2> <p><a href="/learn-wgpu/showcase/pong/">See it here</a></p> <h2 id="normal-mapping"><a href="#normal-mapping" class="header-anchor">#</a> Normal mapping</h2> <p>My perfectionism got in my way a bit with this one. I wasn't sure that what I was getting was &quot;physically accurate&quot;, but it seems to look good.</p> <p><img src="/learn-wgpu/assets/img/normal_mapping_correct.2731b486.png" alt=""></p> <h2 id="_0-5"><a href="#_0-5" class="header-anchor">#</a> 0.5!</h2> <p>Too many things changed to make note of them here. Check out <a href="https://github.com/sotrh/learn-wgpu/pull/29" target="_blank" rel="noopener noreferrer">the 0.5 pull request<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" 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></a> if you're curious about specifics. That being said, 2 things are worth mentioning directly: the y-axis now points up like with DirectX and Metal, and requesting an adapter and creating a device now use <code>Future</code>s. The tutorials have been updated as well as the code.</p> <h2 id="reworked-lighting-tutorial"><a href="#reworked-lighting-tutorial" class="header-anchor">#</a> Reworked lighting tutorial</h2> <p>The <a href="/learn-wgpu/intermediate/tutorial10-lighting/">lighting tutorial</a> was not up to par, so I redid it.</p> <h2 id="added-gif-showcase"><a href="#added-gif-showcase" class="header-anchor">#</a> Added GIF showcase</h2> <p><a href="/learn-wgpu/showcase/gifs/">Creating GIFs</a></p> <h2 id="updated-texture-tutorials"><a href="#updated-texture-tutorials" class="header-anchor">#</a> Updated texture tutorials</h2> <p>Up to this point, we created textures manually everytime. I've pulled out the texture creation code into a new <code>texture.rs</code> file and included it every tutorial from the <a href="/learn-wgpu/beginner/tutorial5-textures/#cleaning-things-up">textures tutorial</a> onward.</p> <h2 id="fixed-panics-do-to-not-specifying-the-correct-usage"><a href="#fixed-panics-do-to-not-specifying-the-correct-usage" class="header-anchor">#</a> Fixed panics do to not specifying the correct <code>usage</code></h2> <p>Wgpu has become more strict about what <code>BufferUsage</code>s and <code>TextureUsage</code>s are required when performing certain operations. For example int the <a href="/learn-wgpu/intermediate/windowless/">Wgpu without a window example</a>, the <code>texture_desc</code> only specified the usage to by <code>COPY_SRC</code>. This caused a crash when the <code>texture</code> was used as a render target. Adding <code>OUTPUT_ATTACHMENT</code> fixed the issue.</p> <h2 id="updating-winit-from-0-20-0-alpha5-to-0-20"><a href="#updating-winit-from-0-20-0-alpha5-to-0-20" class="header-anchor">#</a> Updating Winit from 0.20.0-alpha5 to 0.20</h2> <p>There were a lot of small changes to how the dpi stuff works. You can see all the changes <a href="https://github.com/rust-windowing/winit/blob/master/CHANGELOG.md" target="_blank" rel="noopener noreferrer">in the changelog<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" 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></a>. That means that some of the tutorials had to change.</p> <ul><li>I've removed <code>hidpi_factor</code> from <code>State</code> entirely. They removed the <code>hidpi_factor()</code> method from <code>winit::window::Window</code>, and changed <code>inner_size()</code> to return <code>PhysicalSize</code> instead of <code>LogicalSize</code>, so we don't need to store the <code>hidpi_factor</code> anymore.</li> <li><code>update_hidpi_and_resize</code> is no more. Since <code>ScaleFactorChanged</code> passes in the windows new <code>PhysicalSize</code>, we can simply use <code>resize()</code>.</li> <li><code>State::size</code> is now <code>PhysicalSize&lt;u32&gt;</code> instead of the pre 0.20 <code>LogicalSize</code>.</li> <li><code>EventsCleared</code> is now <code>MainEventsCleared</code>.</li></ul> <p>I may have missed a change, but I made sure that all the examples compile an run, so if you have trouble with your code you can use them as a reference.</p> <h2 id="changed-tutorial-examples-to-use-a-src-directory"><a href="#changed-tutorial-examples-to-use-a-src-directory" class="header-anchor">#</a> Changed tutorial examples to use a src directory</h2> <p>I wasn't using the traditional cargo binary folder setup. I've changed it to the standardized form now.</p> <h2 id="updating-to-0-4-from-0-3"><a href="#updating-to-0-4-from-0-3" class="header-anchor">#</a> Updating to 0.4 from 0.3</h2> <p>There are a few things that have changed:</p> <ol><li>The use of <code>Instance</code> has been removed. Creating a <code>Surface</code> and requesting an <code>Adapter</code> are done as follows.</li></ol> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">let</span> surface <span class="token operator">=</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">Surface</span><span class="token punctuation">::</span><span class="token function">create</span><span class="token punctuation">(</span>window<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> adapter <span class="token operator">=</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">Adapter</span><span class="token punctuation">::</span><span class="token function">request</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">RequestAdapterOptions</span> <span class="token punctuation">{</span>
<span class="token punctuation">..</span><span class="token class-name">Default</span><span class="token punctuation">::</span><span class="token function">default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">unwrap</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// needs to be unwrapped</span>
</code></pre></div><ol start="2"><li>The <code>request_device</code> method now returns a <code>(Device, Queue)</code> tuple. This means that you can borrow the <code>Queue</code> mutably while using the <code>Device</code> immutably. Because of this change, submitting <code>CommandBuffer</code>s to the queue uses the <code>submit</code> method on the <code>Queue</code> directly.</li></ol> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">self</span><span class="token punctuation">.</span>queue<span class="token punctuation">.</span><span class="token function">submit</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token punctuation">[</span>
encoder<span class="token punctuation">.</span><span class="token function">finish</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><ol start="3"><li>The <code>create</code> method on <code>Surface</code> takes in any struct that implements the <code>HasRawWindow</code> trait, instead of a <code>RawWindowHandle</code>. This means that the <code>raw-window-handle = &quot;0.3&quot;</code> line in <code>Cargo.toml</code> is no longer needed.</li></ol> <p>I don't know if this is a change from 0.4, but you use <code>wgpu = &quot;0.4&quot;</code> line in dependencies instead of the <code>[dependencies.wgpu]</code> as wgpu will determine the best back end for you.</p> <h2 id="new-recent-articles"><a href="#new-recent-articles" class="header-anchor">#</a> New/Recent Articles</h2> <div><ul><li><a href="/beginner/tutorial1-window/">Dependencies and the window</a></li><li><a href="/beginner/tutorial2-swapchain/">The Swapchain</a></li><li><a href="/beginner/tutorial3-pipeline/">The Pipeline</a></li><li><a href="/beginner/tutorial4-buffer/">Buffers and Indices</a></li><li><a href="/beginner/tutorial5-textures/">Textures and bind groups</a></li></ul></div></div> <footer class="page-edit"><!----> <div class="last-updated"><span class="prefix">Last Updated: </span> <span class="time">3/11/2021, 3:19:09 AM</span></div></footer> <div class="page-nav"><p class="inner"><span class="prev">
<a href="/learn-wgpu/showcase/imgui-demo/" class="prev">
Basic Imgui Demo
</a></span> <!----></p></div> </main></div></div><div class="global-ui"><!----></div></div>
<script src="/learn-wgpu/assets/js/app.da448c16.js" defer></script><script src="/learn-wgpu/assets/js/2.da3fd46f.js" defer></script><script src="/learn-wgpu/assets/js/17.f03fd0c9.js" defer></script><script src="/learn-wgpu/assets/js/9.ecb6e79c.js" defer></script>
</body>
</html>