Deploying to gh-pages from @ sotrh/learn-wgpu@5bc97f3108 🚀

gh-pages
sotrh 6 months ago
parent bcfea0c264
commit e4eab0c3fd

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -8,11 +8,11 @@
<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.a49faced.js" as="script"><link rel="preload" href="/learn-wgpu/assets/js/5.250d79d3.js" as="script"><link rel="prefetch" href="/learn-wgpu/assets/js/1.eaeeb819.js"><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.dd15c417.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/2.2ef7287a.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.a01d50ae.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.fd4eb8d5.js"><link rel="prefetch" href="/learn-wgpu/assets/js/27.914a9a40.js"><link rel="prefetch" href="/learn-wgpu/assets/js/28.77f7d987.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.c58683af.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.945dce62.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.e6a8b391.js"><link rel="prefetch" href="/learn-wgpu/assets/js/37.5ecf7ce2.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.47515217.js"><link rel="prefetch" href="/learn-wgpu/assets/js/42.4caac867.js"><link rel="prefetch" href="/learn-wgpu/assets/js/43.ac6fc643.js"><link rel="prefetch" href="/learn-wgpu/assets/js/44.27513d85.js"><link rel="prefetch" href="/learn-wgpu/assets/js/45.2ea5b108.js"><link rel="prefetch" href="/learn-wgpu/assets/js/46.e591bcb9.js"><link rel="prefetch" href="/learn-wgpu/assets/js/47.3a7bf317.js"><link rel="prefetch" href="/learn-wgpu/assets/js/48.0a15e622.js"><link rel="prefetch" href="/learn-wgpu/assets/js/49.ad5a99aa.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.48268452.js"><link rel="prefetch" href="/learn-wgpu/assets/js/53.8c976652.js"><link rel="prefetch" href="/learn-wgpu/assets/js/54.daee63ce.js"><link rel="prefetch" href="/learn-wgpu/assets/js/55.3799ddaa.js"><link rel="prefetch" href="/learn-wgpu/assets/js/56.a43d5d8e.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.24bfa87e.js"><link rel="prefetch" href="/learn-wgpu/assets/js/63.90f94cac.js"><link rel="prefetch" href="/learn-wgpu/assets/js/64.b9a310af.js"><link rel="prefetch" href="/learn-wgpu/assets/js/65.362df98e.js"><link rel="prefetch" href="/learn-wgpu/assets/js/66.ef1e3716.js"><link rel="prefetch" href="/learn-wgpu/assets/js/67.ab338058.js"><link rel="prefetch" href="/learn-wgpu/assets/js/68.d785413d.js"><link rel="prefetch" href="/learn-wgpu/assets/js/8.2c0d831a.js"><link rel="prefetch" href="/learn-wgpu/assets/js/9.985bc61a.js"><link rel="prefetch" href="/learn-wgpu/assets/js/vendors~docsearch.efa6f8ef.js">
<link rel="preload" href="/learn-wgpu/assets/css/0.styles.81cb5453.css" as="style"><link rel="preload" href="/learn-wgpu/assets/js/app.99e1547a.js" as="script"><link rel="preload" href="/learn-wgpu/assets/js/5.250d79d3.js" as="script"><link rel="prefetch" href="/learn-wgpu/assets/js/1.eaeeb819.js"><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/2.7dc9d716.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.bcec92ff.js"><link rel="prefetch" href="/learn-wgpu/assets/js/27.c755f80e.js"><link rel="prefetch" href="/learn-wgpu/assets/js/28.be489186.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/30.12d50dcb.js"><link rel="prefetch" href="/learn-wgpu/assets/js/31.550259b2.js"><link rel="prefetch" href="/learn-wgpu/assets/js/32.e359d5e0.js"><link rel="prefetch" href="/learn-wgpu/assets/js/33.945dce62.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.beae0010.js"><link rel="prefetch" href="/learn-wgpu/assets/js/37.5ecf7ce2.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.7e2aef8c.js"><link rel="prefetch" href="/learn-wgpu/assets/js/42.6f76d27e.js"><link rel="prefetch" href="/learn-wgpu/assets/js/43.ddac8e2c.js"><link rel="prefetch" href="/learn-wgpu/assets/js/44.1486e9ca.js"><link rel="prefetch" href="/learn-wgpu/assets/js/45.2ea5b108.js"><link rel="prefetch" href="/learn-wgpu/assets/js/46.fbe2131f.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.c0f22e2e.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.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.2dadff38.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.c78dac93.js"><link rel="prefetch" href="/learn-wgpu/assets/js/61.87dce596.js"><link rel="prefetch" href="/learn-wgpu/assets/js/62.fc4967ec.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.0c2a60e3.js"><link rel="prefetch" href="/learn-wgpu/assets/js/66.a136cd48.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"><div class="theme-default-content"><h1>404</h1> <blockquote>That's a Four-Oh-Four.</blockquote> <a href="/learn-wgpu/" class="router-link-active">Take me home.</a></div></div><div class="global-ui"><!----></div></div>
<script src="/learn-wgpu/assets/js/app.a49faced.js" defer></script><script src="/learn-wgpu/assets/js/5.250d79d3.js" defer></script>
<script src="/learn-wgpu/assets/js/app.99e1547a.js" defer></script><script src="/learn-wgpu/assets/js/5.250d79d3.js" defer></script>
</body>
</html>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1 +1 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[56],{442:function(s,t,i){"use strict";i.r(t);var e=i(7),n=Object(e.a)({},(function(){var s=this._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[s("h1",{attrs:{id:"sources"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#sources"}},[this._v("#")]),this._v(" Sources")]),this._v(" "),s("ul",[s("li",[this._v("https://www.scratchapixel.com/lessons/3d-basic-rendering/introduction-to-shading/diffuse-lambertian-shading")]),this._v(" "),s("li",[this._v("http://jimmiejohnsson84.me/pages/rendering_pbr.html")])])])}),[],!1,null,null,null);t.default=n.exports}}]);
(window.webpackJsonp=window.webpackJsonp||[]).push([[56],{441:function(s,t,i){"use strict";i.r(t);var e=i(7),n=Object(e.a)({},(function(){var s=this._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[s("h1",{attrs:{id:"sources"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#sources"}},[this._v("#")]),this._v(" Sources")]),this._v(" "),s("ul",[s("li",[this._v("https://www.scratchapixel.com/lessons/3d-basic-rendering/introduction-to-shading/diffuse-lambertian-shading")]),this._v(" "),s("li",[this._v("http://jimmiejohnsson84.me/pages/rendering_pbr.html")])])])}),[],!1,null,null,null);t.default=n.exports}}]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1 +1 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[62],{453:function(t,s,e){"use strict";e.r(s);var a=e(7),o=Object(a.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("h1",{attrs:{id:"update-to-0-17"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#update-to-0-17"}},[this._v("#")]),this._v(" Update to 0.17")]),this._v(" "),t("p",[this._v("No changes needed to the tutorial!")])])}),[],!1,null,null,null);s.default=o.exports}}]);
(window.webpackJsonp=window.webpackJsonp||[]).push([[62],{451:function(t,s,e){"use strict";e.r(s);var a=e(7),o=Object(a.a)({},(function(){var t=this._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}},[t("h1",{attrs:{id:"update-to-0-17"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#update-to-0-17"}},[this._v("#")]),this._v(" Update to 0.17")]),this._v(" "),t("p",[this._v("No changes needed to the tutorial!")])])}),[],!1,null,null,null);s.default=o.exports}}]);

@ -1 +1 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[63],{452:function(t,e,o){"use strict";o.r(e);var a=o(7),r=Object(a.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"update-to-0-18-and-hdr-tutorial"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#update-to-0-18-and-hdr-tutorial"}},[t._v("#")]),t._v(" Update to 0.18 and HDR tutorial")]),t._v(" "),e("p",[t._v("First let's go over some of the changes that occurred:")]),t._v(" "),e("ol",[e("li",[e("code",[t._v("RenderPassDescriptor")]),t._v(" now have 2 new fields:\n"),e("code",[t._v("occlusion_query_set")]),t._v(" and, "),e("code",[t._v("timestamp_writes")]),t._v(". I'm\nsetting both to "),e("code",[t._v("None")]),t._v(" for now.")]),t._v(" "),e("li",[e("code",[t._v("ComputePassDescriptor")]),t._v(" now has a "),e("code",[t._v("timestamp_writes")]),t._v("\nfield.")]),t._v(" "),e("li",[e("code",[t._v("InstanceDescriptor")]),t._v(" now has some more fields, but I\nopted to just use "),e("code",[t._v("..Default::default()")]),t._v(" for all the\nfields other than "),e("code",[t._v("backends")]),t._v(".")])]),t._v(" "),e("h2",{attrs:{id:"hdr-tutorial"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#hdr-tutorial"}},[t._v("#")]),t._v(" HDR tutorial")]),t._v(" "),e("p",[t._v("I've been unsure how best to introduce compute shaders\nas they are a big part of what makes WebGPU special, but\nmost browsers don't support them at the moment. With Chrome\nrolling out support for WebGPU, I felt more confident\nwriting a tutorial for them.")]),t._v(" "),e("p",[t._v("Also, I'm been interested learning how to load HDR images\nfrom places like Polyhaven, so I decided to introduce\ncompute shaders by creating one that will load an HDR and\nconvert it to a Cubemap to be rendered.")]),t._v(" "),e("p",[t._v("You can check it out "),e("a",{attrs:{href:"../../intermediate/tutorial13-hdr"}},[t._v("here")]),t._v("!")])])}),[],!1,null,null,null);e.default=r.exports}}]);
(window.webpackJsonp=window.webpackJsonp||[]).push([[63],{453:function(t,e,o){"use strict";o.r(e);var a=o(7),r=Object(a.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"update-to-0-18-and-hdr-tutorial"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#update-to-0-18-and-hdr-tutorial"}},[t._v("#")]),t._v(" Update to 0.18 and HDR tutorial")]),t._v(" "),e("p",[t._v("First let's go over some of the changes that occurred:")]),t._v(" "),e("ol",[e("li",[e("code",[t._v("RenderPassDescriptor")]),t._v(" now have 2 new fields:\n"),e("code",[t._v("occlusion_query_set")]),t._v(" and, "),e("code",[t._v("timestamp_writes")]),t._v(". I'm\nsetting both to "),e("code",[t._v("None")]),t._v(" for now.")]),t._v(" "),e("li",[e("code",[t._v("ComputePassDescriptor")]),t._v(" now has a "),e("code",[t._v("timestamp_writes")]),t._v("\nfield.")]),t._v(" "),e("li",[e("code",[t._v("InstanceDescriptor")]),t._v(" now has some more fields, but I\nopted to just use "),e("code",[t._v("..Default::default()")]),t._v(" for all the\nfields other than "),e("code",[t._v("backends")]),t._v(".")])]),t._v(" "),e("h2",{attrs:{id:"hdr-tutorial"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#hdr-tutorial"}},[t._v("#")]),t._v(" HDR tutorial")]),t._v(" "),e("p",[t._v("I've been unsure how best to introduce compute shaders\nas they are a big part of what makes WebGPU special, but\nmost browsers don't support them at the moment. With Chrome\nrolling out support for WebGPU, I felt more confident\nwriting a tutorial for them.")]),t._v(" "),e("p",[t._v("Also, I'm been interested learning how to load HDR images\nfrom places like Polyhaven, so I decided to introduce\ncompute shaders by creating one that will load an HDR and\nconvert it to a Cubemap to be rendered.")]),t._v(" "),e("p",[t._v("You can check it out "),e("a",{attrs:{href:"../../intermediate/tutorial13-hdr"}},[t._v("here")]),t._v("!")])])}),[],!1,null,null,null);e.default=r.exports}}]);

@ -1 +1 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[64],{454:function(e,t,o){"use strict";o.r(t);var s=o(7),r=Object(s.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h1",{attrs:{id:"foreword"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#foreword"}},[e._v("#")]),e._v(" Foreword")]),e._v(" "),t("p",[e._v("The articles in this section are not meant to be tutorials. They are showcases of the various things you can do with "),t("code",[e._v("wgpu")]),e._v(". I won't go over the specifics of creating "),t("code",[e._v("wgpu")]),e._v(" resources, as those will be covered elsewhere. The code for these examples is still available however and will be accessible on Github.")])])}),[],!1,null,null,null);t.default=r.exports}}]);
(window.webpackJsonp=window.webpackJsonp||[]).push([[64],{455:function(e,t,o){"use strict";o.r(t);var s=o(7),r=Object(s.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h1",{attrs:{id:"foreword"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#foreword"}},[e._v("#")]),e._v(" Foreword")]),e._v(" "),t("p",[e._v("The articles in this section are not meant to be tutorials. They are showcases of the various things you can do with "),t("code",[e._v("wgpu")]),e._v(". I won't go over the specifics of creating "),t("code",[e._v("wgpu")]),e._v(" resources, as those will be covered elsewhere. The code for these examples is still available however and will be accessible on Github.")])])}),[],!1,null,null,null);t.default=r.exports}}]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

@ -8,7 +8,7 @@
<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.a49faced.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/55.3799ddaa.js" as="script"><link rel="preload" href="/learn-wgpu/assets/js/33.945dce62.js" as="script"><link rel="preload" href="/learn-wgpu/assets/js/37.5ecf7ce2.js" as="script"><link rel="prefetch" href="/learn-wgpu/assets/js/10.baf5d1fe.js"><link rel="prefetch" href="/learn-wgpu/assets/js/11.b8633c49.js"><link rel="prefetch" href="/learn-wgpu/assets/js/12.0b8835f1.js"><link rel="prefetch" href="/learn-wgpu/assets/js/13.af1bbe85.js"><link rel="prefetch" href="/learn-wgpu/assets/js/14.626c7cb3.js"><link rel="prefetch" href="/learn-wgpu/assets/js/15.5a8ea302.js"><link rel="prefetch" href="/learn-wgpu/assets/js/16.f4e8226b.js"><link rel="prefetch" href="/learn-wgpu/assets/js/17.dd15c417.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.a01d50ae.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.fd4eb8d5.js"><link rel="prefetch" href="/learn-wgpu/assets/js/27.914a9a40.js"><link rel="prefetch" href="/learn-wgpu/assets/js/28.77f7d987.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.c58683af.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/34.0fe8e5e4.js"><link rel="prefetch" href="/learn-wgpu/assets/js/35.7c607f94.js"><link rel="prefetch" href="/learn-wgpu/assets/js/36.e6a8b391.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.47515217.js"><link rel="prefetch" href="/learn-wgpu/assets/js/42.4caac867.js"><link rel="prefetch" href="/learn-wgpu/assets/js/43.ac6fc643.js"><link rel="prefetch" href="/learn-wgpu/assets/js/44.27513d85.js"><link rel="prefetch" href="/learn-wgpu/assets/js/45.2ea5b108.js"><link rel="prefetch" href="/learn-wgpu/assets/js/46.e591bcb9.js"><link rel="prefetch" href="/learn-wgpu/assets/js/47.3a7bf317.js"><link rel="prefetch" href="/learn-wgpu/assets/js/48.0a15e622.js"><link rel="prefetch" href="/learn-wgpu/assets/js/49.ad5a99aa.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.48268452.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/56.a43d5d8e.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.24bfa87e.js"><link rel="prefetch" href="/learn-wgpu/assets/js/63.90f94cac.js"><link rel="prefetch" href="/learn-wgpu/assets/js/64.b9a310af.js"><link rel="prefetch" href="/learn-wgpu/assets/js/65.362df98e.js"><link rel="prefetch" href="/learn-wgpu/assets/js/66.ef1e3716.js"><link rel="prefetch" href="/learn-wgpu/assets/js/67.ab338058.js"><link rel="prefetch" href="/learn-wgpu/assets/js/68.d785413d.js"><link rel="prefetch" href="/learn-wgpu/assets/js/8.2c0d831a.js"><link rel="prefetch" href="/learn-wgpu/assets/js/9.985bc61a.js"><link rel="prefetch" href="/learn-wgpu/assets/js/vendors~docsearch.efa6f8ef.js">
<link rel="preload" href="/learn-wgpu/assets/css/0.styles.81cb5453.css" as="style"><link rel="preload" href="/learn-wgpu/assets/js/app.99e1547a.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/55.2dadff38.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.bcec92ff.js"><link rel="prefetch" href="/learn-wgpu/assets/js/27.c755f80e.js"><link rel="prefetch" href="/learn-wgpu/assets/js/28.be489186.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/30.12d50dcb.js"><link rel="prefetch" href="/learn-wgpu/assets/js/31.550259b2.js"><link rel="prefetch" href="/learn-wgpu/assets/js/32.e359d5e0.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.beae0010.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.7e2aef8c.js"><link rel="prefetch" href="/learn-wgpu/assets/js/42.6f76d27e.js"><link rel="prefetch" href="/learn-wgpu/assets/js/43.ddac8e2c.js"><link rel="prefetch" href="/learn-wgpu/assets/js/44.1486e9ca.js"><link rel="prefetch" href="/learn-wgpu/assets/js/45.2ea5b108.js"><link rel="prefetch" href="/learn-wgpu/assets/js/46.fbe2131f.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.c0f22e2e.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.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/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.c78dac93.js"><link rel="prefetch" href="/learn-wgpu/assets/js/61.87dce596.js"><link rel="prefetch" href="/learn-wgpu/assets/js/62.fc4967ec.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.0c2a60e3.js"><link rel="prefetch" href="/learn-wgpu/assets/js/66.a136cd48.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>
@ -18,7 +18,7 @@
<span class="token key property">log</span> <span class="token punctuation">=</span> <span class="token string">&quot;0.4&quot;</span>
<span class="token key property">wgpu</span> <span class="token punctuation">=</span> <span class="token string">&quot;0.18&quot;</span>
</code></pre></div><h2 id="using-rust-s-new-resolver"><a href="#using-rust-s-new-resolver" class="header-anchor">#</a> Using Rust's new resolver</h2> <p>As of version 0.10, wgpu requires Cargo's <a href="https://doc.rust-lang.org/cargo/reference/resolver.html#feature-resolver-version-2" target="_blank" rel="noopener noreferrer">newest feature resolver<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>, which is the default in the 2021 edition (any new project started with Rust version 1.56.0 or newer). However, if you are still using the 2018 edition, you must include <code>resolver = &quot;2&quot;</code> in either the <code>[package]</code> section of <code>Cargo.toml</code> if you are working on a single crate or the <code>[workspace]</code> section of the root <code>Cargo.toml</code> in a workspace.</p> <h2 id="env-logger"><a href="#env-logger" class="header-anchor">#</a> env_logger</h2> <p>It is very important to enable logging via <code>env_logger::init();</code>.
When wgpu hits any error it panics with a generic message, while logging the real error via the log crate.
When wgpu hits any error, it panics with a generic message, while logging the real error via the log crate.
This means if you don't include <code>env_logger::init()</code>, wgpu will fail silently, leaving you very confused!<br>
(This has been done in the code below)</p> <h2 id="create-a-new-project"><a href="#create-a-new-project" class="header-anchor">#</a> Create a new project</h2> <p>run <code>cargo new project_name</code> where project_name is the name of the project.<br>
(In the example below, I have used 'tutorial1_window')</p> <h2 id="the-code"><a href="#the-code" class="header-anchor">#</a> The code</h2> <p>There's not much going on here yet, so I'm just going to post the code in full. Just paste this into your <code>lib.rs</code> or equivalent.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">use</span> <span class="token namespace">winit<span class="token punctuation">::</span></span><span class="token punctuation">{</span>
@ -53,7 +53,7 @@ This means if you don't include <code>env_logger::init()</code>, wgpu will fail
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>All this does is create a window and keep it open until the user closes it or presses escape. Next, we'll need a <code>main.rs</code> to run the code. It's quite simple, it just imports <code>run()</code> and, well, runs it!</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">use</span> <span class="token namespace">tutorial1_window<span class="token punctuation">::</span></span>run<span class="token punctuation">;</span>
</code></pre></div><p>All this does is create a window and keep it open until the user closes it or presses escape. Next, we'll need a <code>main.rs</code> to run the code. It's quite simple. It just imports <code>run()</code> and, well, runs it!</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">use</span> <span class="token namespace">tutorial1_window<span class="token punctuation">::</span></span>run<span class="token punctuation">;</span>
<span class="token keyword">fn</span> <span class="token function-definition function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
@ -77,14 +77,14 @@ This means if you don't include <code>env_logger::init()</code>, wgpu will fail
<span class="token punctuation">]</span><span class="token punctuation">}</span>
</code></pre></div><p>The <a href="https://docs.rs/cfg-if" target="_blank" rel="noopener noreferrer">cfg-if<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> crate adds a macro that makes using platform-specific code more manageable.</p> <p>The <code>[target.'cfg(target_arch = &quot;wasm32&quot;)'.dependencies]</code> line tells Cargo to only include these dependencies if we are targeting the <code>wasm32</code> architecture. The next few dependencies just make interfacing with JavaScript a lot easier.</p> <ul><li><a href="https://docs.rs/console_error_panic_hook" target="_blank" rel="noopener noreferrer">console_error_panic_hook<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> configures the <code>panic!</code> macro to send errors to the javascript console. Without this, when you encounter panics, you'll be left in the dark about what caused them.</li> <li><a href="https://docs.rs/console_log" target="_blank" rel="noopener noreferrer">console_log<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> implements the <a href="https://docs.rs/log" target="_blank" rel="noopener noreferrer">log<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> API. It sends all logs to the javascript console. It can be configured to only send logs of a particular log level. This is also great for debugging.</li> <li>We need to enable the WebGL feature on wgpu if we want to run on most current browsers. Support is in the works for using the WebGPU api directly, but that is only possible on experimental versions of browsers such as Firefox Nightly and Chrome Canary.<br>
You're welcome to test this code on these browsers (and the wgpu devs would appreciate it as well), but for the sake of simplicity, I'm going to stick to using the WebGL feature until the WebGPU api gets to a more stable state.<br>
If you want more details, check out the guide for compiling for the web on <a href="https://github.com/gfx-rs/wgpu/wiki/Running-on-the-Web-with-WebGPU-and-WebGL" target="_blank" rel="noopener noreferrer">wgpu's repo<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></li> <li><a href="https://docs.rs/wasm-bindgen" target="_blank" rel="noopener noreferrer">wasm-bindgen<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> is the most important dependency in this list. It's responsible for generating the boilerplate code that will tell the browser how to use our crate. It also allows us to expose methods in Rust that can be used in Javascript, and vice-versa.<br>
I won't get into the specifics of wasm-bindgen, so if you need a primer (or just a refresher), check out <a href="https://rustwasm.github.io/wasm-bindgen/" target="_blank" rel="noopener noreferrer">this<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></li> <li><a href="https://docs.rs/web-sys" target="_blank" rel="noopener noreferrer">web-sys<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> is a crate that includes many methods and structures that are available in a normal javascript application: <code>get_element_by_id</code>, <code>append_child</code>. The features listed are only the bare minimum of what we need currently.</li></ul> <h2 id="more-code"><a href="#more-code" class="header-anchor">#</a> More code</h2> <p>First, we need to import <code>wasm-bindgen</code> in <code>lib.rs</code>:</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token attribute attr-name">#[cfg(target_arch=<span class="token string">&quot;wasm32&quot;</span>)]</span>
If you want more details, check out the guide for compiling for the web on <a href="https://github.com/gfx-rs/wgpu/wiki/Running-on-the-Web-with-WebGPU-and-WebGL" target="_blank" rel="noopener noreferrer">wgpu's repo<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></li> <li><a href="https://docs.rs/wasm-bindgen" target="_blank" rel="noopener noreferrer">wasm-bindgen<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> is the most important dependency in this list. It's responsible for generating the boilerplate code that will tell the browser how to use our crate. It also allows us to expose methods in Rust that can be used in JavaScript and vice-versa.<br>
I won't get into the specifics of wasm-bindgen, so if you need a primer (or just a refresher), check out <a href="https://rustwasm.github.io/wasm-bindgen/" target="_blank" rel="noopener noreferrer">this<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></li> <li><a href="https://docs.rs/web-sys" target="_blank" rel="noopener noreferrer">web-sys<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> is a crate with many methods and structures available in a normal javascript application: <code>get_element_by_id</code>, <code>append_child</code>. The features listed are only the bare minimum of what we need currently.</li></ul> <h2 id="more-code"><a href="#more-code" class="header-anchor">#</a> More code</h2> <p>First, we need to import <code>wasm-bindgen</code> in <code>lib.rs</code>:</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token attribute attr-name">#[cfg(target_arch=<span class="token string">&quot;wasm32&quot;</span>)]</span>
<span class="token keyword">use</span> <span class="token namespace">wasm_bindgen<span class="token punctuation">::</span>prelude<span class="token punctuation">::</span></span><span class="token operator">*</span><span class="token punctuation">;</span>
</code></pre></div><p>Next, we need to tell wasm-bindgen to run our <code>run()</code> function when the WASM is loaded:</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token attribute attr-name">#[cfg_attr(target_arch=<span class="token string">&quot;wasm32&quot;</span>, wasm_bindgen(start))]</span>
<span class="token keyword">pub</span> <span class="token keyword">fn</span> <span class="token function-definition function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// same as above for now...</span>
<span class="token punctuation">}</span>
</code></pre></div><p>Then we need to toggle what logger we are using based on whether we are in WASM land or not. Add the following to the top of the run function, replacing the <code>env_logger::init()</code> line:</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token namespace">cfg_if<span class="token punctuation">::</span></span><span class="token macro property">cfg_if!</span> <span class="token punctuation">{</span>
</code></pre></div><p>Then, we need to toggle what logger we are using based on whether we are in WASM land or not. Add the following to the top of the run function, replacing the <code>env_logger::init()</code> line:</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token namespace">cfg_if<span class="token punctuation">::</span></span><span class="token macro property">cfg_if!</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span> <span class="token attribute attr-name">#[cfg(target_arch = <span class="token string">&quot;wasm32&quot;</span>)]</span> <span class="token punctuation">{</span>
<span class="token namespace">std<span class="token punctuation">::</span>panic<span class="token punctuation">::</span></span><span class="token function">set_hook</span><span class="token punctuation">(</span><span class="token class-name">Box</span><span class="token punctuation">::</span><span class="token function">new</span><span class="token punctuation">(</span><span class="token namespace">console_error_panic_hook<span class="token punctuation">::</span></span>hook<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token namespace">console_log<span class="token punctuation">::</span></span><span class="token function">init_with_level</span><span class="token punctuation">(</span><span class="token namespace">log<span class="token punctuation">::</span></span><span class="token class-name">Level</span><span class="token punctuation">::</span><span class="token class-name">Warn</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">expect</span><span class="token punctuation">(</span><span class="token string">&quot;Couldn't initialize logger&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
@ -110,8 +110,8 @@ I won't get into the specifics of wasm-bindgen, so if you need a primer (or just
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">expect</span><span class="token punctuation">(</span><span class="token string">&quot;Couldn't append canvas to document body.&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><div class="note"><p>The <code>&quot;wasm-example&quot;</code> id is specific to my project (aka. this tutorial). You can substitute this for whatever id you're using in your HTML. Alternatively, you could add the canvas directly to the <code>&lt;body&gt;</code> as they do in the wgpu repo. This part is ultimately up to you.</p></div> <p>That's all the web-specific code we need for now. The next thing we need to do is build the Web Assembly itself.</p> <h2 id="wasm-pack"><a href="#wasm-pack" class="header-anchor">#</a> Wasm Pack</h2> <p>Now you can build a wgpu application with just wasm-bindgen, but I ran into some issues doing that. For one, you need to install wasm-bindgen on your computer as well as include it as a dependency. The version you install as a dependency <strong>needs</strong> to exactly match the version you installed, otherwise, your build will fail.</p> <p>To get around this shortcoming, and to make the lives of everyone reading this easier, I opted to add <a href="https://rustwasm.github.io/docs/wasm-pack/" target="_blank" rel="noopener noreferrer">wasm-pack<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 the mix. Wasm-pack handles installing the correct version of wasm-bindgen for you, and it supports building for different types of web targets as well: browser, NodeJS, and bundlers such as webpack.</p> <p>To use wasm-pack, first, you need to <a href="https://rustwasm.github.io/wasm-pack/installer/" target="_blank" rel="noopener noreferrer">install it<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>Once you've done that, we can use it to build our crate. If you only have one crate in your project, you can just use <code>wasm-pack build</code>. If you're using a workspace, you'll have to specify what crate you want to build. Imagine your crate is a directory called <code>game</code>, you would use:</p> <div class="language-bash extra-class"><pre class="language-bash"><code>wasm-pack build game
</code></pre></div><p>Once wasm-pack is done building you'll have a <code>pkg</code> directory in the same directory as your crate. This has all the javascript code needed to run the WASM code. You'd then import the WASM module in javascript:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> init <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token keyword">import</span><span class="token punctuation">(</span><span class="token string">'./pkg/game.js'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><div class="note"><p>The <code>&quot;wasm-example&quot;</code> id is specific to my project (aka. this tutorial). You can substitute this for whatever id you're using in your HTML. Alternatively, you could add the canvas directly to the <code>&lt;body&gt;</code> as they do in the wgpu repo. This part is ultimately up to you.</p></div> <p>That's all the web-specific code we need for now. The next thing we need to do is build the Web Assembly itself.</p> <h2 id="wasm-pack"><a href="#wasm-pack" class="header-anchor">#</a> Wasm Pack</h2> <p>Now you can build a wgpu application with just wasm-bindgen, but I ran into some issues doing that. For one, you need to install wasm-bindgen on your computer as well as include it as a dependency. The version you install as a dependency <strong>needs</strong> to exactly match the version you installed. Otherwise, your build will fail.</p> <p>To get around this shortcoming and to make the lives of everyone reading this easier, I opted to add <a href="https://rustwasm.github.io/docs/wasm-pack/" target="_blank" rel="noopener noreferrer">wasm-pack<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 the mix. Wasm-pack handles installing the correct version of wasm-bindgen for you, and it supports building for different types of web targets as well: browser, NodeJS, and bundlers such as webpack.</p> <p>To use wasm-pack, first, you need to <a href="https://rustwasm.github.io/wasm-pack/installer/" target="_blank" rel="noopener noreferrer">install it<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>Once you've done that, we can use it to build our crate. If you only have one crate in your project, you can just use <code>wasm-pack build</code>. If you're using a workspace, you'll have to specify what crate you want to build. Imagine your crate is a directory called <code>game</code>. You would then use:</p> <div class="language-bash extra-class"><pre class="language-bash"><code>wasm-pack build game
</code></pre></div><p>Once wasm-pack is done building, you'll have a <code>pkg</code> directory in the same directory as your crate. This has all the javascript code needed to run the WASM code. You'd then import the WASM module in javascript:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> init <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token keyword">import</span><span class="token punctuation">(</span><span class="token string">'./pkg/game.js'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;WASM Loaded&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>This site uses <a href="https://vuepress.vuejs.org/" target="_blank" rel="noopener noreferrer">Vuepress<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>, so I load the WASM in a Vue component. How you handle your WASM will depend on what you want to do. If you want to check out how I'm doing things, take a look at <a href="https://github.com/sotrh/learn-wgpu/blob/master/docs/.vuepress/components/WasmExample.vue" target="_blank" rel="noopener noreferrer">this<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> <div class="note"><p>If you intend to use your WASM module in a plain HTML website, you'll need to tell wasm-pack to target the web:</p> <div class="language-bash extra-class"><pre class="language-bash"><code>wasm-pack build <span class="token parameter variable">--target</span> web
</code></pre></div><p>You'll then need to run the WASM code in an ES6 Module:</p> <div class="language-html extra-class"><pre class="language-html"><code><span class="token doctype"><span class="token punctuation">&lt;!</span><span class="token doctype-tag">DOCTYPE</span> <span class="token name">html</span><span class="token punctuation">&gt;</span></span>
@ -139,7 +139,7 @@ I won't get into the specifics of wasm-bindgen, so if you need a primer (or just
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">&gt;</span></span>
</code></pre></div></div> <p>Press the button below, and you will see the code running!</p> <div id="wasm-example"><!----> <button>Try Tutorial1_window!</button></div> <div class="auto-github-link"><a href="https://github.com/sotrh/learn-wgpu/tree/master/code/beginner/tutorial1-window/" 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:28 AM</span></div></footer> <div class="page-nav"><p class="inner"><span class="prev">
</code></pre></div></div> <p>Press the button below, and you will see the code running!</p> <div id="wasm-example"><!----> <button>Try Tutorial1_window!</button></div> <div class="auto-github-link"><a href="https://github.com/sotrh/learn-wgpu/tree/master/code/beginner/tutorial1-window/" 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:04:05 AM</span></div></footer> <div class="page-nav"><p class="inner"><span class="prev">
<a href="/learn-wgpu/" class="prev router-link-active">
Introduction
@ -148,6 +148,6 @@ I won't get into the specifics of wasm-bindgen, so if you need a primer (or just
</a>
</span></p></div> </main></div></div><div class="global-ui"><!----></div></div>
<script src="/learn-wgpu/assets/js/app.a49faced.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/55.3799ddaa.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>
<script src="/learn-wgpu/assets/js/app.99e1547a.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/55.2dadff38.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>

@ -8,7 +8,7 @@
<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.a49faced.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/41.47515217.js" as="script"><link rel="preload" href="/learn-wgpu/assets/js/33.945dce62.js" as="script"><link rel="preload" href="/learn-wgpu/assets/js/37.5ecf7ce2.js" as="script"><link rel="prefetch" href="/learn-wgpu/assets/js/10.baf5d1fe.js"><link rel="prefetch" href="/learn-wgpu/assets/js/11.b8633c49.js"><link rel="prefetch" href="/learn-wgpu/assets/js/12.0b8835f1.js"><link rel="prefetch" href="/learn-wgpu/assets/js/13.af1bbe85.js"><link rel="prefetch" href="/learn-wgpu/assets/js/14.626c7cb3.js"><link rel="prefetch" href="/learn-wgpu/assets/js/15.5a8ea302.js"><link rel="prefetch" href="/learn-wgpu/assets/js/16.f4e8226b.js"><link rel="prefetch" href="/learn-wgpu/assets/js/17.dd15c417.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.a01d50ae.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.fd4eb8d5.js"><link rel="prefetch" href="/learn-wgpu/assets/js/27.914a9a40.js"><link rel="prefetch" href="/learn-wgpu/assets/js/28.77f7d987.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.c58683af.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/34.0fe8e5e4.js"><link rel="prefetch" href="/learn-wgpu/assets/js/35.7c607f94.js"><link rel="prefetch" href="/learn-wgpu/assets/js/36.e6a8b391.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/42.4caac867.js"><link rel="prefetch" href="/learn-wgpu/assets/js/43.ac6fc643.js"><link rel="prefetch" href="/learn-wgpu/assets/js/44.27513d85.js"><link rel="prefetch" href="/learn-wgpu/assets/js/45.2ea5b108.js"><link rel="prefetch" href="/learn-wgpu/assets/js/46.e591bcb9.js"><link rel="prefetch" href="/learn-wgpu/assets/js/47.3a7bf317.js"><link rel="prefetch" href="/learn-wgpu/assets/js/48.0a15e622.js"><link rel="prefetch" href="/learn-wgpu/assets/js/49.ad5a99aa.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.48268452.js"><link rel="prefetch" href="/learn-wgpu/assets/js/53.8c976652.js"><link rel="prefetch" href="/learn-wgpu/assets/js/54.daee63ce.js"><link rel="prefetch" href="/learn-wgpu/assets/js/55.3799ddaa.js"><link rel="prefetch" href="/learn-wgpu/assets/js/56.a43d5d8e.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.24bfa87e.js"><link rel="prefetch" href="/learn-wgpu/assets/js/63.90f94cac.js"><link rel="prefetch" href="/learn-wgpu/assets/js/64.b9a310af.js"><link rel="prefetch" href="/learn-wgpu/assets/js/65.362df98e.js"><link rel="prefetch" href="/learn-wgpu/assets/js/66.ef1e3716.js"><link rel="prefetch" href="/learn-wgpu/assets/js/67.ab338058.js"><link rel="prefetch" href="/learn-wgpu/assets/js/68.d785413d.js"><link rel="prefetch" href="/learn-wgpu/assets/js/8.2c0d831a.js"><link rel="prefetch" href="/learn-wgpu/assets/js/9.985bc61a.js"><link rel="prefetch" href="/learn-wgpu/assets/js/vendors~docsearch.efa6f8ef.js">
<link rel="preload" href="/learn-wgpu/assets/css/0.styles.81cb5453.css" as="style"><link rel="preload" href="/learn-wgpu/assets/js/app.99e1547a.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/41.7e2aef8c.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.bcec92ff.js"><link rel="prefetch" href="/learn-wgpu/assets/js/27.c755f80e.js"><link rel="prefetch" href="/learn-wgpu/assets/js/28.be489186.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/30.12d50dcb.js"><link rel="prefetch" href="/learn-wgpu/assets/js/31.550259b2.js"><link rel="prefetch" href="/learn-wgpu/assets/js/32.e359d5e0.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.beae0010.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/42.6f76d27e.js"><link rel="prefetch" href="/learn-wgpu/assets/js/43.ddac8e2c.js"><link rel="prefetch" href="/learn-wgpu/assets/js/44.1486e9ca.js"><link rel="prefetch" href="/learn-wgpu/assets/js/45.2ea5b108.js"><link rel="prefetch" href="/learn-wgpu/assets/js/46.fbe2131f.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.c0f22e2e.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.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.2dadff38.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.c78dac93.js"><link rel="prefetch" href="/learn-wgpu/assets/js/61.87dce596.js"><link rel="prefetch" href="/learn-wgpu/assets/js/62.fc4967ec.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.0c2a60e3.js"><link rel="prefetch" href="/learn-wgpu/assets/js/66.a136cd48.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>
@ -68,7 +68,7 @@
<span class="token comment">// # Safety</span>
<span class="token comment">//</span>
<span class="token comment">// The surface needs to live as long as the window that created it.</span>
<span class="token comment">// State owns the window so this should be safe.</span>
<span class="token comment">// State owns the window, so this should be safe.</span>
<span class="token keyword">let</span> surface <span class="token operator">=</span> <span class="token keyword">unsafe</span> <span class="token punctuation">{</span> instance<span class="token punctuation">.</span><span class="token function">create_surface</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>window<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> adapter <span class="token operator">=</span> instance<span class="token punctuation">.</span><span class="token function">request_adapter</span><span class="token punctuation">(</span>
@ -80,18 +80,18 @@
<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token keyword">await</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 punctuation">}</span>
</code></pre></div><h3 id="instance-and-adapter"><a href="#instance-and-adapter" class="header-anchor">#</a> Instance and Adapter</h3> <p>The <code>instance</code> is the first thing you create when using wgpu. Its main purpose
is to create <code>Adapter</code>s and <code>Surface</code>s.</p> <p>The <code>adapter</code> is a handle to our actual graphics card. You can use this to get information about the graphics card such as its name and what backend the adapter uses. We use this to create our <code>Device</code> and <code>Queue</code> later. Let's discuss the fields of <code>RequestAdapterOptions</code>.</p> <ul><li><code>power_preference</code> has two variants: <code>LowPower</code>, and <code>HighPerformance</code>. <code>LowPower</code> will pick an adapter that favors battery life, such as an integrated GPU. <code>HighPerformance</code> will pick an adapter for more power-hungry yet more performant GPU's such as a dedicated graphics card. WGPU will favor <code>LowPower</code> if there is no adapter for the <code>HighPerformance</code> option.</li> <li>The <code>compatible_surface</code> field tells wgpu to find an adapter that can present to the supplied surface.</li> <li>The <code>force_fallback_adapter</code> forces wgpu to pick an adapter that will work on all hardware. This usually means that the rendering backend will use a &quot;software&quot; system, instead of hardware such as a GPU.</li></ul> <div class="note"><p>The options I've passed to <code>request_adapter</code> aren't guaranteed to work for all devices, but will work for most of them. If wgpu can't find an adapter with the required permissions, <code>request_adapter</code> will return <code>None</code>. If you want to get all adapters for a particular backend you can use <code>enumerate_adapters</code>. This will give you an iterator that you can loop over to check if one of the adapters works for your needs.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">let</span> adapter <span class="token operator">=</span> instance
is to create <code>Adapter</code>s and <code>Surface</code>s.</p> <p>The <code>adapter</code> is a handle for our actual graphics card. You can use this to get information about the graphics card, such as its name and what backend the adapter uses. We use this to create our <code>Device</code> and <code>Queue</code> later. Let's discuss the fields of <code>RequestAdapterOptions</code>.</p> <ul><li><code>power_preference</code> has two variants: <code>LowPower</code> and <code>HighPerformance</code>. <code>LowPower</code> will pick an adapter that favors battery life, such as an integrated GPU. <code>HighPerformance</code> will pick an adapter for more power-hungry yet more performant GPU's, such as a dedicated graphics card. WGPU will favor <code>LowPower</code> if there is no adapter for the <code>HighPerformance</code> option.</li> <li>The <code>compatible_surface</code> field tells wgpu to find an adapter that can present to the supplied surface.</li> <li>The <code>force_fallback_adapter</code> forces wgpu to pick an adapter that will work on all hardware. This usually means that the rendering backend will use a &quot;software&quot; system instead of hardware such as a GPU.</li></ul> <div class="note"><p>The options I've passed to <code>request_adapter</code> aren't guaranteed to work for all devices, but will work for most of them. If wgpu can't find an adapter with the required permissions, <code>request_adapter</code> will return <code>None</code>. If you want to get all adapters for a particular backend, you can use <code>enumerate_adapters</code>. This will give you an iterator that you can loop over to check if one of the adapters works for your needs.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">let</span> adapter <span class="token operator">=</span> instance
<span class="token punctuation">.</span><span class="token function">enumerate_adapters</span><span class="token punctuation">(</span><span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">Backends</span><span class="token punctuation">::</span><span class="token function">all</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">find</span><span class="token punctuation">(</span><span class="token closure-params"><span class="token closure-punctuation punctuation">|</span>adapter<span class="token closure-punctuation punctuation">|</span></span> <span class="token punctuation">{</span>
<span class="token comment">// Check if this adapter supports our surface</span>
adapter<span class="token punctuation">.</span><span class="token function">is_surface_supported</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>surface<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>
</code></pre></div><p>One thing to note is that <code>enumerate_adapters</code> isn't available on WASM, so you have to use <code>request_adapter</code>.</p> <p>Another thing to note is that <code>Adapter</code>s are locked to a specific backend. If you are on Windows and have 2 graphics cards you'll have at least 4 adapters available to use, 2 Vulkan and 2 DirectX.</p> <p>For more fields you can use to refine your search, <a href="https://docs.rs/wgpu/latest/wgpu/struct.Adapter.html" target="_blank" rel="noopener noreferrer">check out the docs<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></div> <h3 id="the-surface-2"><a href="#the-surface-2" class="header-anchor">#</a> The Surface</h3> <p>The <code>surface</code> is the part of the window that we draw to. We need it to draw directly to the screen. Our <code>window</code> needs to implement <a href="https://crates.io/crates/raw-window-handle" target="_blank" rel="noopener noreferrer">raw-window-handle<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>'s <code>HasRawWindowHandle</code> trait to create a surface. Fortunately, winit's <code>Window</code> fits the bill. We also need it to request our <code>adapter</code>.</p> <h3 id="device-and-queue"><a href="#device-and-queue" class="header-anchor">#</a> Device and Queue</h3> <p>Let's use the <code>adapter</code> to create the device and queue.</p> <div class="language-rust extra-class"><pre class="language-rust"><code> <span class="token keyword">let</span> <span class="token punctuation">(</span>device<span class="token punctuation">,</span> queue<span class="token punctuation">)</span> <span class="token operator">=</span> adapter<span class="token punctuation">.</span><span class="token function">request_device</span><span class="token punctuation">(</span>
</code></pre></div><p>One thing to note is that <code>enumerate_adapters</code> isn't available on WASM, so you have to use <code>request_adapter</code>.</p> <p>Another thing to note is that <code>Adapter</code>s are locked to a specific backend. If you are on Windows and have two graphics cards, you'll have at least four adapters available to use: 2 Vulkan and 2 DirectX.</p> <p>For more fields you can use to refine your search, <a href="https://docs.rs/wgpu/latest/wgpu/struct.Adapter.html" target="_blank" rel="noopener noreferrer">check out the docs<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></div> <h3 id="the-surface-2"><a href="#the-surface-2" class="header-anchor">#</a> The Surface</h3> <p>The <code>surface</code> is the part of the window that we draw to. We need it to draw directly to the screen. Our <code>window</code> needs to implement <a href="https://crates.io/crates/raw-window-handle" target="_blank" rel="noopener noreferrer">raw-window-handle<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>'s <code>HasRawWindowHandle</code> trait to create a surface. Fortunately, winit's <code>Window</code> fits the bill. We also need it to request our <code>adapter</code>.</p> <h3 id="device-and-queue"><a href="#device-and-queue" class="header-anchor">#</a> Device and Queue</h3> <p>Let's use the <code>adapter</code> to create the device and queue.</p> <div class="language-rust extra-class"><pre class="language-rust"><code> <span class="token keyword">let</span> <span class="token punctuation">(</span>device<span class="token punctuation">,</span> queue<span class="token punctuation">)</span> <span class="token operator">=</span> adapter<span class="token punctuation">.</span><span class="token function">request_device</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">DeviceDescriptor</span> <span class="token punctuation">{</span>
features<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">Features</span><span class="token punctuation">::</span><span class="token function">empty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token comment">// WebGL doesn't support all of wgpu's features, so if</span>
<span class="token comment">// we're building for the web we'll have to disable some.</span>
<span class="token comment">// we're building for the web, we'll have to disable some.</span>
limits<span class="token punctuation">:</span> <span class="token keyword">if</span> <span class="token macro property">cfg!</span><span class="token punctuation">(</span>target_arch <span class="token operator">=</span> <span class="token string">&quot;wasm32&quot;</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">Limits</span><span class="token punctuation">::</span><span class="token function">downlevel_webgl2_defaults</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
@ -101,9 +101,9 @@ is to create <code>Adapter</code>s and <code>Surface</code>s.</p> <p>The <code>a
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token class-name">None</span><span class="token punctuation">,</span> <span class="token comment">// Trace path</span>
<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token keyword">await</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>
</code></pre></div><p>The <code>features</code> field on <code>DeviceDescriptor</code>, allows us to specify what extra features we want. For this simple example, I've decided not to use any extra features.</p> <div class="note"><p>The graphics card you have limits the features you can use. If you want to use certain features you may need to limit what devices you support or provide workarounds.</p> <p>You can get a list of features supported by your device using <code>adapter.features()</code>, or <code>device.features()</code>.</p> <p>You can view a full list of features <a href="https://docs.rs/wgpu/latest/wgpu/struct.Features.html" target="_blank" rel="noopener noreferrer">here<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></div> <p>The <code>limits</code> field describes the limit of certain types of resources that we can create. We'll use the defaults for this tutorial, so we can support most devices. You can view a list of limits <a href="https://docs.rs/wgpu/latest/wgpu/struct.Limits.html" target="_blank" rel="noopener noreferrer">here<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> <div class="language-rust extra-class"><pre class="language-rust"><code> <span class="token keyword">let</span> surface_caps <span class="token operator">=</span> surface<span class="token punctuation">.</span><span class="token function">get_capabilities</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>adapter<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>The <code>features</code> field on <code>DeviceDescriptor</code> allows us to specify what extra features we want. For this simple example, I've decided not to use any extra features.</p> <div class="note"><p>The graphics card you have limits the features you can use. If you want to use certain features, you may need to limit what devices you support or provide workarounds.</p> <p>You can get a list of features supported by your device using <code>adapter.features()</code> or <code>device.features()</code>.</p> <p>You can view a full list of features <a href="https://docs.rs/wgpu/latest/wgpu/struct.Features.html" target="_blank" rel="noopener noreferrer">here<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></div> <p>The <code>limits</code> field describes the limit of certain types of resources that we can create. We'll use the defaults for this tutorial so we can support most devices. You can view a list of limits <a href="https://docs.rs/wgpu/latest/wgpu/struct.Limits.html" target="_blank" rel="noopener noreferrer">here<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> <div class="language-rust extra-class"><pre class="language-rust"><code> <span class="token keyword">let</span> surface_caps <span class="token operator">=</span> surface<span class="token punctuation">.</span><span class="token function">get_capabilities</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>adapter<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// Shader code in this tutorial assumes an sRGB surface texture. Using a different</span>
<span class="token comment">// one will result all the colors coming out darker. If you want to support non</span>
<span class="token comment">// one will result in all the colors coming out darker. If you want to support non</span>
<span class="token comment">// sRGB surfaces, you'll need to account for that when drawing to the frame.</span>
<span class="token keyword">let</span> surface_format <span class="token operator">=</span> surface_caps<span class="token punctuation">.</span>formats<span class="token punctuation">.</span><span class="token function">iter</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">copied</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
@ -119,10 +119,10 @@ is to create <code>Adapter</code>s and <code>Surface</code>s.</p> <p>The <code>a
view_formats<span class="token punctuation">:</span> <span class="token macro property">vec!</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>
surface<span class="token punctuation">.</span><span class="token function">configure</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>device<span class="token punctuation">,</span> <span class="token operator">&amp;</span>config<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>Here we are defining a config for our surface. This will define how the surface creates its underlying <code>SurfaceTexture</code>s. We will talk about <code>SurfaceTexture</code> when we get to the <code>render</code> function. For now, let's talk about the config's fields.</p> <p>The <code>usage</code> field describes how <code>SurfaceTexture</code>s will be used. <code>RENDER_ATTACHMENT</code> specifies that the textures will be used to write to the screen (we'll talk about more <code>TextureUsages</code>s later).</p> <p>The <code>format</code> defines how <code>SurfaceTexture</code>s will be stored on the gpu. We can get a supported format from the <code>SurfaceCapabilities</code>.</p> <p><code>width</code> and <code>height</code> are the width and the height in pixels of a <code>SurfaceTexture</code>. This should usually be the width and the height of the window.</p> <div class="warning">
</code></pre></div><p>Here we are defining a config for our surface. This will define how the surface creates its underlying <code>SurfaceTexture</code>s. We will talk about <code>SurfaceTexture</code> when we get to the <code>render</code> function. For now, let's talk about the config's fields.</p> <p>The <code>usage</code> field describes how <code>SurfaceTexture</code>s will be used. <code>RENDER_ATTACHMENT</code> specifies that the textures will be used to write to the screen (we'll talk about more <code>TextureUsages</code>s later).</p> <p>The <code>format</code> defines how <code>SurfaceTexture</code>s will be stored on the GPU. We can get a supported format from the <code>SurfaceCapabilities</code>.</p> <p><code>width</code> and <code>height</code> are the width and the height in pixels of a <code>SurfaceTexture</code>. This should usually be the width and the height of the window.</p> <div class="warning">
Make sure that the width and height of the `SurfaceTexture` are not 0, as that can cause your app to crash.
</div> <p><code>present_mode</code> uses <code>wgpu::PresentMode</code> enum which determines how to sync the surface with the display. The option we picked, <code>PresentMode::Fifo</code>, will cap the display rate at the display's framerate. This is essentially VSync. This mode is guaranteed to be supported on all platforms. There are other options and you can see all of them <a href="https://docs.rs/wgpu/latest/wgpu/enum.PresentMode.html" target="_blank" rel="noopener noreferrer">in the docs<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> <div class="note"><p>If you want to let your users pick what <code>PresentMode</code> they use, you can use <a href="https://docs.rs/wgpu/latest/wgpu/struct.SurfaceCapabilities.html#structfield.present_modes" target="_blank" rel="noopener noreferrer">SurfaceCapabilities::present_modes<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 get a list of all the <code>PresentMode</code>s the surface supports:</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">let</span> modes <span class="token operator">=</span> <span class="token operator">&amp;</span>surface_caps<span class="token punctuation">.</span>present_modes<span class="token punctuation">;</span>
</code></pre></div><p>Regardless, <code>PresentMode::Fifo</code> will always be supported, and <code>PresentMode::AutoVsync</code> and <code>PresentMode::AutoNoVsync</code> have fallback support and therefore will work on all platforms.</p></div> <p><code>alpha_mode</code> is honestly not something I'm familiar with. I believe it has something to do with transparent windows, but feel free to open a pull request. For now we'll just use the first <code>AlphaMode</code> in the list given by <code>surface_caps</code>.</p> <p><code>view_formats</code> is a list of <code>TextureFormat</code>s that you can use when creating <code>TextureView</code>s (we'll cover those briefly later in this tutorial as well as more in depth <a href="../tutorial5-textures">in the texture tutorial</a>). As of writing this means that if your surface is srgb color space, you can create a texture view that uses a linear color space.</p> <p>Now that we've configured our surface properly we can add these new fields at the end of the method.</p> <div class="language-rust extra-class"><pre class="language-rust"><code> <span class="token keyword">async</span> <span class="token keyword">fn</span> <span class="token function-definition function">new</span><span class="token punctuation">(</span>window<span class="token punctuation">:</span> <span class="token class-name">Window</span><span class="token punctuation">)</span> <span class="token punctuation">-&gt;</span> <span class="token keyword">Self</span> <span class="token punctuation">{</span>
</div> <p><code>present_mode</code> uses <code>wgpu::PresentMode</code> enum, which determines how to sync the surface with the display. The option we picked, <code>PresentMode::Fifo</code>, will cap the display rate at the display's framerate. This is essentially VSync. This mode is guaranteed to be supported on all platforms. There are other options, and you can see all of them <a href="https://docs.rs/wgpu/latest/wgpu/enum.PresentMode.html" target="_blank" rel="noopener noreferrer">in the docs<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> <div class="note"><p>If you want to let your users pick what <code>PresentMode</code> they use, you can use <a href="https://docs.rs/wgpu/latest/wgpu/struct.SurfaceCapabilities.html#structfield.present_modes" target="_blank" rel="noopener noreferrer">SurfaceCapabilities::present_modes<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 get a list of all the <code>PresentMode</code>s the surface supports:</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">let</span> modes <span class="token operator">=</span> <span class="token operator">&amp;</span>surface_caps<span class="token punctuation">.</span>present_modes<span class="token punctuation">;</span>
</code></pre></div><p>Regardless, <code>PresentMode::Fifo</code> will always be supported, and <code>PresentMode::AutoVsync</code> and <code>PresentMode::AutoNoVsync</code> have fallback support and therefore will work on all platforms.</p></div> <p><code>alpha_mode</code> is honestly not something I'm familiar with. I believe it has something to do with transparent windows, but feel free to open a pull request. For now, we'll just use the first <code>AlphaMode</code> in the list given by <code>surface_caps</code>.</p> <p><code>view_formats</code> is a list of <code>TextureFormat</code>s that you can use when creating <code>TextureView</code>s (we'll cover those briefly later in this tutorial as well as more in depth <a href="../tutorial5-textures">in the texture tutorial</a>). As of writing, this means that if your surface is sRGB color space, you can create a texture view that uses a linear color space.</p> <p>Now that we've configured our surface properly, we can add these new fields at the end of the method.</p> <div class="language-rust extra-class"><pre class="language-rust"><code> <span class="token keyword">async</span> <span class="token keyword">fn</span> <span class="token function-definition function">new</span><span class="token punctuation">(</span>window<span class="token punctuation">:</span> <span class="token class-name">Window</span><span class="token punctuation">)</span> <span class="token punctuation">-&gt;</span> <span class="token keyword">Self</span> <span class="token punctuation">{</span>
<span class="token comment">// ...</span>
<span class="token keyword">Self</span> <span class="token punctuation">{</span>
@ -134,7 +134,7 @@ Make sure that the width and height of the `SurfaceTexture` are not 0, as that c
size<span class="token punctuation">,</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>Since our <code>State::new()</code> method is async we need to change <code>run()</code> to be async as well so that we can await it.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">pub</span> <span class="token keyword">async</span> <span class="token keyword">fn</span> <span class="token function-definition function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
</code></pre></div><p>Since our <code>State::new()</code> method is async, we need to change <code>run()</code> to be async as well so that we can await it.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">pub</span> <span class="token keyword">async</span> <span class="token keyword">fn</span> <span class="token function-definition function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// Window setup...</span>
<span class="token keyword">let</span> <span class="token keyword">mut</span> state <span class="token operator">=</span> <span class="token class-name">State</span><span class="token punctuation">::</span><span class="token function">new</span><span class="token punctuation">(</span>window<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token keyword">await</span><span class="token punctuation">;</span>
@ -147,7 +147,7 @@ Make sure that the width and height of the `SurfaceTexture` are not 0, as that c
</code></pre></div><p>We then use the <code>block_on</code> function provided by pollster to await our future:</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">fn</span> <span class="token function-definition function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token namespace">pollster<span class="token punctuation">::</span></span><span class="token function">block_on</span><span class="token punctuation">(</span><span class="token function">run</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="warning"><p>Don't use <code>block_on</code> inside of an async function if you plan to support WASM. Futures have to be run using the browser's executor. If you try to bring your own your code will crash when you encounter a future that doesn't execute immediately.</p></div> <p>If we try to build WASM now it will fail because <code>wasm-bindgen</code> doesn't support using async functions as <code>start</code> methods. You could switch to calling <code>run</code> manually in javascript, but for simplicity, we'll add the <a href="https://docs.rs/wasm-bindgen-futures" target="_blank" rel="noopener noreferrer">wasm-bindgen-futures<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> crate to our WASM dependencies as that doesn't require us to change any code. Your dependencies should look something like this:</p> <div class="language-toml extra-class"><pre class="language-toml"><code><span class="token punctuation">[</span><span class="token table class-name">dependencies</span><span class="token punctuation">]</span>
</code></pre></div><div class="warning"><p>Don't use <code>block_on</code> inside of an async function if you plan to support WASM. Futures have to be run using the browser's executor. If you try to bring your own, your code will crash when you encounter a future that doesn't execute immediately.</p></div> <p>If we try to build WASM now, it will fail because <code>wasm-bindgen</code> doesn't support using async functions as <code>start</code> methods. You could switch to calling <code>run</code> manually in javascript, but for simplicity, we'll add the <a href="https://docs.rs/wasm-bindgen-futures" target="_blank" rel="noopener noreferrer">wasm-bindgen-futures<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> crate to our WASM dependencies as that doesn't require us to change any code. Your dependencies should look something like this:</p> <div class="language-toml extra-class"><pre class="language-toml"><code><span class="token punctuation">[</span><span class="token table class-name">dependencies</span><span class="token punctuation">]</span>
<span class="token key property">cfg-if</span> <span class="token punctuation">=</span> <span class="token string">&quot;1&quot;</span>
<span class="token key property">winit</span> <span class="token punctuation">=</span> <span class="token string">&quot;0.28&quot;</span>
<span class="token key property">env_logger</span> <span class="token punctuation">=</span> <span class="token string">&quot;0.10&quot;</span>
@ -175,7 +175,7 @@ Make sure that the width and height of the `SurfaceTexture` are not 0, as that c
<span class="token keyword">self</span><span class="token punctuation">.</span>surface<span class="token punctuation">.</span><span class="token function">configure</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token keyword">self</span><span class="token punctuation">.</span>device<span class="token punctuation">,</span> <span class="token operator">&amp;</span><span class="token keyword">self</span><span class="token punctuation">.</span>config<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>There's nothing different here from the initial <code>surface</code> configuration, so I won't get into it.</p> <p>We call this method in <code>run()</code> in the event loop for the following events.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">match</span> event <span class="token punctuation">{</span>
</code></pre></div><p>There's nothing different here from the initial <code>surface</code> configuration, so I won't get into it.</p> <p>We call this method <code>run()</code> in the event loop for the following events.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">match</span> event <span class="token punctuation">{</span>
<span class="token comment">// ...</span>
<span class="token punctuation">}</span> <span class="token keyword">if</span> window_id <span class="token operator">==</span> state<span class="token punctuation">.</span><span class="token function">window</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">id</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
@ -197,7 +197,7 @@ Make sure that the width and height of the `SurfaceTexture` are not 0, as that c
<span class="token keyword">fn</span> <span class="token function-definition function">input</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token keyword">mut</span> <span class="token keyword">self</span><span class="token punctuation">,</span> event<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token class-name">WindowEvent</span><span class="token punctuation">)</span> <span class="token punctuation">-&gt;</span> <span class="token keyword">bool</span> <span class="token punctuation">{</span>
<span class="token boolean">false</span>
<span class="token punctuation">}</span>
</code></pre></div><p>We need to do a little more work in the event loop. We want <code>State</code> to have priority over <code>run()</code>. Doing that (and previous changes) should have your loop looking like this.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token comment">// run()</span>
</code></pre></div><p>We need to do a little more work in the event loop. We want <code>State</code> to have priority over <code>run()</code>. Doing that (and previous changes) should make your loop look like this.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token comment">// run()</span>
event_loop<span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token keyword">move</span> <span class="token closure-params"><span class="token closure-punctuation punctuation">|</span>event<span class="token punctuation">,</span> _<span class="token punctuation">,</span> control_flow<span class="token closure-punctuation punctuation">|</span></span> <span class="token punctuation">{</span>
<span class="token keyword">match</span> event <span class="token punctuation">{</span>
<span class="token class-name">Event</span><span class="token punctuation">::</span><span class="token class-name">WindowEvent</span> <span class="token punctuation">{</span>
@ -235,10 +235,10 @@ event_loop<span class="token punctuation">.</span><span class="token function">r
<span class="token keyword">fn</span> <span class="token function-definition function">render</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token keyword">mut</span> <span class="token keyword">self</span><span class="token punctuation">)</span> <span class="token punctuation">-&gt;</span> <span class="token class-name">Result</span><span class="token operator">&lt;</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">SurfaceError</span><span class="token operator">&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword">let</span> output <span class="token operator">=</span> <span class="token keyword">self</span><span class="token punctuation">.</span>surface<span class="token punctuation">.</span><span class="token function">get_current_texture</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">?</span><span class="token punctuation">;</span>
</code></pre></div><p>The <code>get_current_texture</code> function will wait for the <code>surface</code> to provide a new <code>SurfaceTexture</code> that we will render to. We'll store this in <code>output</code> for later.</p> <div class="language-rust extra-class"><pre class="language-rust"><code> <span class="token keyword">let</span> view <span class="token operator">=</span> output<span class="token punctuation">.</span>texture<span class="token punctuation">.</span><span class="token function">create_view</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">TextureViewDescriptor</span><span class="token punctuation">::</span><span class="token function">default</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>This line creates a <code>TextureView</code> with default settings. We need to do this because we want to control how the render code interacts with the texture.</p> <p>We also need to create a <code>CommandEncoder</code> to create the actual commands to send to the gpu. Most modern graphics frameworks expect commands to be stored in a command buffer before being sent to the gpu. The <code>encoder</code> builds a command buffer that we can then send to the gpu.</p> <div class="language-rust extra-class"><pre class="language-rust"><code> <span class="token keyword">let</span> <span class="token keyword">mut</span> encoder <span class="token operator">=</span> <span class="token keyword">self</span><span class="token punctuation">.</span>device<span class="token punctuation">.</span><span class="token function">create_command_encoder</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">CommandEncoderDescriptor</span> <span class="token punctuation">{</span>
</code></pre></div><p>This line creates a <code>TextureView</code> with default settings. We need to do this because we want to control how the render code interacts with the texture.</p> <p>We also need to create a <code>CommandEncoder</code> to create the actual commands to send to the GPU. Most modern graphics frameworks expect commands to be stored in a command buffer before being sent to the GPU. The <code>encoder</code> builds a command buffer that we can then send to the GPU.</p> <div class="language-rust extra-class"><pre class="language-rust"><code> <span class="token keyword">let</span> <span class="token keyword">mut</span> encoder <span class="token operator">=</span> <span class="token keyword">self</span><span class="token punctuation">.</span>device<span class="token punctuation">.</span><span class="token function">create_command_encoder</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">CommandEncoderDescriptor</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;Render Encoder&quot;</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>Now we can get to clearing the screen (long time coming). We need to use the <code>encoder</code> to create a <code>RenderPass</code>. The <code>RenderPass</code> has all the methods for the actual drawing. The code for creating a <code>RenderPass</code> is a bit nested, so I'll copy it all here before talking about its pieces.</p> <div class="language-rust extra-class"><pre class="language-rust"><code> <span class="token punctuation">{</span>
</code></pre></div><p>Now we can get to clearing the screen (a long time coming). We need to use the <code>encoder</code> to create a <code>RenderPass</code>. The <code>RenderPass</code> has all the methods for the actual drawing. The code for creating a <code>RenderPass</code> is a bit nested, so I'll copy it all here before talking about its pieces.</p> <div class="language-rust extra-class"><pre class="language-rust"><code> <span class="token punctuation">{</span>
<span class="token keyword">let</span> _render_pass <span class="token operator">=</span> encoder<span class="token punctuation">.</span><span class="token function">begin_render_pass</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">RenderPassDescriptor</span> <span class="token punctuation">{</span>
label<span class="token punctuation">:</span> <span class="token class-name">Some</span><span class="token punctuation">(</span><span class="token string">&quot;Render Pass&quot;</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
color_attachments<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token punctuation">[</span><span class="token class-name">Some</span><span class="token punctuation">(</span><span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">RenderPassColorAttachment</span> <span class="token punctuation">{</span>
@ -266,7 +266,7 @@ event_loop<span class="token punctuation">.</span><span class="token function">r
<span class="token class-name">Ok</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>First things first, let's talk about the extra block (<code>{}</code>) around <code>encoder.begin_render_pass(...)</code>. <code>begin_render_pass()</code> borrows <code>encoder</code> mutably (aka <code>&amp;mut self</code>). We can't call <code>encoder.finish()</code> until we release that mutable borrow. The block tells rust to drop any variables within it when the code leaves that scope thus releasing the mutable borrow on <code>encoder</code> and allowing us to <code>finish()</code> it. If you don't like the <code>{}</code>, you can also use <code>drop(render_pass)</code> to achieve the same effect.</p> <p>The last lines of the code tell <code>wgpu</code> to finish the command buffer, and to submit it to the gpu's render queue.</p> <p>We need to update the event loop again to call this method. We'll also call <code>update()</code> before it too.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token comment">// run()</span>
</code></pre></div><p>First things first, let's talk about the extra block (<code>{}</code>) around <code>encoder.begin_render_pass(...)</code>. <code>begin_render_pass()</code> borrows <code>encoder</code> mutably (aka <code>&amp;mut self</code>). We can't call <code>encoder.finish()</code> until we release that mutable borrow. The block tells Rust to drop any variables within it when the code leaves that scope, thus releasing the mutable borrow on <code>encoder</code> and allowing us to <code>finish()</code> it. If you don't like the <code>{}</code>, you can also use <code>drop(render_pass)</code> to achieve the same effect.</p> <p>The last lines of the code tell <code>wgpu</code> to finish the command buffer and submit it to the GPU's render queue.</p> <p>We need to update the event loop again to call this method. We'll also call <code>update()</code> before it, too.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token comment">// run()</span>
event_loop<span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token keyword">move</span> <span class="token closure-params"><span class="token closure-punctuation punctuation">|</span>event<span class="token punctuation">,</span> _<span class="token punctuation">,</span> control_flow<span class="token closure-punctuation punctuation">|</span></span> <span class="token punctuation">{</span>
<span class="token keyword">match</span> event <span class="token punctuation">{</span>
<span class="token comment">// ...</span>
@ -283,7 +283,7 @@ event_loop<span class="token punctuation">.</span><span class="token function">r
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token class-name">Event</span><span class="token punctuation">::</span><span class="token class-name">MainEventsCleared</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
<span class="token comment">// RedrawRequested will only trigger once, unless we manually</span>
<span class="token comment">// RedrawRequested will only trigger once unless we manually</span>
<span class="token comment">// request it.</span>
state<span class="token punctuation">.</span><span class="token function">window</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">request_redraw</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
@ -297,7 +297,7 @@ event_loop<span class="token punctuation">.</span><span class="token function">r
<span class="token punctuation">]</span><span class="token punctuation">,</span>
depth_stencil_attachment<span class="token punctuation">:</span> <span class="token class-name">None</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
</code></pre></div><p>A <code>RenderPassDescriptor</code> only has three fields: <code>label</code>, <code>color_attachments</code> and <code>depth_stencil_attachment</code>. The <code>color_attachments</code> describe where we are going to draw our color to. We use the <code>TextureView</code> we created earlier to make sure that we render to the screen.</p> <div class="note"><p>The <code>color_attachments</code> field is a &quot;sparse&quot; array. This allows you to use a pipeline that expects multiple render targets and only supply the ones you care about.</p></div> <p>We'll use <code>depth_stencil_attachment</code> later, but we'll set it to <code>None</code> for now.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token class-name">Some</span><span class="token punctuation">(</span><span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">RenderPassColorAttachment</span> <span class="token punctuation">{</span>
</code></pre></div><p>A <code>RenderPassDescriptor</code> only has three fields: <code>label</code>, <code>color_attachments</code> and <code>depth_stencil_attachment</code>. The <code>color_attachments</code> describe where we are going to draw our color to. We use the <code>TextureView</code> we created earlier to make sure that we render to the screen.</p> <div class="note"><p>The <code>color_attachments</code> field is a &quot;sparse&quot; array. This allows you to use a pipeline that expects multiple render targets and only supplies the ones you care about.</p></div> <p>We'll use <code>depth_stencil_attachment</code> later, but we'll set it to <code>None</code> for now.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token class-name">Some</span><span class="token punctuation">(</span><span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">RenderPassColorAttachment</span> <span class="token punctuation">{</span>
view<span class="token punctuation">:</span> <span class="token operator">&amp;</span>view<span class="token punctuation">,</span>
resolve_target<span class="token punctuation">:</span> <span class="token class-name">None</span><span class="token punctuation">,</span>
ops<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">Operations</span> <span class="token punctuation">{</span>
@ -310,7 +310,7 @@ event_loop<span class="token punctuation">.</span><span class="token function">r
store<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">StoreOp</span><span class="token punctuation">::</span><span class="token class-name">Store</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p>The <code>RenderPassColorAttachment</code> has the <code>view</code> field which informs <code>wgpu</code> what texture to save the colors to. In this case we specify the <code>view</code> that we created using <code>surface.get_current_texture()</code>. This means that any colors we draw to this attachment will get drawn to the screen.</p> <p>The <code>resolve_target</code> is the texture that will receive the resolved output. This will be the same as <code>view</code> unless multisampling is enabled. We don't need to specify this, so we leave it as <code>None</code>.</p> <p>The <code>ops</code> field takes a <code>wpgu::Operations</code> object. This tells wgpu what to do with the colors on the screen (specified by <code>view</code>). The <code>load</code> field tells wgpu how to handle colors stored from the previous frame. Currently, we are clearing the screen with a bluish color. The <code>store</code> field tells wgpu whether we want to store the rendered results to the <code>Texture</code> behind our <code>TextureView</code> (in this case it's the <code>SurfaceTexture</code>). We use <code>true</code> as we do want to store our render results.</p> <div class="note"><p>It's not uncommon to not clear the screen if the screen is going to be completely covered up with objects. If your scene doesn't cover the entire screen however you can end up with something like this.</p> <p><img src="/learn-wgpu/assets/img/no-clear.753f913f.png" alt="./no-clear.png"></p></div> <h2 id="validation-errors"><a href="#validation-errors" class="header-anchor">#</a> Validation Errors?</h2> <p>If wgpu is using Vulkan on your machine, you may run into validation errors if you are running an older version of the Vulkan SDK. You should be using at least version <code>1.2.182</code> as older versions can give out some false positives. If errors persist, you may have encountered a bug in wgpu. You can post an issue at <a href="https://github.com/gfx-rs/wgpu" target="_blank" rel="noopener noreferrer">https://github.com/gfx-rs/wgpu<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> <h2 id="challenge"><a href="#challenge" class="header-anchor">#</a> Challenge</h2> <p>Modify the <code>input()</code> method to capture mouse events, and update the clear color using that. <em>Hint: you'll probably need to use <code>WindowEvent::CursorMoved</code></em>.</p> <div id="wasm-example"><!----> <button>Try Tutorial2_surface!</button></div> <div class="auto-github-link"><a href="https://github.com/sotrh/learn-wgpu/tree/master/code/beginner/tutorial2-surface/" 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:28 AM</span></div></footer> <div class="page-nav"><p class="inner"><span class="prev">
</code></pre></div><p>The <code>RenderPassColorAttachment</code> has the <code>view</code> field, which informs <code>wgpu</code> what texture to save the colors to. In this case, we specify the <code>view</code> that we created using <code>surface.get_current_texture()</code>. This means that any colors we draw to this attachment will get drawn to the screen.</p> <p>The <code>resolve_target</code> is the texture that will receive the resolved output. This will be the same as <code>view</code> unless multisampling is enabled. We don't need to specify this, so we leave it as <code>None</code>.</p> <p>The <code>ops</code> field takes a <code>wpgu::Operations</code> object. This tells wgpu what to do with the colors on the screen (specified by <code>view</code>). The <code>load</code> field tells wgpu how to handle colors stored from the previous frame. Currently, we are clearing the screen with a bluish color. The <code>store</code> field tells wgpu whether we want to store the rendered results to the <code>Texture</code> behind our <code>TextureView</code> (in this case, it's the <code>SurfaceTexture</code>). We use <code>true</code> as we do want to store our render results.</p> <div class="note"><p>It's not uncommon to not clear the screen if the screen is going to be completely covered up with objects. If your scene doesn't cover the entire screen, however, you can end up with something like this.</p> <p><img src="/learn-wgpu/assets/img/no-clear.753f913f.png" alt="./no-clear.png"></p></div> <h2 id="validation-errors"><a href="#validation-errors" class="header-anchor">#</a> Validation Errors?</h2> <p>If wgpu is using Vulkan on your machine, you may run into validation errors if you are running an older version of the Vulkan SDK. You should be using at least version <code>1.2.182</code> as older versions can give out some false positives. If errors persist, you may have encountered a bug in wgpu. You can post an issue at <a href="https://github.com/gfx-rs/wgpu" target="_blank" rel="noopener noreferrer">https://github.com/gfx-rs/wgpu<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> <h2 id="challenge"><a href="#challenge" class="header-anchor">#</a> Challenge</h2> <p>Modify the <code>input()</code> method to capture mouse events, and update the clear color using that. <em>Hint: you'll probably need to use <code>WindowEvent::CursorMoved</code></em>.</p> <div id="wasm-example"><!----> <button>Try Tutorial2_surface!</button></div> <div class="auto-github-link"><a href="https://github.com/sotrh/learn-wgpu/tree/master/code/beginner/tutorial2-surface/" 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:04:05 AM</span></div></footer> <div class="page-nav"><p class="inner"><span class="prev">
<a href="/learn-wgpu/beginner/tutorial1-window/" class="prev">
Dependencies and the window
@ -319,6 +319,6 @@ event_loop<span class="token punctuation">.</span><span class="token function">r
</a>
</span></p></div> </main></div></div><div class="global-ui"><!----></div></div>
<script src="/learn-wgpu/assets/js/app.a49faced.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/41.47515217.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>
<script src="/learn-wgpu/assets/js/app.99e1547a.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/41.7e2aef8c.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>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -8,7 +8,7 @@
<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.a49faced.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/47.3a7bf317.js" as="script"><link rel="preload" href="/learn-wgpu/assets/js/33.945dce62.js" as="script"><link rel="preload" href="/learn-wgpu/assets/js/37.5ecf7ce2.js" as="script"><link rel="prefetch" href="/learn-wgpu/assets/js/10.baf5d1fe.js"><link rel="prefetch" href="/learn-wgpu/assets/js/11.b8633c49.js"><link rel="prefetch" href="/learn-wgpu/assets/js/12.0b8835f1.js"><link rel="prefetch" href="/learn-wgpu/assets/js/13.af1bbe85.js"><link rel="prefetch" href="/learn-wgpu/assets/js/14.626c7cb3.js"><link rel="prefetch" href="/learn-wgpu/assets/js/15.5a8ea302.js"><link rel="prefetch" href="/learn-wgpu/assets/js/16.f4e8226b.js"><link rel="prefetch" href="/learn-wgpu/assets/js/17.dd15c417.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.a01d50ae.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.fd4eb8d5.js"><link rel="prefetch" href="/learn-wgpu/assets/js/27.914a9a40.js"><link rel="prefetch" href="/learn-wgpu/assets/js/28.77f7d987.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.c58683af.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/34.0fe8e5e4.js"><link rel="prefetch" href="/learn-wgpu/assets/js/35.7c607f94.js"><link rel="prefetch" href="/learn-wgpu/assets/js/36.e6a8b391.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.47515217.js"><link rel="prefetch" href="/learn-wgpu/assets/js/42.4caac867.js"><link rel="prefetch" href="/learn-wgpu/assets/js/43.ac6fc643.js"><link rel="prefetch" href="/learn-wgpu/assets/js/44.27513d85.js"><link rel="prefetch" href="/learn-wgpu/assets/js/45.2ea5b108.js"><link rel="prefetch" href="/learn-wgpu/assets/js/46.e591bcb9.js"><link rel="prefetch" href="/learn-wgpu/assets/js/48.0a15e622.js"><link rel="prefetch" href="/learn-wgpu/assets/js/49.ad5a99aa.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.48268452.js"><link rel="prefetch" href="/learn-wgpu/assets/js/53.8c976652.js"><link rel="prefetch" href="/learn-wgpu/assets/js/54.daee63ce.js"><link rel="prefetch" href="/learn-wgpu/assets/js/55.3799ddaa.js"><link rel="prefetch" href="/learn-wgpu/assets/js/56.a43d5d8e.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.24bfa87e.js"><link rel="prefetch" href="/learn-wgpu/assets/js/63.90f94cac.js"><link rel="prefetch" href="/learn-wgpu/assets/js/64.b9a310af.js"><link rel="prefetch" href="/learn-wgpu/assets/js/65.362df98e.js"><link rel="prefetch" href="/learn-wgpu/assets/js/66.ef1e3716.js"><link rel="prefetch" href="/learn-wgpu/assets/js/67.ab338058.js"><link rel="prefetch" href="/learn-wgpu/assets/js/68.d785413d.js"><link rel="prefetch" href="/learn-wgpu/assets/js/8.2c0d831a.js"><link rel="prefetch" href="/learn-wgpu/assets/js/9.985bc61a.js"><link rel="prefetch" href="/learn-wgpu/assets/js/vendors~docsearch.efa6f8ef.js">
<link rel="preload" href="/learn-wgpu/assets/css/0.styles.81cb5453.css" as="style"><link rel="preload" href="/learn-wgpu/assets/js/app.99e1547a.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/47.22e16c22.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.bcec92ff.js"><link rel="prefetch" href="/learn-wgpu/assets/js/27.c755f80e.js"><link rel="prefetch" href="/learn-wgpu/assets/js/28.be489186.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/30.12d50dcb.js"><link rel="prefetch" href="/learn-wgpu/assets/js/31.550259b2.js"><link rel="prefetch" href="/learn-wgpu/assets/js/32.e359d5e0.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.beae0010.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.7e2aef8c.js"><link rel="prefetch" href="/learn-wgpu/assets/js/42.6f76d27e.js"><link rel="prefetch" href="/learn-wgpu/assets/js/43.ddac8e2c.js"><link rel="prefetch" href="/learn-wgpu/assets/js/44.1486e9ca.js"><link rel="prefetch" href="/learn-wgpu/assets/js/45.2ea5b108.js"><link rel="prefetch" href="/learn-wgpu/assets/js/46.fbe2131f.js"><link rel="prefetch" href="/learn-wgpu/assets/js/48.7d70df25.js"><link rel="prefetch" href="/learn-wgpu/assets/js/49.c0f22e2e.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.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.2dadff38.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.c78dac93.js"><link rel="prefetch" href="/learn-wgpu/assets/js/61.87dce596.js"><link rel="prefetch" href="/learn-wgpu/assets/js/62.fc4967ec.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.0c2a60e3.js"><link rel="prefetch" href="/learn-wgpu/assets/js/66.a136cd48.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>
@ -18,7 +18,7 @@
base_vertex<span class="token punctuation">:</span> <span class="token keyword">i32</span><span class="token punctuation">,</span>
instances<span class="token punctuation">:</span> <span class="token class-name">Range</span><span class="token operator">&lt;</span><span class="token keyword">u32</span><span class="token operator">&gt;</span> <span class="token comment">// &lt;-- This right here</span>
<span class="token punctuation">)</span>
</code></pre></div><p>The <code>instances</code> parameter takes a <code>Range&lt;u32&gt;</code>. This parameter tells the GPU how many copies, or instances, of the model we want to draw. Currently, we are specifying <code>0..1</code>, which instructs the GPU to draw our model once, and then stop. If we used <code>0..5</code>, our code would draw 5 instances.</p> <p>The fact that <code>instances</code> is a <code>Range&lt;u32&gt;</code> may seem weird as using <code>1..2</code> for instances would still draw 1 instance of our object. Seems like it would be simpler to just use a <code>u32</code> right? The reason it's a range is that sometimes we don't want to draw <strong>all</strong> of our objects. Sometimes we want to draw a selection of them, because others are not in frame, or we are debugging and want to look at a particular set of instances.</p> <p>Ok, now we know how to draw multiple instances of an object, how do we tell wgpu what particular instance to draw? We are going to use something known as an instance buffer.</p> <h2 id="the-instance-buffer"><a href="#the-instance-buffer" class="header-anchor">#</a> The Instance Buffer</h2> <p>We'll create an instance buffer in a similar way to how we create a uniform buffer. First, we'll create a struct called <code>Instance</code>.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token comment">// lib.rs</span>
</code></pre></div><p>The <code>instances</code> parameter takes a <code>Range&lt;u32&gt;</code>. This parameter tells the GPU how many copies, or instances, of the model we want to draw. Currently, we are specifying <code>0..1</code>, which instructs the GPU to draw our model once and then stop. If we used <code>0..5</code>, our code would draw five instances.</p> <p>The fact that <code>instances</code> is a <code>Range&lt;u32&gt;</code> may seem weird, as using <code>1..2</code> for instances would still draw one instance of our object. It seems like it would be simpler just to use a <code>u32</code>, right? The reason it's a range is that sometimes we don't want to draw <strong>all</strong> of our objects. Sometimes, we want to draw a selection of them because others are not in the frame, or we are debugging and want to look at a particular set of instances.</p> <p>Ok, now we know how to draw multiple instances of an object. How do we tell wgpu what particular instance to draw? We are going to use something known as an instance buffer.</p> <h2 id="the-instance-buffer"><a href="#the-instance-buffer" class="header-anchor">#</a> The Instance Buffer</h2> <p>We'll create an instance buffer similarly to how we create a uniform buffer. First, we'll create a struct called <code>Instance</code>.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token comment">// lib.rs</span>
<span class="token comment">// ...</span>
<span class="token comment">// NEW!</span>
@ -26,7 +26,7 @@
position<span class="token punctuation">:</span> <span class="token namespace">cgmath<span class="token punctuation">::</span></span><span class="token class-name">Vector3</span><span class="token operator">&lt;</span><span class="token keyword">f32</span><span class="token operator">&gt;</span><span class="token punctuation">,</span>
rotation<span class="token punctuation">:</span> <span class="token namespace">cgmath<span class="token punctuation">::</span></span><span class="token class-name">Quaternion</span><span class="token operator">&lt;</span><span class="token keyword">f32</span><span class="token operator">&gt;</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
</code></pre></div><div class="note"><p>A <code>Quaternion</code> is a mathematical structure often used to represent rotation. The math behind them is beyond me (it involves imaginary numbers and 4D space) so I won't be covering them here. If you really want to dive into them <a href="https://mathworld.wolfram.com/Quaternion.html" target="_blank" rel="noopener noreferrer">here's a Wolfram Alpha 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></div> <p>Using these values directly in the shader would be a pain as quaternions don't have a WGSL analog. I don't feel like writing the math in the shader, so we'll convert the <code>Instance</code> data into a matrix and store it into a struct called <code>InstanceRaw</code>.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token comment">// NEW!</span>
</code></pre></div><div class="note"><p>A <code>Quaternion</code> is a mathematical structure often used to represent rotation. The math behind them is beyond me (it involves imaginary numbers and 4D space), so I won't be covering them here. If you really want to dive into them <a href="https://mathworld.wolfram.com/Quaternion.html" target="_blank" rel="noopener noreferrer">here's a Wolfram Alpha 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></div> <p>Using these values directly in the shader would be a pain, as quaternions don't have a WGSL analog. I don't feel like writing the math in the shader, so we'll convert the <code>Instance</code> data into a matrix and store it in a struct called <code>InstanceRaw</code>.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token comment">// NEW!</span>
<span class="token attribute attr-name">#[repr(C)]</span>
<span class="token attribute attr-name">#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]</span>
<span class="token keyword">struct</span> <span class="token type-definition class-name">InstanceRaw</span> <span class="token punctuation">{</span>
@ -40,14 +40,14 @@
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>Now we need to add 2 fields to <code>State</code>: <code>instances</code>, and <code>instance_buffer</code>.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">struct</span> <span class="token type-definition class-name">State</span> <span class="token punctuation">{</span>
</code></pre></div><p>Now we need to add two fields to <code>State</code>: <code>instances</code> and <code>instance_buffer</code>.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">struct</span> <span class="token type-definition class-name">State</span> <span class="token punctuation">{</span>
instances<span class="token punctuation">:</span> <span class="token class-name">Vec</span><span class="token operator">&lt;</span><span class="token class-name">Instance</span><span class="token operator">&gt;</span><span class="token punctuation">,</span>
instance_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 punctuation">}</span>
</code></pre></div><p>The <code>cgmath</code> crate uses traits to provide common mathematical methods across its structs such as <code>Vector3</code>, and these traits must be imported before these methods can be called. For convenience, the <code>prelude</code> module within the crate provides the most common of these extension crates when it is imported.</p> <p>To import this prelude module, put this line 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">cgmath<span class="token punctuation">::</span>prelude<span class="token punctuation">::</span></span><span class="token operator">*</span><span class="token punctuation">;</span>
</code></pre></div><p>The <code>cgmath</code> crate uses traits to provide common mathematical methods across its structs, such as <code>Vector3</code>, which must be imported before these methods can be called. For convenience, the <code>prelude</code> module within the crate provides the most common of these extension crates when it is imported.</p> <p>To import this prelude module, put this line 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">cgmath<span class="token punctuation">::</span>prelude<span class="token punctuation">::</span></span><span class="token operator">*</span><span class="token punctuation">;</span>
</code></pre></div><p>We'll create the instances in <code>new()</code>. We'll use some constants to simplify things. We'll display our instances in 10 rows of 10, and they'll be spaced evenly apart.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">const</span> <span class="token constant">NUM_INSTANCES_PER_ROW</span><span class="token punctuation">:</span> <span class="token keyword">u32</span> <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> <span class="token constant">INSTANCE_DISPLACEMENT</span><span class="token punctuation">:</span> <span class="token namespace">cgmath<span class="token punctuation">::</span></span><span class="token class-name">Vector3</span><span class="token operator">&lt;</span><span class="token keyword">f32</span><span class="token operator">&gt;</span> <span class="token operator">=</span> <span class="token namespace">cgmath<span class="token punctuation">::</span></span><span class="token class-name">Vector3</span><span class="token punctuation">::</span><span class="token function">new</span><span class="token punctuation">(</span><span class="token constant">NUM_INSTANCES_PER_ROW</span> <span class="token keyword">as</span> <span class="token keyword">f32</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 constant">NUM_INSTANCES_PER_ROW</span> <span class="token keyword">as</span> <span class="token keyword">f32</span> <span class="token operator">*</span> <span class="token number">0.5</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>Now we can create the actual instances.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">impl</span> <span class="token class-name">State</span> <span class="token punctuation">{</span>
</code></pre></div><p>Now, we can create the actual instances.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">impl</span> <span class="token class-name">State</span> <span class="token punctuation">{</span>
<span class="token keyword">async</span> <span class="token keyword">fn</span> <span class="token function-definition function">new</span><span class="token punctuation">(</span>window<span class="token punctuation">:</span> <span class="token class-name">Window</span><span class="token punctuation">)</span> <span class="token punctuation">-&gt;</span> <span class="token keyword">Self</span> <span class="token punctuation">{</span>
<span class="token comment">// ...</span>
<span class="token keyword">let</span> instances <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">..</span><span class="token constant">NUM_INSTANCES_PER_ROW</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">flat_map</span><span class="token punctuation">(</span><span class="token closure-params"><span class="token closure-punctuation punctuation">|</span>z<span class="token closure-punctuation punctuation">|</span></span> <span class="token punctuation">{</span>
@ -56,7 +56,7 @@
<span class="token keyword">let</span> rotation <span class="token operator">=</span> <span class="token keyword">if</span> position<span class="token punctuation">.</span><span class="token function">is_zero</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// this is needed so an object at (0, 0, 0) won't get scaled to zero</span>
<span class="token comment">// as Quaternions can effect scale if they're not created correctly</span>
<span class="token comment">// as Quaternions can affect scale if they're not created correctly</span>
<span class="token namespace">cgmath<span class="token punctuation">::</span></span><span class="token class-name">Quaternion</span><span class="token punctuation">::</span><span class="token function">from_axis_angle</span><span class="token punctuation">(</span><span class="token namespace">cgmath<span class="token punctuation">::</span></span><span class="token class-name">Vector3</span><span class="token punctuation">::</span><span class="token function">unit_z</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token namespace">cgmath<span class="token punctuation">::</span></span><span class="token class-name">Deg</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 keyword">else</span> <span class="token punctuation">{</span>
<span class="token namespace">cgmath<span class="token punctuation">::</span></span><span class="token class-name">Quaternion</span><span class="token punctuation">::</span><span class="token function">from_axis_angle</span><span class="token punctuation">(</span>position<span class="token punctuation">.</span><span class="token function">normalize</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token namespace">cgmath<span class="token punctuation">::</span></span><span class="token class-name">Deg</span><span class="token punctuation">(</span><span class="token number">45.0</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
@ -92,8 +92,8 @@
<span class="token comment">// for each vec4. We'll have to reassemble the mat4 in the shader.</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">// While our vertex shader only uses locations 0, and 1 now, in later tutorials we'll</span>
<span class="token comment">// be using 2, 3, and 4, for Vertex. We'll start at slot 5 not conflict with them later</span>
<span class="token comment">// While our vertex shader only uses locations 0, and 1 now, in later tutorials, we'll</span>
<span class="token comment">// be using 2, 3, and 4, for Vertex. We'll start at slot 5, not conflict with them later</span>
shader_location<span class="token punctuation">:</span> <span class="token number">5</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">Float32x4</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
@ -131,7 +131,7 @@
instances<span class="token punctuation">,</span>
instance_buffer<span class="token punctuation">,</span>
<span class="token punctuation">}</span>
</code></pre></div><p>The last change we need to make is in the <code>render()</code> method. We need to bind our <code>instance_buffer</code> and we need to change the range we're using in <code>draw_indexed()</code> to include the number of instances.</p> <div class="language-rust extra-class"><pre class="language-rust"><code>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>
</code></pre></div><p>The last change we need to make is in the <code>render()</code> method. We need to bind our <code>instance_buffer</code> and change the range we're using in <code>draw_indexed()</code> to include the number of instances.</p> <div class="language-rust extra-class"><pre class="language-rust"><code>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_bind_group</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span><span class="token keyword">self</span><span class="token punctuation">.</span>diffuse_bind_group<span class="token punctuation">,</span> <span class="token operator">&amp;</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
render_pass<span class="token punctuation">.</span><span class="token function">set_bind_group</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span><span class="token keyword">self</span><span class="token punctuation">.</span>camera_bind_group<span class="token punctuation">,</span> <span class="token operator">&amp;</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
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>
@ -141,7 +141,7 @@ render_pass<span class="token punctuation">.</span><span class="token function">
<span class="token comment">// UPDATED!</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 keyword">self</span><span class="token punctuation">.</span>instances<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 punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><div class="warning"><p>Make sure if you add new instances to the <code>Vec</code>, that you recreate the <code>instance_buffer</code> and as well as <code>camera_bind_group</code>, otherwise your new instances won't show up correctly.</p></div> <p>We need to reference the parts of our new matrix in <code>shader.wgsl</code> so that we can use it for our instances. Add the following to the top of <code>shader.wgsl</code>.</p> <div class="language-wgsl extra-class"><pre class="language-wgsl"><code><span class="token keyword">struct</span> <span class="token class-name">InstanceInput</span> <span class="token punctuation">{</span>
</code></pre></div><div class="warning"><p>Make sure that if you add new instances to the <code>Vec</code>, you recreate the <code>instance_buffer</code> as well as <code>camera_bind_group</code>. Otherwise, your new instances won't show up correctly.</p></div> <p>We need to reference the parts of our new matrix in <code>shader.wgsl</code> so that we can use it for our instances. Add the following to the top of <code>shader.wgsl</code>.</p> <div class="language-wgsl extra-class"><pre class="language-wgsl"><code><span class="token keyword">struct</span> <span class="token class-name">InstanceInput</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">5</span><span class="token punctuation">)</span> model_matrix_0<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">6</span><span class="token punctuation">)</span> model_matrix_1<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">7</span><span class="token punctuation">)</span> model_matrix_2<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>
@ -171,7 +171,7 @@ render_pass<span class="token punctuation">.</span><span class="token function">
out<span class="token punctuation">.</span>clip_position <span class="token operator">=</span> camera<span class="token punctuation">.</span>view_proj <span class="token operator">*</span> model_matrix <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>
</code></pre></div><p>With all that done, we should have a forest of trees!</p> <p><img src="/learn-wgpu/assets/img/forest.5c5cf3ad.png" alt="./forest.png"></p> <h2 id="challenge"><a href="#challenge" class="header-anchor">#</a> Challenge</h2> <p>Modify the position and/or rotation of the instances every frame.</p> <div id="wasm-example"><!----> <button>Try Tutorial7_instancing!</button></div> <div class="auto-github-link"><a href="https://github.com/sotrh/learn-wgpu/tree/master/code/beginner/tutorial7-instancing/" 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:28 AM</span></div></footer> <div class="page-nav"><p class="inner"><span class="prev">
</code></pre></div><p>With all that done, we should have a forest of trees!</p> <p><img src="/learn-wgpu/assets/img/forest.5c5cf3ad.png" alt="./forest.png"></p> <h2 id="challenge"><a href="#challenge" class="header-anchor">#</a> Challenge</h2> <p>Modify the position and/or rotation of the instances every frame.</p> <div id="wasm-example"><!----> <button>Try Tutorial7_instancing!</button></div> <div class="auto-github-link"><a href="https://github.com/sotrh/learn-wgpu/tree/master/code/beginner/tutorial7-instancing/" 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:04:05 AM</span></div></footer> <div class="page-nav"><p class="inner"><span class="prev">
<a href="/learn-wgpu/beginner/tutorial6-uniforms/" class="prev">
Uniform buffers and a 3d camera
@ -180,6 +180,6 @@ render_pass<span class="token punctuation">.</span><span class="token function">
</a>
</span></p></div> </main></div></div><div class="global-ui"><!----></div></div>
<script src="/learn-wgpu/assets/js/app.a49faced.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/47.3a7bf317.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>
<script src="/learn-wgpu/assets/js/app.99e1547a.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/47.22e16c22.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>

File diff suppressed because one or more lines are too long

@ -8,11 +8,11 @@
<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.a49faced.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/36.e6a8b391.js" as="script"><link rel="preload" href="/learn-wgpu/assets/js/33.945dce62.js" as="script"><link rel="preload" href="/learn-wgpu/assets/js/37.5ecf7ce2.js" as="script"><link rel="prefetch" href="/learn-wgpu/assets/js/10.baf5d1fe.js"><link rel="prefetch" href="/learn-wgpu/assets/js/11.b8633c49.js"><link rel="prefetch" href="/learn-wgpu/assets/js/12.0b8835f1.js"><link rel="prefetch" href="/learn-wgpu/assets/js/13.af1bbe85.js"><link rel="prefetch" href="/learn-wgpu/assets/js/14.626c7cb3.js"><link rel="prefetch" href="/learn-wgpu/assets/js/15.5a8ea302.js"><link rel="prefetch" href="/learn-wgpu/assets/js/16.f4e8226b.js"><link rel="prefetch" href="/learn-wgpu/assets/js/17.dd15c417.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.a01d50ae.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.fd4eb8d5.js"><link rel="prefetch" href="/learn-wgpu/assets/js/27.914a9a40.js"><link rel="prefetch" href="/learn-wgpu/assets/js/28.77f7d987.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.c58683af.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/34.0fe8e5e4.js"><link rel="prefetch" href="/learn-wgpu/assets/js/35.7c607f94.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.47515217.js"><link rel="prefetch" href="/learn-wgpu/assets/js/42.4caac867.js"><link rel="prefetch" href="/learn-wgpu/assets/js/43.ac6fc643.js"><link rel="prefetch" href="/learn-wgpu/assets/js/44.27513d85.js"><link rel="prefetch" href="/learn-wgpu/assets/js/45.2ea5b108.js"><link rel="prefetch" href="/learn-wgpu/assets/js/46.e591bcb9.js"><link rel="prefetch" href="/learn-wgpu/assets/js/47.3a7bf317.js"><link rel="prefetch" href="/learn-wgpu/assets/js/48.0a15e622.js"><link rel="prefetch" href="/learn-wgpu/assets/js/49.ad5a99aa.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.48268452.js"><link rel="prefetch" href="/learn-wgpu/assets/js/53.8c976652.js"><link rel="prefetch" href="/learn-wgpu/assets/js/54.daee63ce.js"><link rel="prefetch" href="/learn-wgpu/assets/js/55.3799ddaa.js"><link rel="prefetch" href="/learn-wgpu/assets/js/56.a43d5d8e.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.24bfa87e.js"><link rel="prefetch" href="/learn-wgpu/assets/js/63.90f94cac.js"><link rel="prefetch" href="/learn-wgpu/assets/js/64.b9a310af.js"><link rel="prefetch" href="/learn-wgpu/assets/js/65.362df98e.js"><link rel="prefetch" href="/learn-wgpu/assets/js/66.ef1e3716.js"><link rel="prefetch" href="/learn-wgpu/assets/js/67.ab338058.js"><link rel="prefetch" href="/learn-wgpu/assets/js/68.d785413d.js"><link rel="prefetch" href="/learn-wgpu/assets/js/8.2c0d831a.js"><link rel="prefetch" href="/learn-wgpu/assets/js/9.985bc61a.js"><link rel="prefetch" href="/learn-wgpu/assets/js/vendors~docsearch.efa6f8ef.js">
<link rel="preload" href="/learn-wgpu/assets/css/0.styles.81cb5453.css" as="style"><link rel="preload" href="/learn-wgpu/assets/js/app.99e1547a.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/36.beae0010.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.bcec92ff.js"><link rel="prefetch" href="/learn-wgpu/assets/js/27.c755f80e.js"><link rel="prefetch" href="/learn-wgpu/assets/js/28.be489186.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/30.12d50dcb.js"><link rel="prefetch" href="/learn-wgpu/assets/js/31.550259b2.js"><link rel="prefetch" href="/learn-wgpu/assets/js/32.e359d5e0.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/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.7e2aef8c.js"><link rel="prefetch" href="/learn-wgpu/assets/js/42.6f76d27e.js"><link rel="prefetch" href="/learn-wgpu/assets/js/43.ddac8e2c.js"><link rel="prefetch" href="/learn-wgpu/assets/js/44.1486e9ca.js"><link rel="prefetch" href="/learn-wgpu/assets/js/45.2ea5b108.js"><link rel="prefetch" href="/learn-wgpu/assets/js/46.fbe2131f.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.c0f22e2e.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.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.2dadff38.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.c78dac93.js"><link rel="prefetch" href="/learn-wgpu/assets/js/61.87dce596.js"><link rel="prefetch" href="/learn-wgpu/assets/js/62.fc4967ec.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.0c2a60e3.js"><link rel="prefetch" href="/learn-wgpu/assets/js/66.a136cd48.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/" 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/" aria-current="page" class="active sidebar-link">Model Loading</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/learn-wgpu/beginner/tutorial9-models/#accessing-files-in-the-res-folder" class="sidebar-link">Accessing files in the res folder</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/beginner/tutorial9-models/#accessing-files-from-wasm" class="sidebar-link">Accessing files from WASM</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/beginner/tutorial9-models/#loading-models-with-tobj" class="sidebar-link">Loading models with TOBJ</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/beginner/tutorial9-models/#rendering-a-mesh" class="sidebar-link">Rendering a mesh</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/beginner/tutorial9-models/#using-the-correct-textures" class="sidebar-link">Using the correct textures</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/beginner/tutorial9-models/#rendering-the-entire-model" class="sidebar-link">Rendering the entire model</a></li></ul></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="model-loading"><a href="#model-loading" class="header-anchor">#</a> Model Loading</h1> <p>Up to this point we've been creating our models manually. While this is an acceptable way to do this, it's really slow if we want to include complex models with lots of polygons. Because of this, we're going to modify our code to leverage the <code>.obj</code> model format so that we can create a model in software such as blender and display it in our code.</p> <p>Our <code>lib.rs</code> file is getting pretty cluttered, let's create a <code>model.rs</code> file that we can put our model loading code into.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token comment">// model.rs</span>
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="inner"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/learn-wgpu/" class="home-link router-link-active"><!----> <span class="site-name">Learn Wgpu</span></a> <div class="links"><!----> <div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div></div></div></header> <div class="sidebar-mask"></div> <div class="docs-layout"><aside class="sidebar"><!----> <ul class="sidebar-links"><li><a href="/learn-wgpu/" aria-current="page" class="sidebar-link">Introduction</a></li><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>Beginner</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/learn-wgpu/beginner/tutorial1-window/" class="sidebar-link">Dependencies and the window</a></li><li><a href="/learn-wgpu/beginner/tutorial2-surface/" class="sidebar-link">The Surface</a></li><li><a href="/learn-wgpu/beginner/tutorial3-pipeline/" class="sidebar-link">The Pipeline</a></li><li><a href="/learn-wgpu/beginner/tutorial4-buffer/" class="sidebar-link">Buffers and Indices</a></li><li><a href="/learn-wgpu/beginner/tutorial5-textures/" class="sidebar-link">Textures and bind groups</a></li><li><a href="/learn-wgpu/beginner/tutorial6-uniforms/" class="sidebar-link">Uniform buffers and a 3d camera</a></li><li><a href="/learn-wgpu/beginner/tutorial7-instancing/" class="sidebar-link">Instancing</a></li><li><a href="/learn-wgpu/beginner/tutorial8-depth/" class="sidebar-link">The Depth Buffer</a></li><li><a href="/learn-wgpu/beginner/tutorial9-models/" aria-current="page" class="active sidebar-link">Model Loading</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/learn-wgpu/beginner/tutorial9-models/#accessing-files-in-the-res-folder" class="sidebar-link">Accessing files in the res folder</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/beginner/tutorial9-models/#accessing-files-from-wasm" class="sidebar-link">Accessing files from WASM</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/beginner/tutorial9-models/#loading-models-with-tobj" class="sidebar-link">Loading models with TOBJ</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/beginner/tutorial9-models/#rendering-a-mesh" class="sidebar-link">Rendering a mesh</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/beginner/tutorial9-models/#using-the-correct-textures" class="sidebar-link">Using the correct textures</a></li><li class="sidebar-sub-header"><a href="/learn-wgpu/beginner/tutorial9-models/#rendering-the-entire-model" class="sidebar-link">Rendering the entire model</a></li></ul></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="model-loading"><a href="#model-loading" class="header-anchor">#</a> Model Loading</h1> <p>Up to this point, we've been creating our models manually. While this is an acceptable way to do this, it's really slow if we want to include complex models with lots of polygons. Because of this, we're going to modify our code to leverage the <code>.obj</code> model format so that we can create a model in software such as Blender and display it in our code.</p> <p>Our <code>lib.rs</code> file is getting pretty cluttered. Let's create a <code>model.rs</code> file into which we can put our model loading code.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token comment">// model.rs</span>
<span class="token keyword">pub</span> <span class="token keyword">trait</span> <span class="token type-definition 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 punctuation">}</span>
@ -30,7 +30,7 @@
<span class="token macro property">todo!</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>You'll notice a couple of things here. In <code>lib.rs</code> we had <code>Vertex</code> as a struct, here we're using a trait. We could have multiple vertex types (model, UI, instance data, etc.). Making <code>Vertex</code> a trait will allow us to abstract out the <code>VertexBufferLayout</code> creation code to make creating <code>RenderPipeline</code>s simpler.</p> <p>Another thing to mention is the <code>normal</code> field in <code>ModelVertex</code>. We won't use this until we talk about lighting, but will add it to the struct for now.</p> <p>Let's define our <code>VertexBufferLayout</code>.</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 keyword">for</span> <span class="token class-name">ModelVertex</span> <span class="token punctuation">{</span>
</code></pre></div><p>You'll notice a couple of things here. In <code>lib.rs</code>, we had <code>Vertex</code> as a struct, but here we're using a trait. We could have multiple vertex types (model, UI, instance data, etc.). Making <code>Vertex</code> a trait will allow us to abstract out the <code>VertexBufferLayout</code> creation code to make creating <code>RenderPipeline</code>s simpler.</p> <p>Another thing to mention is the <code>normal</code> field in <code>ModelVertex</code>. We won't use this until we talk about lighting, but will add it to the struct for now.</p> <p>Let's define our <code>VertexBufferLayout</code>.</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 keyword">for</span> <span class="token class-name">ModelVertex</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>
@ -65,13 +65,13 @@
<span class="token comment">// ...</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>Since the <code>desc</code> method is implemented on the <code>Vertex</code> trait, the trait needs to be imported before the method will be accessible. Put the import towards the top of the file with the others.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">use</span> <span class="token namespace">model<span class="token punctuation">::</span></span><span class="token class-name">Vertex</span><span class="token punctuation">;</span>
</code></pre></div><p>With all that in place, we need a model to render. If you have one already that's great, but I've supplied a <a href="https://github.com/sotrh/learn-wgpu/blob/master/code/beginner/tutorial9-models/res/cube.zip" target="_blank" rel="noopener noreferrer">zip file<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> with the model and all of its textures. We're going to put this model in a new <code>res</code> folder next to the existing <code>src</code> folder.</p> <h2 id="accessing-files-in-the-res-folder"><a href="#accessing-files-in-the-res-folder" class="header-anchor">#</a> Accessing files in the res folder</h2> <p>When cargo builds and runs our program it sets what's known as the current working directory. This directory is usually the folder containing your project's root <code>Cargo.toml</code>. The path to our res folder may differ depending on the structure of the project. In the <code>res</code> folder for the example code for this section tutorial is at <code>code/beginner/tutorial9-models/res/</code>. When loading our model we could use this path, and just append <code>cube.obj</code>. This is fine, but if we change our project's structure, our code will break.</p> <p>We're going to fix that by modifying our build script to copy our <code>res</code> folder to where cargo creates our executable, and we'll reference it from there. Create a file called <code>build.rs</code> and add the following:</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">use</span> <span class="token namespace">anyhow<span class="token punctuation">::</span></span><span class="token operator">*</span><span class="token punctuation">;</span>
</code></pre></div><p>With all that in place, we need a model to render. If you have one already, that's great, but I've supplied a <a href="https://github.com/sotrh/learn-wgpu/blob/master/code/beginner/tutorial9-models/res/cube.zip" target="_blank" rel="noopener noreferrer">zip file<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> with the model and all of its textures. We're going to put this model in a new <code>res</code> folder next to the existing <code>src</code> folder.</p> <h2 id="accessing-files-in-the-res-folder"><a href="#accessing-files-in-the-res-folder" class="header-anchor">#</a> Accessing files in the res folder</h2> <p>When Cargo builds and runs our program, it sets what's known as the current working directory. This directory usually contains your project's root <code>Cargo.toml</code>. The path to our res folder may differ depending on the project's structure. In the <code>res</code> folder, the example code for this section tutorial is at <code>code/beginner/tutorial9-models/res/</code>. When loading our model, we could use this path and just append <code>cube.obj</code>. This is fine, but if we change our project's structure, our code will break.</p> <p>We're going to fix that by modifying our build script to copy our <code>res</code> folder to where Cargo creates our executable, and we'll reference it from there. Create a file called <code>build.rs</code> and add the following:</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">use</span> <span class="token namespace">anyhow<span class="token punctuation">::</span></span><span class="token operator">*</span><span class="token punctuation">;</span>
<span class="token keyword">use</span> <span class="token namespace">fs_extra<span class="token punctuation">::</span></span>copy_items<span class="token punctuation">;</span>
<span class="token keyword">use</span> <span class="token namespace">fs_extra<span class="token punctuation">::</span>dir<span class="token punctuation">::</span></span><span class="token class-name">CopyOptions</span><span class="token punctuation">;</span>
<span class="token keyword">use</span> <span class="token namespace">std<span class="token punctuation">::</span></span>env<span class="token punctuation">;</span>
<span class="token keyword">fn</span> <span class="token function-definition function">main</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 punctuation">(</span><span class="token punctuation">)</span><span class="token operator">&gt;</span> <span class="token punctuation">{</span>
<span class="token comment">// This tells cargo to rerun this script if something in /res/ changes.</span>
<span class="token comment">// This tells Cargo to rerun this script if something in /res/ changes.</span>
<span class="token macro property">println!</span><span class="token punctuation">(</span><span class="token string">&quot;cargo:rerun-if-changed=res/*&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> out_dir <span class="token operator">=</span> <span class="token namespace">env<span class="token punctuation">::</span></span><span class="token function">var</span><span class="token punctuation">(</span><span class="token string">&quot;OUT_DIR&quot;</span><span class="token punctuation">)</span><span class="token operator">?</span><span class="token punctuation">;</span>
@ -83,11 +83,11 @@
<span class="token class-name">Ok</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>Make sure to put <code>build.rs</code> in the same folder as the <code>Cargo.toml</code>. If you don't, cargo won't run it when your crate builds.</p></div> <div class="note"><p>The <code>OUT_DIR</code> is an environment variable that cargo uses to specify where our application will be built.</p></div> <p>You'll need to modify your <code>Cargo.toml</code> for this to work properly. Add the following below your <code>[dependencies]</code> block.</p> <div class="language-toml extra-class"><pre class="language-toml"><code><span class="token punctuation">[</span><span class="token table class-name">build-dependencies</span><span class="token punctuation">]</span>
</code></pre></div><div class="note"><p>Make sure to put <code>build.rs</code> in the same folder as the <code>Cargo.toml</code>. If you don't, Cargo won't run it when your crate builds.</p></div> <div class="note"><p>The <code>OUT_DIR</code> is an environment variable that Cargo uses to specify where our application will be built.</p></div> <p>You'll need to modify your <code>Cargo.toml</code> for this to work properly. Add the following below your <code>[dependencies]</code> block.</p> <div class="language-toml extra-class"><pre class="language-toml"><code><span class="token punctuation">[</span><span class="token table class-name">build-dependencies</span><span class="token punctuation">]</span>
<span class="token key property">anyhow</span> <span class="token punctuation">=</span> <span class="token string">&quot;1.0&quot;</span>
<span class="token key property">fs_extra</span> <span class="token punctuation">=</span> <span class="token string">&quot;1.2&quot;</span>
<span class="token key property">glob</span> <span class="token punctuation">=</span> <span class="token string">&quot;0.3&quot;</span>
</code></pre></div><h2 id="accessing-files-from-wasm"><a href="#accessing-files-from-wasm" class="header-anchor">#</a> Accessing files from WASM</h2> <p>By design, you can't access files on a user's filesystem in Web Assembly. Instead, we'll serve those files up using a web serve, and then load those files into our code using an http request. In order to simplify this, let's create a file called <code>resources.rs</code> to handle this for us. We'll create two functions that will load text files and binary files respectively.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">use</span> <span class="token namespace">std<span class="token punctuation">::</span>io<span class="token punctuation">::</span></span><span class="token punctuation">{</span><span class="token class-name">BufReader</span><span class="token punctuation">,</span> <span class="token class-name">Cursor</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><h2 id="accessing-files-from-wasm"><a href="#accessing-files-from-wasm" class="header-anchor">#</a> Accessing files from WASM</h2> <p>By design, you can't access files on a user's filesystem in Web Assembly. Instead, we'll serve those files up using a web serve and then load those files into our code using an http request. In order to simplify this, let's create a file called <code>resources.rs</code> to handle this for us. We'll create two functions that load text and binary files, respectively.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">use</span> <span class="token namespace">std<span class="token punctuation">::</span>io<span class="token punctuation">::</span></span><span class="token punctuation">{</span><span class="token class-name">BufReader</span><span class="token punctuation">,</span> <span class="token class-name">Cursor</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">use</span> <span class="token namespace">cfg_if<span class="token punctuation">::</span></span>cfg_if<span class="token punctuation">;</span>
<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>
@ -144,7 +144,7 @@
<span class="token class-name">Ok</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><div class="note"><p>We're using <code>OUT_DIR</code> on desktop to get to our <code>res</code> folder.</p></div> <p>I'm using <a href="https://docs.rs/reqwest" target="_blank" rel="noopener noreferrer">reqwest<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 handle loading the requests when using WASM. Add the following to the Cargo.toml:</p> <div class="language-toml extra-class"><pre class="language-toml"><code><span class="token punctuation">[</span><span class="token table class-name">target.'cfg(target_arch = &quot;wasm32&quot;)'.dependencies</span><span class="token punctuation">]</span>
</code></pre></div><div class="note"><p>We're using <code>OUT_DIR</code> on desktop to access our <code>res</code> folder.</p></div> <p>I'm using <a href="https://docs.rs/reqwest" target="_blank" rel="noopener noreferrer">reqwest<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 handle loading the requests when using WASM. Add the following to the <code>Cargo.toml</code>:</p> <div class="language-toml extra-class"><pre class="language-toml"><code><span class="token punctuation">[</span><span class="token table class-name">target.'cfg(target_arch = &quot;wasm32&quot;)'.dependencies</span><span class="token punctuation">]</span>
<span class="token comment"># Other dependencies</span>
<span class="token key property">reqwest</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;0.11&quot;</span> <span class="token punctuation">}</span>
</code></pre></div><p>We'll also need to add the <code>Location</code> feature to <code>web-sys</code>:</p> <div class="language-toml extra-class"><pre class="language-toml"><code><span class="token key property">web-sys</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;0.3&quot;</span><span class="token punctuation">,</span> <span class="token key property">features</span> <span class="token punctuation">=</span> <span class="token punctuation">[</span>
@ -159,12 +159,12 @@
<span class="token key property">tobj</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;3.2.1&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;async&quot;</span><span class="token punctuation">,</span>
<span class="token punctuation">]</span><span class="token punctuation">}</span>
</code></pre></div><p>Before we can load our model though, we need somewhere to put it.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token comment">// model.rs</span>
</code></pre></div><p>Before we can load our model, though, we need somewhere to put it.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token comment">// model.rs</span>
<span class="token keyword">pub</span> <span class="token keyword">struct</span> <span class="token type-definition class-name">Model</span> <span class="token punctuation">{</span>
<span class="token keyword">pub</span> meshes<span class="token punctuation">:</span> <span class="token class-name">Vec</span><span class="token operator">&lt;</span><span class="token class-name">Mesh</span><span class="token operator">&gt;</span><span class="token punctuation">,</span>
<span class="token keyword">pub</span> materials<span class="token punctuation">:</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;</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
</code></pre></div><p>You'll notice that our <code>Model</code> struct has a <code>Vec</code> for the <code>meshes</code>, and for <code>materials</code>. This is important as our obj file can include multiple meshes and materials. We still need to create the <code>Mesh</code> and <code>Material</code> classes, so let's do that.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">pub</span> <span class="token keyword">struct</span> <span class="token type-definition class-name">Material</span> <span class="token punctuation">{</span>
</code></pre></div><p>You'll notice that our <code>Model</code> struct has a <code>Vec</code> for the <code>meshes</code> and <code>materials</code>. This is important as our obj file can include multiple meshes and materials. We still need to create the <code>Mesh</code> and <code>Material</code> classes, so let's do that.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">pub</span> <span class="token keyword">struct</span> <span class="token type-definition class-name">Material</span> <span class="token punctuation">{</span>
<span class="token keyword">pub</span> name<span class="token punctuation">:</span> <span class="token class-name">String</span><span class="token punctuation">,</span>
<span class="token keyword">pub</span> diffuse_texture<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 keyword">pub</span> bind_group<span class="token punctuation">:</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">BindGroup</span><span class="token punctuation">,</span>
@ -177,7 +177,7 @@
<span class="token keyword">pub</span> num_elements<span class="token punctuation">:</span> <span class="token keyword">u32</span><span class="token punctuation">,</span>
<span class="token keyword">pub</span> material<span class="token punctuation">:</span> <span class="token keyword">usize</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
</code></pre></div><p>The <code>Material</code> is pretty simple, it's just the name and one texture. Our cube obj actually has 2 textures, but one is a normal map, and we'll get to those <a href="../../intermediate/tutorial11-normals">later</a>. The name is more for debugging purposes.</p> <p>Speaking of textures, we'll need to add a function to load a <code>Texture</code> in <code>resources.rs</code>.</p> <div class="language-rust extra-class"><pre class="language-rust"><code>
</code></pre></div><p>The <code>Material</code> is pretty simple. It's just the name and one texture. Our cube obj actually has two textures, but one is a normal map, and we'll get to those <a href="../../intermediate/tutorial11-normals">later</a>. The name is more for debugging purposes.</p> <p>Speaking of textures, we'll need to add a function to load a <code>Texture</code> in <code>resources.rs</code>.</p> <div class="language-rust extra-class"><pre class="language-rust"><code>
<span class="token keyword">pub</span> <span class="token keyword">async</span> <span class="token keyword">fn</span> <span class="token function-definition function">load_texture</span><span class="token punctuation">(</span>
file_name<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token keyword">str</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>
@ -186,7 +186,7 @@
<span class="token keyword">let</span> data <span class="token operator">=</span> <span class="token function">load_binary</span><span class="token punctuation">(</span>file_name<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token keyword">await</span><span class="token operator">?</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">from_bytes</span><span class="token punctuation">(</span>device<span class="token punctuation">,</span> queue<span class="token punctuation">,</span> <span class="token operator">&amp;</span>data<span class="token punctuation">,</span> file_name<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><p>The <code>load_texture</code> method will be useful when we load the textures for our models, as <code>include_bytes!</code> requires that we know the name of the file at compile time which we can't really guarantee with model textures.</p> <p><code>Mesh</code> holds a vertex buffer, an index buffer, and the number of indices in the mesh. We're using an <code>usize</code> for the material. This <code>usize</code> will be used to index the <code>materials</code> list when it comes time to draw.</p> <p>With all that out of the way, we can get to loading our model.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">pub</span> <span class="token keyword">async</span> <span class="token keyword">fn</span> <span class="token function-definition function">load_model</span><span class="token punctuation">(</span>
</code></pre></div><p>The <code>load_texture</code> method will be useful when we load the textures for our models, as <code>include_bytes!</code> requires that we know the name of the file at compile time, which we can't really guarantee with model textures.</p> <p><code>Mesh</code> holds a vertex buffer, an index buffer, and the number of indices in the mesh. We're using an <code>usize</code> for the material. This <code>usize</code> will index the <code>materials</code> list when it comes time to draw.</p> <p>With all that out of the way, we can get to loading our model.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">pub</span> <span class="token keyword">async</span> <span class="token keyword">fn</span> <span class="token function-definition function">load_model</span><span class="token punctuation">(</span>
file_name<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token keyword">str</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>
@ -278,7 +278,7 @@
<span class="token class-name">Ok</span><span class="token punctuation">(</span><span class="token namespace">model<span class="token punctuation">::</span></span><span class="token class-name">Model</span> <span class="token punctuation">{</span> meshes<span class="token punctuation">,</span> materials <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="rendering-a-mesh"><a href="#rendering-a-mesh" class="header-anchor">#</a> Rendering a mesh</h2> <p>Before we can draw the model, we need to be able to draw an individual mesh. Let's create a trait called <code>DrawModel</code>, and implement it for <code>RenderPass</code>.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token comment">// model.rs</span>
</code></pre></div><h2 id="rendering-a-mesh"><a href="#rendering-a-mesh" class="header-anchor">#</a> Rendering a mesh</h2> <p>Before we can draw the model, we need to be able to draw an individual mesh. Let's create a trait called <code>DrawModel</code> and implement it for <code>RenderPass</code>.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token comment">// model.rs</span>
<span class="token keyword">pub</span> <span class="token keyword">trait</span> <span class="token type-definition class-name">DrawModel</span><span class="token operator">&lt;</span><span class="token lifetime-annotation symbol">'a</span><span class="token operator">&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword">fn</span> <span class="token function-definition function">draw_mesh</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token keyword">mut</span> <span class="token keyword">self</span><span class="token punctuation">,</span> mesh<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token lifetime-annotation symbol">'a</span> <span class="token class-name">Mesh</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">fn</span> <span class="token function-definition function">draw_mesh_instanced</span><span class="token punctuation">(</span>
@ -305,7 +305,7 @@
<span class="token keyword">self</span><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>mesh<span class="token punctuation">.</span>num_elements<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> instances<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 could have put these methods in an <code>impl Model</code>, but I felt it made more sense to have the <code>RenderPass</code> do all the rendering, as that's kind of its job. This does mean we have to import <code>DrawModel</code> when we go to render though.</p> <p>When we removed <code>vertex_buffer</code>, etc. we also removed their render_pass setup.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token comment">// lib.rs</span>
</code></pre></div><p>We could have put these methods in an <code>impl Model</code>, but I felt it made more sense to have the <code>RenderPass</code> do all the rendering, as that's kind of its job. This does mean we have to import <code>DrawModel</code> when we go to render, though.</p> <p>When we removed <code>vertex_buffer</code>, etc., we also removed their render_pass setup.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token comment">// lib.rs</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">1</span><span class="token punctuation">,</span> <span class="token keyword">self</span><span class="token punctuation">.</span>instance_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_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_bind_group</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span><span class="token keyword">self</span><span class="token punctuation">.</span>diffuse_bind_group<span class="token punctuation">,</span> <span class="token operator">&amp;</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
@ -313,11 +313,11 @@ render_pass<span class="token punctuation">.</span><span class="token function">
<span class="token keyword">use</span> <span class="token namespace">model<span class="token punctuation">::</span></span><span class="token class-name">DrawModel</span><span class="token punctuation">;</span>
render_pass<span class="token punctuation">.</span><span class="token function">draw_mesh_instanced</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token keyword">self</span><span class="token punctuation">.</span>obj_model<span class="token punctuation">.</span>meshes<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</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>instances<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 punctuation">;</span>
</code></pre></div><p>Before that though we need to actually load the model and save it to <code>State</code>. Put the following in <code>State::new()</code>.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">let</span> obj_model <span class="token operator">=</span>
</code></pre></div><p>Before that, though, we need to load the model and save it to <code>State</code>. Put the following in <code>State::new()</code>.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">let</span> obj_model <span class="token operator">=</span>
<span class="token namespace">resources<span class="token punctuation">::</span></span><span class="token function">load_model</span><span class="token punctuation">(</span><span class="token string">&quot;cube.obj&quot;</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>device<span class="token punctuation">,</span> <span class="token operator">&amp;</span>queue<span class="token punctuation">,</span> <span class="token operator">&amp;</span>texture_bind_group_layout<span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token keyword">await</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>
</code></pre></div><p>Our new model is a bit bigger than our previous one so we're gonna need to adjust the spacing on our instances a bit.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">const</span> <span class="token constant">SPACE_BETWEEN</span><span class="token punctuation">:</span> <span class="token keyword">f32</span> <span class="token operator">=</span> <span class="token number">3.0</span><span class="token punctuation">;</span>
</code></pre></div><p>Our new model is a bit bigger than our previous one, so we're gonna need to adjust the spacing on our instances a bit.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">const</span> <span class="token constant">SPACE_BETWEEN</span><span class="token punctuation">:</span> <span class="token keyword">f32</span> <span class="token operator">=</span> <span class="token number">3.0</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> instances <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">..</span><span class="token constant">NUM_INSTANCES_PER_ROW</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">flat_map</span><span class="token punctuation">(</span><span class="token closure-params"><span class="token closure-punctuation punctuation">|</span>z<span class="token closure-punctuation punctuation">|</span></span> <span class="token punctuation">{</span>
<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">..</span><span class="token constant">NUM_INSTANCES_PER_ROW</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 keyword">move</span> <span class="token closure-params"><span class="token closure-punctuation punctuation">|</span>x<span class="token closure-punctuation punctuation">|</span></span> <span class="token punctuation">{</span>
<span class="token keyword">let</span> x <span class="token operator">=</span> <span class="token constant">SPACE_BETWEEN</span> <span class="token operator">*</span> <span class="token punctuation">(</span>x <span class="token keyword">as</span> <span class="token keyword">f32</span> <span class="token operator">-</span> <span class="token constant">NUM_INSTANCES_PER_ROW</span> <span class="token keyword">as</span> <span class="token keyword">f32</span> <span class="token operator">/</span> <span class="token number">2.0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
@ -336,7 +336,7 @@ render_pass<span class="token punctuation">.</span><span class="token function">
<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>
</code></pre></div><p>With all that done, you should get something like this.</p> <p><img src="/learn-wgpu/assets/img/cubes.988d14be.png" alt="cubes.png"></p> <h2 id="using-the-correct-textures"><a href="#using-the-correct-textures" class="header-anchor">#</a> Using the correct textures</h2> <p>If you look at the texture files for our obj, you'll see that they don't match up to our obj. The texture we want to see is this one,</p> <p><img src="/learn-wgpu/assets/img/cube-diffuse.03fc55af.jpg" alt="cube-diffuse.jpg"></p> <p>but we're still getting our happy tree texture.</p> <p>The reason for this is quite simple. Though we've created our textures we haven't created a bind group to give to the <code>RenderPass</code>. We're still using our old <code>diffuse_bind_group</code>. If we want to change that we need to use the bind group from our materials - the <code>bind_group</code> member of the <code>Material</code> struct.</p> <p>We're going to add a material parameter to <code>DrawModel</code>.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">pub</span> <span class="token keyword">trait</span> <span class="token type-definition class-name">DrawModel</span><span class="token operator">&lt;</span><span class="token lifetime-annotation symbol">'a</span><span class="token operator">&gt;</span> <span class="token punctuation">{</span>
</code></pre></div><p>With all that done, you should get something like this.</p> <p><img src="/learn-wgpu/assets/img/cubes.988d14be.png" alt="cubes.png"></p> <h2 id="using-the-correct-textures"><a href="#using-the-correct-textures" class="header-anchor">#</a> Using the correct textures</h2> <p>If you look at the texture files for our obj, you'll see that they don't match up to our obj. The texture we want to see is this one,</p> <p><img src="/learn-wgpu/assets/img/cube-diffuse.03fc55af.jpg" alt="cube-diffuse.jpg"></p> <p>but we're still getting our happy tree texture.</p> <p>The reason for this is quite simple. Though we've created our textures, we haven't created a bind group to give to the <code>RenderPass</code>. We're still using our old <code>diffuse_bind_group</code>. If we want to change that, we need to use the bind group from our materials - the <code>bind_group</code> member of the <code>Material</code> struct.</p> <p>We're going to add a material parameter to <code>DrawModel</code>.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">pub</span> <span class="token keyword">trait</span> <span class="token type-definition class-name">DrawModel</span><span class="token operator">&lt;</span><span class="token lifetime-annotation symbol">'a</span><span class="token operator">&gt;</span> <span class="token punctuation">{</span>
<span class="token keyword">fn</span> <span class="token function-definition function">draw_mesh</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token keyword">mut</span> <span class="token keyword">self</span><span class="token punctuation">,</span> mesh<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token lifetime-annotation symbol">'a</span> <span class="token class-name">Mesh</span><span class="token punctuation">,</span> material<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token lifetime-annotation symbol">'a</span> <span class="token class-name">Material</span><span class="token punctuation">,</span> camera_bind_group<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token lifetime-annotation symbol">'a</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">BindGroup</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">fn</span> <span class="token function-definition function">draw_mesh_instanced</span><span class="token punctuation">(</span>
<span class="token operator">&amp;</span><span class="token keyword">mut</span> <span class="token keyword">self</span><span class="token punctuation">,</span>
@ -377,7 +377,7 @@ render_pass<span class="token punctuation">.</span><span class="token function">
<span class="token keyword">let</span> mesh <span class="token operator">=</span> <span class="token operator">&amp;</span><span class="token keyword">self</span><span class="token punctuation">.</span>obj_model<span class="token punctuation">.</span>meshes<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> material <span class="token operator">=</span> <span class="token operator">&amp;</span><span class="token keyword">self</span><span class="token punctuation">.</span>obj_model<span class="token punctuation">.</span>materials<span class="token punctuation">[</span>mesh<span class="token punctuation">.</span>material<span class="token punctuation">]</span><span class="token punctuation">;</span>
render_pass<span class="token punctuation">.</span><span class="token function">draw_mesh_instanced</span><span class="token punctuation">(</span>mesh<span class="token punctuation">,</span> material<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>instances<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 operator">&amp;</span><span class="token keyword">self</span><span class="token punctuation">.</span>camera_bind_group<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>With all that in place, we should get the following.</p> <p><img src="/learn-wgpu/assets/img/cubes-correct.2db711eb.png" alt="cubes-correct.png"></p> <h2 id="rendering-the-entire-model"><a href="#rendering-the-entire-model" class="header-anchor">#</a> Rendering the entire model</h2> <p>Right now we are specifying the mesh and the material directly. This is useful if we want to draw a mesh with a different material. We're also not rendering other parts of the model (if we had some). Let's create a method for <code>DrawModel</code> that will draw all the parts of the model with their respective materials.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">pub</span> <span class="token keyword">trait</span> <span class="token type-definition class-name">DrawModel</span><span class="token operator">&lt;</span><span class="token lifetime-annotation symbol">'a</span><span class="token operator">&gt;</span> <span class="token punctuation">{</span>
</code></pre></div><p>With all that in place, we should get the following.</p> <p><img src="/learn-wgpu/assets/img/cubes-correct.2db711eb.png" alt="cubes-correct.png"></p> <h2 id="rendering-the-entire-model"><a href="#rendering-the-entire-model" class="header-anchor">#</a> Rendering the entire model</h2> <p>Right now, we are specifying the mesh and the material directly. This is useful if we want to draw a mesh with a different material. We're also not rendering other parts of the model (if we had some). Let's create a method for <code>DrawModel</code> that will draw all the parts of the model with their respective materials.</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">pub</span> <span class="token keyword">trait</span> <span class="token type-definition class-name">DrawModel</span><span class="token operator">&lt;</span><span class="token lifetime-annotation symbol">'a</span><span class="token operator">&gt;</span> <span class="token punctuation">{</span>
<span class="token comment">// ...</span>
<span class="token keyword">fn</span> <span class="token function-definition function">draw_model</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token keyword">mut</span> <span class="token keyword">self</span><span class="token punctuation">,</span> model<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token lifetime-annotation symbol">'a</span> <span class="token class-name">Model</span><span class="token punctuation">,</span> camera_bind_group<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token lifetime-annotation symbol">'a</span> <span class="token namespace">wgpu<span class="token punctuation">::</span></span><span class="token class-name">BindGroup</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">fn</span> <span class="token function-definition function">draw_model_instanced</span><span class="token punctuation">(</span>
@ -411,7 +411,7 @@ render_pass<span class="token punctuation">.</span><span class="token function">
</code></pre></div><p>The code in <code>lib.rs</code> will change accordingly.</p> <div class="language-rust extra-class"><pre class="language-rust"><code>render_pass<span class="token punctuation">.</span><span class="token function">set_vertex_buffer</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token keyword">self</span><span class="token punctuation">.</span>instance_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_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">draw_model_instanced</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token keyword">self</span><span class="token punctuation">.</span>obj_model<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>instances<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 operator">&amp;</span><span class="token keyword">self</span><span class="token punctuation">.</span>camera_bind_group<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><div id="wasm-example"><!----> <button>Try Tutorial9_models!</button></div> <div class="auto-github-link"><a href="https://github.com/sotrh/learn-wgpu/tree/master/code/beginner/tutorial9-models/" 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:28 AM</span></div></footer> <div class="page-nav"><p class="inner"><span class="prev">
</code></pre></div><div id="wasm-example"><!----> <button>Try Tutorial9_models!</button></div> <div class="auto-github-link"><a href="https://github.com/sotrh/learn-wgpu/tree/master/code/beginner/tutorial9-models/" 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:04:05 AM</span></div></footer> <div class="page-nav"><p class="inner"><span class="prev">
<a href="/learn-wgpu/beginner/tutorial8-depth/" class="prev">
The Depth Buffer
@ -420,6 +420,6 @@ render_pass<span class="token punctuation">.</span><span class="token function">
</a>
</span></p></div> </main></div></div><div class="global-ui"><!----></div></div>
<script src="/learn-wgpu/assets/js/app.a49faced.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/36.e6a8b391.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>
<script src="/learn-wgpu/assets/js/app.99e1547a.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/36.beae0010.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>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

@ -8,11 +8,11 @@
<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.a49faced.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/56.a43d5d8e.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.dd15c417.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.a01d50ae.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.fd4eb8d5.js"><link rel="prefetch" href="/learn-wgpu/assets/js/27.914a9a40.js"><link rel="prefetch" href="/learn-wgpu/assets/js/28.77f7d987.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.c58683af.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.945dce62.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.e6a8b391.js"><link rel="prefetch" href="/learn-wgpu/assets/js/37.5ecf7ce2.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.47515217.js"><link rel="prefetch" href="/learn-wgpu/assets/js/42.4caac867.js"><link rel="prefetch" href="/learn-wgpu/assets/js/43.ac6fc643.js"><link rel="prefetch" href="/learn-wgpu/assets/js/44.27513d85.js"><link rel="prefetch" href="/learn-wgpu/assets/js/45.2ea5b108.js"><link rel="prefetch" href="/learn-wgpu/assets/js/46.e591bcb9.js"><link rel="prefetch" href="/learn-wgpu/assets/js/47.3a7bf317.js"><link rel="prefetch" href="/learn-wgpu/assets/js/48.0a15e622.js"><link rel="prefetch" href="/learn-wgpu/assets/js/49.ad5a99aa.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.48268452.js"><link rel="prefetch" href="/learn-wgpu/assets/js/53.8c976652.js"><link rel="prefetch" href="/learn-wgpu/assets/js/54.daee63ce.js"><link rel="prefetch" href="/learn-wgpu/assets/js/55.3799ddaa.js"><link rel="prefetch" href="/learn-wgpu/assets/js/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.24bfa87e.js"><link rel="prefetch" href="/learn-wgpu/assets/js/63.90f94cac.js"><link rel="prefetch" href="/learn-wgpu/assets/js/64.b9a310af.js"><link rel="prefetch" href="/learn-wgpu/assets/js/65.362df98e.js"><link rel="prefetch" href="/learn-wgpu/assets/js/66.ef1e3716.js"><link rel="prefetch" href="/learn-wgpu/assets/js/67.ab338058.js"><link rel="prefetch" href="/learn-wgpu/assets/js/68.d785413d.js"><link rel="prefetch" href="/learn-wgpu/assets/js/8.2c0d831a.js"><link rel="prefetch" href="/learn-wgpu/assets/js/9.985bc61a.js"><link rel="prefetch" href="/learn-wgpu/assets/js/vendors~docsearch.efa6f8ef.js">
<link rel="preload" href="/learn-wgpu/assets/css/0.styles.81cb5453.css" as="style"><link rel="preload" href="/learn-wgpu/assets/js/app.99e1547a.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/56.e9c45fb7.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.bcec92ff.js"><link rel="prefetch" href="/learn-wgpu/assets/js/27.c755f80e.js"><link rel="prefetch" href="/learn-wgpu/assets/js/28.be489186.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/30.12d50dcb.js"><link rel="prefetch" href="/learn-wgpu/assets/js/31.550259b2.js"><link rel="prefetch" href="/learn-wgpu/assets/js/32.e359d5e0.js"><link rel="prefetch" href="/learn-wgpu/assets/js/33.945dce62.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.beae0010.js"><link rel="prefetch" href="/learn-wgpu/assets/js/37.5ecf7ce2.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.7e2aef8c.js"><link rel="prefetch" href="/learn-wgpu/assets/js/42.6f76d27e.js"><link rel="prefetch" href="/learn-wgpu/assets/js/43.ddac8e2c.js"><link rel="prefetch" href="/learn-wgpu/assets/js/44.1486e9ca.js"><link rel="prefetch" href="/learn-wgpu/assets/js/45.2ea5b108.js"><link rel="prefetch" href="/learn-wgpu/assets/js/46.fbe2131f.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.c0f22e2e.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.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.2dadff38.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.c78dac93.js"><link rel="prefetch" href="/learn-wgpu/assets/js/61.87dce596.js"><link rel="prefetch" href="/learn-wgpu/assets/js/62.fc4967ec.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.0c2a60e3.js"><link rel="prefetch" href="/learn-wgpu/assets/js/66.a136cd48.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"><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="sources"><a href="#sources" class="header-anchor">#</a> Sources</h1> <ul><li>https://www.scratchapixel.com/lessons/3d-basic-rendering/introduction-to-shading/diffuse-lambertian-shading</li> <li>http://jimmiejohnsson84.me/pages/rendering_pbr.html</li></ul></div> <footer class="page-edit"><!----> <div class="last-updated"><span class="prefix">Last Updated: </span> <span class="time">11/28/2023, 12:41:28 AM</span></div></footer> <!----> </main></div></div><div class="global-ui"><!----></div></div>
<script src="/learn-wgpu/assets/js/app.a49faced.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/56.a43d5d8e.js" defer></script>
<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="sources"><a href="#sources" class="header-anchor">#</a> Sources</h1> <ul><li>https://www.scratchapixel.com/lessons/3d-basic-rendering/introduction-to-shading/diffuse-lambertian-shading</li> <li>http://jimmiejohnsson84.me/pages/rendering_pbr.html</li></ul></div> <footer class="page-edit"><!----> <div class="last-updated"><span class="prefix">Last Updated: </span> <span class="time">12/1/2023, 2:04:05 AM</span></div></footer> <!----> </main></div></div><div class="global-ui"><!----></div></div>
<script src="/learn-wgpu/assets/js/app.99e1547a.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/56.e9c45fb7.js" defer></script>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save