<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>TypeGPU | Blog</title><description/><link>https://docs.swmansion.com/</link><language>en</language><item><title>TypeGPU 0.12</title><link>https://docs.swmansion.com/TypeGPU/blog/typegpu-012/</link><guid isPermaLink="true">https://docs.swmansion.com/TypeGPU/blog/typegpu-012/</guid><pubDate>Wed, 12 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Hello fellow GPU enthusiast!&lt;/p&gt;
&lt;p&gt;Over the past 2 months, my team and I have been working on making TypeGPU useful in more places, and making it disappear a little more once your app is ready to ship. TypeGPU resources can now cross React Native runtimes, shaders can be made considerably smaller, and our experimental WebGL backend can run real TypeGPU render pipelines.&lt;/p&gt;
&lt;p&gt;We have also added lower-level command recording APIs, asynchronous pipeline initialization, and a handful of shader code improvements. There is quite a lot to unpack, so let’s get into it!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#new-examples&quot;&gt;New examples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#built-with-typegpu-012&quot;&gt;Built with TypeGPU 0.12&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#migration-guide&quot;&gt;Migration guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#typegpu-on-other-runtimes&quot;&gt;TypeGPU on other runtimes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#more-control-over-gpu-work&quot;&gt;More control over GPU work&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#smaller-production-shaders&quot;&gt;Smaller production shaders&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#shader-code-ergonomics&quot;&gt;Shader code ergonomics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#better-warnings&quot;&gt;Better warnings&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#ecosystem&quot;&gt;Ecosystem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#whats-next&quot;&gt;What’s next?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;h2 id=&quot;new-examples&quot;&gt;New examples&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Our examples page has grown quite a bit since the last release post. There are five new demos that push TypeGPU in very different directions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://typegpu.com/examples/#example=rendering--trippy-raymarching&quot;&gt;“Trippy Raymarching”&lt;/a&gt; - an interactive, twisting tunnel of SDF spheres, complete with enough controls to make it uniquely yours.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://typegpu.com/examples/#example=rendering--os-awards&quot;&gt;“OS Awards”&lt;/a&gt; - an interactive, physically based rendering of our Open Source Awards statuette.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://typegpu.com/examples/#example=image-processing--selfie-segmentation&quot;&gt;“Selfie Segmentation”&lt;/a&gt; - real-time background replacement, with the entire inference and post-processing pipeline running in TypeGPU.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://typegpu.com/examples/#example=rendering--radiance-cascades&quot;&gt;“Radiance Cascades”&lt;/a&gt; - a from-scratch implementation of real-time 2D global illumination.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://typegpu.com/examples/#example=rendering--radiance-cascades-drawing&quot;&gt;“Radiance Cascades (with drawing)”&lt;/a&gt; - paint glowing shapes and watch light propagate through the scene, powered by the new &lt;code dir=&quot;auto&quot;&gt;@typegpu/radiance-cascades&lt;/code&gt; package.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The initial release of &lt;code dir=&quot;auto&quot;&gt;@typegpu/react&lt;/code&gt; also came with three smaller examples showing how TypeGPU resources fit into React components and hooks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://typegpu.com/examples/#example=react--spinning-triangle&quot;&gt;“React: Spinning Triangle”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://typegpu.com/examples/#example=react--shifting-gradient&quot;&gt;“React: Shifting Gradient”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://typegpu.com/examples/#example=react--confetti&quot;&gt;“React: Confetti”&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And there are two new examples showing the progress of our experimental WebGL fallback:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://typegpu.com/examples/#example=simple--triangle-gl&quot;&gt;“Triangle (WebGL fallback)”&lt;/a&gt; - the smallest possible proof that the same TypeGPU pipeline can target something other than WebGPU.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://typegpu.com/examples/#example=rendering--caustics-gl&quot;&gt;“Caustics (WebGL fallback)”&lt;/a&gt; - a more demanding example combining uniforms, matrices, helper functions and &lt;code dir=&quot;auto&quot;&gt;@typegpu/noise&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The second one is particularly exciting. A fallback is only useful if it can render more than a triangle, and the caustics example is a nice first glimpse of where this work is heading.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;built-with-typegpu&quot;&gt;Built with TypeGPU&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Examples are one thing, but this release cycle also brought two complete games powered by TypeGPU 0.12 to the web and app stores.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;bone-tide&quot;&gt;Bone Tide&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;https://reczkok.github.io/typegpu-adventure/beta/&quot;&gt;&lt;img src=&quot;https://docs.swmansion.com/TypeGPU/_astro/bone-tide-screenshot.CeK-ZYKC_1WOAIE.webp&quot; alt=&quot;&amp;#x22;Bone Tide&amp;#x22; Screenshot&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;1285&quot; height=&quot;594&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/reczko_konrad/status/2083514256423575753?s=20&quot;&gt;Bone Tide&lt;/a&gt;, created by my teammate Konrad Reczko &lt;a href=&quot;https://github.com/reczkok&quot;&gt;(@reczkok)&lt;/a&gt;, is now available on the &lt;a href=&quot;https://apps.apple.com/pl/app/bone-tide-horde-survival/id6791994827&quot;&gt;App Store&lt;/a&gt;, &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.swmansion.bonetide&amp;#x26;hl=en&quot;&gt;Google Play&lt;/a&gt; and &lt;a href=&quot;https://reczkok.github.io/typegpu-adventure/beta/&quot;&gt;the web&lt;/a&gt;. It was written from scratch without an existing engine underneath, with both its game logic and shaders written in TypeScript. Its Expo app runs on the exact same TypeGPU engine as the web game, shared one-to-one between platforms, with only the UI ported to React.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;purrkour&quot;&gt;Purrkour&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;https://blazejkustra.github.io/purrkour/&quot;&gt;&lt;img src=&quot;https://docs.swmansion.com/TypeGPU/_astro/purrkour-screenshot.D4e_qQ8J_Zk2hdn.webp&quot; alt=&quot;&amp;#x22;Purrkour&amp;#x22; Screenshot&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;1758&quot; height=&quot;886&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://apps.apple.com/pl/app/purrkour-cat-puzzle-game/id6793995936&quot;&gt;Purrkour&lt;/a&gt; is a cozy puzzle game by Błażej Kustra in which you help cats jump across compact living rooms and find their way into boxes. It is available on the &lt;a href=&quot;https://apps.apple.com/pl/app/purrkour-cat-puzzle-game/id6793995936&quot;&gt;App Store&lt;/a&gt; and &lt;a href=&quot;https://blazejkustra.github.io/purrkour/&quot;&gt;on the web&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Seeing two very different games make the leap from experiments to something anyone can download and play is an exciting milestone for TypeGPU. Congratulations to both creators on their releases!&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;shaders-v3&quot;&gt;Shaders v3&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;https://docs.swmansion.com/TypeGPU/_astro/shaderscom.XLc7VOA2_Z1GR65W.webp&quot; alt=&quot;Shaders.com&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;1920&quot; height=&quot;1080&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://shaders.com/&quot;&gt;Shaders&lt;/a&gt; has launched v3 with an entirely new rendering engine built directly on TypeGPU. According to their &lt;a href=&quot;https://shaders.com/updates/introducing-shaders-v3&quot;&gt;release post&lt;/a&gt;, the new engine helped make production bundles 3× smaller on average and shader compilation up to 25× faster.&lt;/p&gt;
&lt;p&gt;It’s awesome to see TypeGPU being adopted by a tool used to ship WebGPU effects to thousands of production websites. Congratulations to the Shaders team on the release!&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;migration-guide&quot;&gt;Migration guide&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;This release removes a set of APIs that have been deprecated for a while, most notably the old pipeline builder, texture layout descriptors, &lt;code dir=&quot;auto&quot;&gt;.value&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;layout.bound&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We have prepared a detailed &lt;a href=&quot;https://docs.swmansion.com/TypeGPU/migrations/0-12&quot;&gt;Migrating to 0.12&lt;/a&gt; guide with before-and-after snippets for each change.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;typegpu-on-other-runtimes&quot;&gt;TypeGPU on other runtimes&lt;/h2&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;react-native-worklets&quot;&gt;React Native Worklets&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Per-frame work in a React Native app should not have to wait for unrelated work on the RN thread. With &lt;code dir=&quot;auto&quot;&gt;react-native-worklets&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;@typegpu/react&lt;/code&gt; can now run its &lt;code dir=&quot;auto&quot;&gt;useFrame&lt;/code&gt; callbacks on the UI thread.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;useFrame&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&lt;span&gt;{ &lt;/span&gt;&lt;span&gt;elapsedSeconds&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;worklet&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;context&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;ctxRef&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;current&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;context) &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;timeUniform&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;write&lt;/span&gt;&lt;span&gt;(elapsedSeconds);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;pipeline&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;withColorAttachment&lt;/span&gt;&lt;span&gt;({ view: context })&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;draw&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;The tricky part was not moving the callback itself. It was making the resources captured by it usable on another JavaScript runtime. TypeGPU roots, buffers, textures, samplers, bind groups, layouts and pipelines can now be transferred while keeping the same underlying GPU objects and their identity.&lt;/p&gt;
&lt;p&gt;If your app uses React Native, refer to the &lt;a href=&quot;https://docs.swmansion.com/TypeGPU/integration/react-native/worklets/&quot;&gt;React Native Worklets guide&lt;/a&gt; for setup instructions and the rules around transferring resources.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;experimental-webgl-fallback&quot;&gt;Experimental WebGL fallback&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;@typegpu/gl&lt;/code&gt; can generate GLSL and execute a subset of TypeGPU’s render API on WebGL 2. You can try WebGPU first and fall back automatically with one function:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { initWithGLFallback } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;@typegpu/gl&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;root&lt;/span&gt;&lt;span&gt; = await &lt;/span&gt;&lt;span&gt;initWithGLFallback&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;This is still experimental and does not cover compute or the full TypeGPU API, but it can already run non-trivial render pipelines. The same work also lets TypeGPU functions used through &lt;code dir=&quot;auto&quot;&gt;@typegpu/three&lt;/code&gt; follow Three.js onto its WebGL backend.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.swmansion.com/TypeGPU/ecosystem/typegpu-gl/&quot;&gt;Read more about the supported API and manual GLSL generation in the &lt;code dir=&quot;auto&quot;&gt;@typegpu/gl&lt;/code&gt; guide.&lt;/a&gt;&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;more-control-over-gpu-work&quot;&gt;More control over GPU work&lt;/h2&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;command-encoders-and-passes&quot;&gt;Command encoders and passes&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Calling &lt;code dir=&quot;auto&quot;&gt;.draw()&lt;/code&gt; or &lt;code dir=&quot;auto&quot;&gt;.dispatchWorkgroups()&lt;/code&gt; directly remains the simplest way to execute a pipeline. For cases where multiple operations should share one command buffer or render pass, TypeGPU now exposes typed command encoders and passes.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;encoder&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;root[&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;~unstable&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;createCommandEncoder&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;pass&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;encoder&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;beginRenderPass&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;colorAttachments: { view: &lt;/span&gt;&lt;span&gt;context&lt;/span&gt;&lt;span&gt; },&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;scenePipeline&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;with&lt;/span&gt;&lt;span&gt;(pass)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;draw&lt;/span&gt;&lt;span&gt;(sceneVertexCount);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;overlayPipeline&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;with&lt;/span&gt;&lt;span&gt;(pass)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;draw&lt;/span&gt;&lt;span&gt;(overlayVertexCount);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;pass&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;end&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;encoder&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;submit&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;The pass can be used from the pipeline-centric API, as above, or directly through familiar methods like &lt;code dir=&quot;auto&quot;&gt;pass.setPipeline()&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;pass.setBindGroup()&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;pass.draw()&lt;/code&gt;. TypeGPU keeps track of the state shared by both styles and only applies it when necessary.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.swmansion.com/TypeGPU/apis/pipelines/#command-encoders-and-passes&quot;&gt;More about command encoders and passes in the Pipelines guide.&lt;/a&gt;&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;asynchronous-pipeline-initialization&quot;&gt;Asynchronous pipeline initialization&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Pipelines are still initialized lazily on their first draw or dispatch. Larger applications can now move that work away from the first frame by initializing them ahead of time:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Promise&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;all&lt;/span&gt;&lt;span&gt;([&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;simulationPipeline&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;initAsync&lt;/span&gt;&lt;span&gt;(),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;scenePipeline&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;initAsync&lt;/span&gt;&lt;span&gt;(),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;postProcessingPipeline&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;initAsync&lt;/span&gt;&lt;span&gt;(),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;]);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;initAsync()&lt;/code&gt; uses WebGPU’s asynchronous pipeline creation APIs and waits until compilation finishes on the device. There is also &lt;code dir=&quot;auto&quot;&gt;initSync()&lt;/code&gt; if you only want to eagerly perform the regular synchronous initialization.&lt;/p&gt;
&lt;p&gt;For small and medium-sized shaders the difference will usually be negligible, so there is no need to initialize every pipeline manually.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;one-kind-of-buffer-binding&quot;&gt;One kind of buffer binding&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Until now, &lt;code dir=&quot;auto&quot;&gt;root.createUniform(...)&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;buffer.as(&apos;uniform&apos;)&lt;/code&gt; returned two subtly different kinds of objects. In 0.12 they are both buffer bindings, with the same read, write and shader access APIs.&lt;/p&gt;
&lt;p&gt;This also means a shorthand binding can be passed directly to a matching bind group:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;size&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;root&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;createUniform&lt;/span&gt;&lt;span&gt;(d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;vec2u&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;vec2u&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;800&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;600&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;layout&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;tgpu&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;bindGroupLayout&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;size: { uniform: &lt;/span&gt;&lt;span&gt;d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;vec2u&lt;/span&gt;&lt;span&gt; },&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;bindGroup&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;root&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;createBindGroup&lt;/span&gt;&lt;span&gt;(layout&lt;/span&gt;&lt;span&gt;, { &lt;/span&gt;&lt;span&gt;size&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;It is a small distinction to remove, but it makes buffers much easier to move between TypeGPU’s fixed-resource and manual bind group APIs.&lt;/p&gt;
&lt;p&gt;For type annotations, 0.12 also adds &lt;code dir=&quot;auto&quot;&gt;TgpuUniformBuffer&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;TgpuStorageBuffer&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;TgpuVertexBuffer&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;TgpuIndexBuffer&lt;/code&gt;. They replace verbose intersections between &lt;code dir=&quot;auto&quot;&gt;TgpuBuffer&lt;/code&gt; and individual usage flags.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;smaller-production-shaders&quot;&gt;Smaller production shaders&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Minifying JavaScript does not make the WGSL generated at runtime any smaller. TypeGPU 0.12 adds two experimental options aimed specifically at shader code.&lt;/p&gt;
&lt;p&gt;The bundler plugin can shorten identifiers stored in shader metadata:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;typegpu&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;autoNamingEnabled: &lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;unstable_obfuscate: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;The runtime can then remove comments and redundant whitespace from the generated shader:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;root&lt;/span&gt;&lt;span&gt; = await &lt;/span&gt;&lt;span&gt;tgpu&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;init&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;{ unstable_minify: &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;These options can be enabled independently, but together they turn this:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;coneVolume&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;radius&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;f32&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;height&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;f32&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;-&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;f32&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; baseArea &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;141592653589793f &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pow&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;radius&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;2f&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;volume&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; baseArea &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;height&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;3f&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;volume&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;into something closer to this:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;item&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;f32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;f32&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;-&gt;&lt;/span&gt;&lt;span&gt;f32&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;c&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;141592653589793f*&lt;/span&gt;&lt;span&gt;pow&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;2f&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;span&gt;let&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;((&lt;/span&gt;&lt;span&gt;c&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt;3f&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Obfuscated errors are not fun to debug, so we strongly recommend enabling these options only for production builds. &lt;a href=&quot;https://docs.swmansion.com/TypeGPU/advanced/minifying-shaders/&quot;&gt;The Minifying &amp;#x26; Obfuscating Shaders guide&lt;/a&gt; covers the tradeoffs in more detail.&lt;/p&gt;
&lt;p&gt;Alongside this, using the named &lt;code dir=&quot;auto&quot;&gt;tgpu&lt;/code&gt; export, flatter captured externals and an improved package build make it easier for regular JavaScript tree-shaking to remove TypeGPU code your app does not use.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;shader-code-ergonomics&quot;&gt;Shader code ergonomics&lt;/h2&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;a-general-purpose-bitcast&quot;&gt;A general-purpose bitcast&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;The new &lt;code dir=&quot;auto&quot;&gt;std.bitcast&lt;/code&gt; works on the CPU and the GPU, and supports scalars and vectors of equal byte size, including &lt;code dir=&quot;auto&quot;&gt;f16&lt;/code&gt; vectors.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;floatBits&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;std&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;bitcast&lt;/span&gt;&lt;span&gt;(d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;f32&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;u32&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;packedHalfs&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;std&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;bitcast&lt;/span&gt;&lt;span&gt;(d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;vec2h&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;u32&lt;/span&gt;&lt;span&gt;)(d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;vec2h&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0.5&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;The narrower &lt;code dir=&quot;auto&quot;&gt;std.bitcastU32toF32&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;std.bitcastU32toI32&lt;/code&gt; helpers are now deprecated in favor of this API.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;private-properties&quot;&gt;Private properties&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Resources stored in private class properties can now be captured by shader functions. This makes it easier to keep reusable GPU modules properly encapsulated.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Counter&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;#value &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; tgpu&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt;(d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;u32&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;increment&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;use gpu&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; n &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;this&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;#value&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;knowing-where-code-is-used&quot;&gt;Knowing where code is used&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;std.getShaderStage()&lt;/code&gt; returns &lt;code dir=&quot;auto&quot;&gt;&apos;vertex&apos;&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;&apos;fragment&apos;&lt;/code&gt; or &lt;code dir=&quot;auto&quot;&gt;&apos;compute&apos;&lt;/code&gt; during shader generation. A helper can use it to specialize itself for every stage it is called from, in the same spirit as &lt;code dir=&quot;auto&quot;&gt;std.getTargetShaderLanguage()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.swmansion.com/TypeGPU/apis/utils/#resolution-environment&quot;&gt;More about resolution environment helpers in the Utils guide.&lt;/a&gt;&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;better-warnings&quot;&gt;Better warnings&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Warnings now include a category, making it easier to tell a precision loss from a missing WebGPU feature or an internal fallback. Less important warnings are also silenced in production by default.&lt;/p&gt;
&lt;p&gt;If a warning is expected and cannot be addressed at its source, it can be disabled explicitly:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { warn } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;typegpu&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;warn&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;disable&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;implicit-conversion&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Calling &lt;code dir=&quot;auto&quot;&gt;warn.reset()&lt;/code&gt; restores the defaults. Silencing a warning should remain the last resort, but now there is a precise escape hatch when you need one.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;ecosystem&quot;&gt;Ecosystem&lt;/h2&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;typegpu-for-react&quot;&gt;TypeGPU for React&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;@typegpu/react&lt;/code&gt; brings TypeGPU resources into the React lifecycle, on both the web and React Native. Hooks such as &lt;code dir=&quot;auto&quot;&gt;useRoot&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;useUniform&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;useBindGroup&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;useConfigureContext&lt;/code&gt; take care of creating resources, sharing them between components and cleaning them up, while &lt;code dir=&quot;auto&quot;&gt;useFrame&lt;/code&gt; provides a natural place to update and draw every frame.&lt;/p&gt;
&lt;p&gt;Values can stay on the GPU and be updated imperatively, or follow React state through &lt;code dir=&quot;auto&quot;&gt;useMirroredUniform&lt;/code&gt;. The package also integrates with Suspense while the root is being initialized, so loading and unsupported-device states fit into the rest of your component tree.&lt;/p&gt;
&lt;p&gt;The three React examples mentioned above are a good place to see these pieces working together. For a guided introduction and the complete hook reference, head over to the &lt;a href=&quot;https://docs.swmansion.com/TypeGPU/ecosystem/typegpu-react/&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;@typegpu/react&lt;/code&gt; guide&lt;/a&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;2d-global-illumination-with-typegpuradiance-cascades&quot;&gt;2D global illumination with @typegpu/radiance-cascades&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;@typegpu/radiance-cascades&lt;/code&gt; packages a TypeGPU implementation of the Radiance Cascades technique for real-time 2D global illumination. You provide shader callbacks that describe the scene’s signed distance field and surface colors; the package owns the cascade textures and dispatches the compute passes needed to produce a radiance field.&lt;/p&gt;
&lt;p&gt;It pairs particularly well with &lt;code dir=&quot;auto&quot;&gt;@typegpu/sdf&lt;/code&gt;: draw a scene into a texture, turn it into a signed distance field with jump flooding, and feed the result into the radiance runner. That is exactly how the interactive &lt;a href=&quot;https://typegpu.com/examples/#example=rendering--radiance-cascades-drawing&quot;&gt;“Radiance Cascades (with drawing)”&lt;/a&gt; demo lets light react immediately to every brush stroke.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://docs.swmansion.com/TypeGPU/ecosystem/typegpu-radiance-cascades/&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;@typegpu/radiance-cascades&lt;/code&gt; guide&lt;/a&gt; covers the basic setup, generated SDF textures, custom ray marching and output configuration.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;better-pseudo-random-numbers-in-typegpunoise&quot;&gt;Better pseudo-random numbers in @typegpu/noise&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;@typegpu/noise&lt;/code&gt; now uses &lt;code dir=&quot;auto&quot;&gt;Xoroshiro64**&lt;/code&gt; as its default pseudo-random number generator. It has a 64-bit state, works on both the CPU and GPU, and produces substantially better distributions than the previous default.&lt;/p&gt;
&lt;p&gt;The package also exports the generator as &lt;code dir=&quot;auto&quot;&gt;XOROSHIRO64STARSTAR&lt;/code&gt;, a new &lt;code dir=&quot;auto&quot;&gt;LCG32&lt;/code&gt; implementation, and utilities for hashing and scrambling seeds. If your app depends on the exact sequence produced by the old generator, the &lt;a href=&quot;https://docs.swmansion.com/TypeGPU/migrations/0-12/#new-pseudo-random-number-generator-in-typegpunoise&quot;&gt;migration guide&lt;/a&gt; includes a compatible implementation.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;whats-next&quot;&gt;What’s next?&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;There are many more things introduced in TypeGPU 0.12 that I haven’t mentioned. If you’re curious about the full list of changes made in TypeGPU 0.12, you can
read &lt;a href=&quot;https://github.com/software-mansion/TypeGPU/compare/v0.11.9...v0.12.0&quot;&gt;the full 0.12.0 diff&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>Release notes</category></item><item><title>TypeGPU 0.11</title><link>https://docs.swmansion.com/TypeGPU/blog/typegpu-011/</link><guid isPermaLink="true">https://docs.swmansion.com/TypeGPU/blog/typegpu-011/</guid><pubDate>Tue, 14 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Hello fellow GPU enthusiast!&lt;/p&gt;
&lt;p&gt;Over the past 2 months, my team and I have been pulling on a few threads that we thought would improve TypeGPU in terms of efficiency, and as a byproduct, we actually made the APIs more convenient. We are also introducing a &lt;em&gt;lint plugin&lt;/em&gt; to further improve the diagnostics and feedback you receive while writing TypeGPU shaders, on top of the type safety we already provide.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#new-examples&quot;&gt;New examples&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#migration-guide&quot;&gt;Migration guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#new-and-improved-write-apis&quot;&gt;New and improved write APIs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#shader-code-ergonomics&quot;&gt;Shader code ergonomics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#ecosystem-updates&quot;&gt;Ecosystem updates&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#whats-next&quot;&gt;What’s next?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We have been pulling a few more threads than I mentioned here… but for those, you’ll have to wait for the next blog post 🤐.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;new-examples&quot;&gt;New examples&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;My teammate Konrad Reczko &lt;a href=&quot;https://github.com/reczkok&quot;&gt;(@reczkok)&lt;/a&gt; has outdone himself again, and delivered 3 new examples that push TypeGPU APIs to their limits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://typegpu.com/examples/#example=algorithms--genetic-racing&quot;&gt;“Genetic Racing”&lt;/a&gt; - watch a swarm of cars learn to traverse a procedurally generated race track.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://typegpu.com/examples/#example=simple--mesh-skinning&quot;&gt;“Mesh Skinning”&lt;/a&gt; - an animation and skinning system built from scratch in TypeGPU.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://typegpu.com/examples/#example=rendering--pom&quot;&gt;“Parallax Occlusion Mapping”&lt;/a&gt; - squeezing amazing depth out of just two triangles and a set of textures.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;h2 id=&quot;migration-guide&quot;&gt;Migration guide&lt;/h2&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;deprecated-apis&quot;&gt;Deprecated APIs&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code dir=&quot;auto&quot;&gt;buffer.writePartial&lt;/code&gt; API is being deprecated in favor of &lt;code dir=&quot;auto&quot;&gt;buffer.patch&lt;/code&gt; &lt;a href=&quot;#a-better-partial-write&quot;&gt;(and here are the reasons why)&lt;/a&gt;.
To migrate, simply replace any partial write of arrays in the form of &lt;code dir=&quot;auto&quot;&gt;[{ idx: 2, value: foo }, /* ... */]&lt;/code&gt; with &lt;code dir=&quot;auto&quot;&gt;{ 2: foo, /* ... */ }&lt;/code&gt;.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;buffer&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;root&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;createBuffer&lt;/span&gt;&lt;span&gt;(d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;arrayOf&lt;/span&gt;&lt;span&gt;(d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;vec3f&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;$usage&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;storage&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;buffer&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;writePartial&lt;/span&gt;&lt;span&gt;([{ idx: &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;, value: d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;vec3f&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;) }]);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;buffer&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;patch&lt;/span&gt;&lt;span&gt;({ &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;: d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;vec3f&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;) });&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;stabilizing-textures-and-samplers&quot;&gt;Stabilizing textures and samplers&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;One by one, we’re making our APIs available without the &lt;code dir=&quot;auto&quot;&gt;[&apos;~unstable&apos;]&lt;/code&gt; prefix, and this time around, it’s &lt;strong&gt;textures&lt;/strong&gt; and &lt;strong&gt;samplers&lt;/strong&gt;.
Just drop the unstable prefix, and you’re good to go.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;sampler&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;root[&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;~unstable&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;createSampler&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;const &lt;/span&gt;&lt;span&gt;sampler&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;root&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;createSampler&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;magFilter: &lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;linear&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;minFilter: &lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;linear&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;const &lt;/span&gt;&lt;span&gt;texture&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;root[&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;~unstable&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;createTexture&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;const &lt;/span&gt;&lt;span&gt;texture&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;root&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;createTexture&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;size:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;256&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;256&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;format: &lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;rgba8unorm&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt; as const,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;$usage&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;sampled&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h2 id=&quot;new-and-improved-write-apis&quot;&gt;New and improved write APIs&lt;/h2&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;efficient-data&quot;&gt;Efficient data&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;When writing to a buffer with an array of vectors, it’s no longer required to create vector instances (e.g. &lt;code dir=&quot;auto&quot;&gt;d.vec3f()&lt;/code&gt;).&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;positionsMutable&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;root&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;createMutable&lt;/span&gt;&lt;span&gt;(d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;arrayOf&lt;/span&gt;&lt;span&gt;(d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;vec3f&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// existing overload&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;positionsMutable&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;write&lt;/span&gt;&lt;span&gt;([d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;vec3f&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;), d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;vec3f&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt;), d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;vec3f&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;6&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;7&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;8&lt;/span&gt;&lt;span&gt;)]);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// new overloads ⚡&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;positionsMutable&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;write&lt;/span&gt;&lt;span&gt;([[&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;], [&lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt;], [&lt;/span&gt;&lt;span&gt;6&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;7&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;8&lt;/span&gt;&lt;span&gt;]]); &lt;/span&gt;&lt;span&gt;// tuples&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;positionsMutable&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;write&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Float32Array&lt;/span&gt;&lt;span&gt;([&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;6&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;7&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;8&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;])); &lt;/span&gt;&lt;span&gt;// typed arrays (mind the padding)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// and more...&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Each one is more efficient than the previous, so you can choose the appropriate API for your efficiency needs.
&lt;a href=&quot;https://docs.swmansion.com/TypeGPU/apis/buffers/#writing-to-a-buffer&quot;&gt;More about these new APIs here&lt;/a&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;a-better-partial-write&quot;&gt;A better partial write&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;When writing to a buffer, we require the passed in value to exactly match the schema. This specifically means that updating a single field of a single array item was very costly. The &lt;code dir=&quot;auto&quot;&gt;buffer.writePartial&lt;/code&gt; API remedied that by accepting partial records
for structs, and a list of indices and values to update in arrays. This works fine, but doesn’t compose well with more complex data structures:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;Node&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;struct&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;color: &lt;/span&gt;&lt;span&gt;d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;vec3f&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// Indices of neighboring nodes&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;neighbors: &lt;/span&gt;&lt;span&gt;d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;arrayOf&lt;/span&gt;&lt;span&gt;(d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;u32&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;nodes&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;root&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;createUniform&lt;/span&gt;&lt;span&gt;(d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;arrayOf&lt;/span&gt;&lt;span&gt;(Node&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;100&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Updating the 50th node&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;nodes&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;writePartial&lt;/span&gt;&lt;span&gt;([&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;idx: &lt;/span&gt;&lt;span&gt;50&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;value: {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;color: d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;vec3f&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;// We cannot pass [48, 49, 51, 52], as we could with nodes.write()&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;neighbors: [{ idx: &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, value: &lt;/span&gt;&lt;span&gt;48&lt;/span&gt;&lt;span&gt; }, { idx: &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;, value: &lt;/span&gt;&lt;span&gt;49&lt;/span&gt;&lt;span&gt; }, { idx: &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;, value: &lt;/span&gt;&lt;span&gt;51&lt;/span&gt;&lt;span&gt; }, { idx: &lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;, value: &lt;/span&gt;&lt;span&gt;52&lt;/span&gt;&lt;span&gt; }],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;]);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;If we loosened the type to accept either partial arrays or full arrays, then we would reach an ambiguity in the following case:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;Foo&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;struct&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;idx: &lt;/span&gt;&lt;span&gt;d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;u32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;value: &lt;/span&gt;&lt;span&gt;d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;f32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;foos&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;root&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;createUniform&lt;/span&gt;&lt;span&gt;(d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;arrayOf&lt;/span&gt;&lt;span&gt;(Foo&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;foos&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;writePartial&lt;/span&gt;&lt;span&gt;([{ idx: &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;, value: &lt;/span&gt;&lt;span&gt;/* ... */&lt;/span&gt;&lt;span&gt; }, { idx: &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, value: &lt;/span&gt;&lt;span&gt;/* ... */&lt;/span&gt;&lt;span&gt; }]);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;We could traverse the value deeper to disambiguate, but for the sake of efficiency and being able to reuse optimizations added to &lt;code dir=&quot;auto&quot;&gt;buffer.write&lt;/code&gt; by &lt;a href=&quot;https://github.com/reczkok&quot;&gt;Konrad&lt;/a&gt;, we chose to add a new API:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;foos&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;writePartial&lt;/span&gt;&lt;span&gt;([{ idx: &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;, value: &lt;/span&gt;&lt;span&gt;/* ... */&lt;/span&gt;&lt;span&gt; }, { idx: &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, value: &lt;/span&gt;&lt;span&gt;/* ... */&lt;/span&gt;&lt;span&gt; }]);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;foos&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;patch&lt;/span&gt;&lt;span&gt;({ &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;/* ... */&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;/* ... */&lt;/span&gt;&lt;span&gt; });&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.swmansion.com/TypeGPU/apis/buffers/#patching-buffers&quot;&gt;You can read more about .patch in the Buffers guide&lt;/a&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;writing-struct-of-arrays-soa-data&quot;&gt;Writing struct-of-arrays (SoA) data&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;When the buffer schema is an &lt;code dir=&quot;auto&quot;&gt;array&amp;#x3C;struct&amp;#x3C;...&gt;&gt;&lt;/code&gt;, you can write the data in a struct-of-arrays form with &lt;code dir=&quot;auto&quot;&gt;writeSoA&lt;/code&gt; from &lt;code dir=&quot;auto&quot;&gt;typegpu/common&lt;/code&gt;. This is useful when your CPU-side data is already stored per-field, such as simulation attributes kept in separate typed arrays.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;Particle&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;struct&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;pos: &lt;/span&gt;&lt;span&gt;d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;vec3f&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;vel: &lt;/span&gt;&lt;span&gt;d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;f32&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;particleBuffer&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;root&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;createBuffer&lt;/span&gt;&lt;span&gt;(d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;arrayOf&lt;/span&gt;&lt;span&gt;(Particle&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;common&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;writeSoA&lt;/span&gt;&lt;span&gt;(particleBuffer, {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;pos: &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Float32Array&lt;/span&gt;&lt;span&gt;([&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;6&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;]),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;vel: &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Float32Array&lt;/span&gt;&lt;span&gt;([&lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;20&lt;/span&gt;&lt;span&gt;]),&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.swmansion.com/TypeGPU/apis/buffers/#writing-struct-of-arrays-soa-data&quot;&gt;More about this API can be found in the Buffers guide.&lt;/a&gt;&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;shader-code-ergonomics&quot;&gt;Shader code ergonomics&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;There have been a lot of improvements to our shader generation, mainly regarding comptime execution and pruning of unreachable branches.
I will highlight some of them in the following sections.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;stdrange&quot;&gt;std.range&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;The new &lt;code dir=&quot;auto&quot;&gt;std.range&lt;/code&gt; function works similarly to &lt;code dir=&quot;auto&quot;&gt;range()&lt;/code&gt; in Python, and returns an array that can be iterated over.
When combined with &lt;code dir=&quot;auto&quot;&gt;tgpu.unroll&lt;/code&gt;, it’s now very easy to produce a set amount of code blocks.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;let &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;u32&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;of&lt;/span&gt;&lt;span&gt; tgpu&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;unroll&lt;/span&gt;&lt;span&gt;(std&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;range&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;))) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// this block will be inlined 3 times&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;result &lt;/span&gt;&lt;span&gt;+=&lt;/span&gt;&lt;span&gt; i &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Generates:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;var&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0u&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// unrolled iteration #0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0u&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// unrolled iteration #1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;10u&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// unrolled iteration #2&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;result&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;20u&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Because &lt;code dir=&quot;auto&quot;&gt;i&lt;/code&gt; is known at comptime, the &lt;code dir=&quot;auto&quot;&gt;i * 10&lt;/code&gt; is evaluated and injected into the generated code in each block.
For more, refer to &lt;a href=&quot;https://docs.swmansion.com/TypeGPU/apis/utils/#tgpuunroll&quot;&gt;tgpu.unroll documentation.&lt;/a&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;boolean-logic&quot;&gt;Boolean logic&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Logical expressions are now short-circuited if we can determine the result early.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;clampingEnabled&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;tgpu&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;accessor&lt;/span&gt;&lt;span&gt;(d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;bool&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;interpolate&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;t&lt;/span&gt;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;use gpu&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;let &lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt; + &lt;/span&gt;&lt;span&gt;(b&lt;/span&gt;&lt;span&gt; - &lt;/span&gt;&lt;span&gt;a)&lt;/span&gt;&lt;span&gt; * &lt;/span&gt;&lt;span&gt;t;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (clampingEnabled&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span&gt; value &lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// Constantly increasing, without ever going past 2&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;value &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; (value &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt; value;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; value;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Generated WGSL depending on the value of &lt;code dir=&quot;auto&quot;&gt;clampingEnabled&lt;/code&gt;:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// clampingEnabled.$ === false&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;interpolate&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;f32&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;f32&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;t&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;f32&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;-&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;f32&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;var&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;t&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// clampingEnabled.$ === true&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;interpolate&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;f32&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;f32&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;t&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;f32&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;-&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;f32&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;var&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;t&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt; &gt; &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;convenience-overload-for-tgpuconst-api&quot;&gt;Convenience overload for &lt;code dir=&quot;auto&quot;&gt;tgpu.const&lt;/code&gt; API&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;If you’re defining a WGSL constant using an array schema, you no longer have to duplicate the array length both in the value and in the schema.
The &lt;code dir=&quot;auto&quot;&gt;tgpu.const&lt;/code&gt; function now accepts dynamically-sized schemas.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;ColorStops&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;arrayOf&lt;/span&gt;&lt;span&gt;(d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;vec3f&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;colorStops&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;tgpu&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;ColorStops&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;ColorStops&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;[d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;vec3f&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;), d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;vec3f&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;), d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;vec3f&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;)]&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h2 id=&quot;ecosystem-updates&quot;&gt;Ecosystem updates&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;There has been a lot of work outside of the &lt;code dir=&quot;auto&quot;&gt;typegpu&lt;/code&gt; package, both internally and from the community.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;lint-plugin&quot;&gt;Lint plugin&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Aleksander Katan (&lt;a href=&quot;https://github.com/aleksanderkatan&quot;&gt;@aleksanderkatan&lt;/a&gt;) has been working behind the scenes on an ESLint/Oxlint plugin, capable of catching user errors that types cannot.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { tgpu, d } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;typegpu&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;increment&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;use gpu&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; n&lt;/span&gt;&lt;span&gt;++&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;//     ^^^&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// Cannot assign to &apos;n&apos; since WGSL parameters are immutable.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// If you&apos;re using d.ref, please either use &apos;.$&apos; or disable this rule&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;createBoid&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;use gpu&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;boid&lt;/span&gt;&lt;span&gt; = { pos: &lt;/span&gt;&lt;span&gt;d&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;vec2f&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; size: &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;//           ^^^^^^^^^^^^^^^^^^^^^^^^^^^&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// { pos: d.vec2f(), size: 1 } must be wrapped in a schema call&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; boid;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;clampTo0&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;use gpu&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;let &lt;/span&gt;&lt;span&gt;result;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;//  ^^^^^^&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// &apos;result&apos; must have an initial value&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (n &lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;result &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;else&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;result &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; n;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; result;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.swmansion.com/TypeGPU/tooling/eslint-plugin-typegpu/&quot;&gt;For setup instructions and available rules, refer to the documentation&lt;/a&gt;&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;new-typegpucolor-helpers&quot;&gt;New @typegpu/color helpers&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;There are three new helper functions importable from &lt;code dir=&quot;auto&quot;&gt;@typegpu/color&lt;/code&gt; which can be called at comptime to create
color vectors from hexadecimal strings: &lt;code dir=&quot;auto&quot;&gt;hexToRgb&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;hexToRgba&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;hexToOklab&lt;/code&gt;.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { hexToRgb } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;@typegpu/color&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;function&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getGradientColor&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;t&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;number&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;use gpu&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;hexToRgb&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;#FF00FF&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const &lt;/span&gt;&lt;span&gt;to&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;hexToRgb&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;#00FF00&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; std&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;mix&lt;/span&gt;&lt;span&gt;(from&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; to&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; t);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Generated WGSL:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;getGradientColor&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;t&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;f32&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;-&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;vec3f&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;var&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;vec3f&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;var&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;to&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;vec3f&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;mix&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;to&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;t&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;bundler-plugin-rewrite&quot;&gt;Bundler plugin rewrite&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code dir=&quot;auto&quot;&gt;unplugin-typegpu&lt;/code&gt; package is what enables TypeScript shaders, and to support its continued development, we rewrote it from
the ground up. It should now support more bundlers than ever before, out of the box, including &lt;code dir=&quot;auto&quot;&gt;esbuild&lt;/code&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;motion-gpu&quot;&gt;Motion GPU&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;A minimalist WebGPU framework called &lt;a href=&quot;https://motion-gpu.dev/&quot;&gt;Motion GPU&lt;/a&gt; introduced a way to integrate with TypeGPU, and wrote about it
in their documentation &lt;a href=&quot;https://motion-gpu.dev/docs/integrations-typegpu&quot;&gt;(Integrations / TypeGPU)&lt;/a&gt;. It’s awesome to see the continued adoption
of TypeGPU in other ecosystems and communities 🎉&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;whats-next&quot;&gt;What’s next?&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;There are many more things introduced in TypeGPU 0.11 that I haven’t mentioned. If you’re curious, you can
read &lt;a href=&quot;https://github.com/software-mansion/TypeGPU/compare/v0.10.2...v0.11.0&quot;&gt;the full 0.11.0 changelog&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>Release notes</category></item><item><title>How to enable WebGPU on your device</title><link>https://docs.swmansion.com/TypeGPU/blog/troubleshooting/</link><guid isPermaLink="true">https://docs.swmansion.com/TypeGPU/blog/troubleshooting/</guid><description>Since WebGPU is still considered experimental, despite being supported by many browsers, it is often hidden behind flags. This post will help you find out if your browser supports WebGPU and help you enable it if needed.

</description><pubDate>Fri, 04 Oct 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Since WebGPU is still considered experimental, despite being supported by many
browsers, it is often hidden behind flags. This post will help you find out if
your browser secretly supports WebGPU and, if it does, how you can enable it. In
general, you can check if your browser supports WebGPU by visiting
&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API#browser_compatibility&quot;&gt;the WebGPU API doccumentation&lt;/a&gt;
and looking for your browser in the list. If it is listed under &lt;code dir=&quot;auto&quot;&gt;full support&lt;/code&gt;
it should generally work out of the box (on the listed operating systems). There
are some cases where it is more complicated and requires some manual
configuration. This post will guide you through the process of enabling WebGPU
on your devices.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;safari-on-ios&quot;&gt;Safari on iOS&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Despite what the
&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API#browser_compatibility&quot;&gt;docs&lt;/a&gt;
tell us, there is a way to enable WebGPU in Safari on iOS.&lt;/p&gt;
&lt;p&gt;To enable WebGPU go to:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Settings &gt; Apps &gt; Safari &gt; Advanced &gt; Feature Flags&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;or for iOS versions lower than 18:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Settings &gt; Safari &gt; Advanced &gt; Feature Flags&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Then enable WebGPU and restart Safari.&lt;/p&gt;
&lt;p&gt;That’s it! After enabling the WebGPU flag you can go to
&lt;a href=&quot;https://docs.swmansion.com/TypeGPU/examples/&quot;&gt;our examples page&lt;/a&gt; and you should
be able to tinker with them on your phone.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;safari-on-macos&quot;&gt;Safari on macOS&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Go to:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Settings &gt; Advanced&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;And check the &lt;code dir=&quot;auto&quot;&gt;Show features for web developers&lt;/code&gt; checkbox. After that, you can
go to:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Settings &gt; Feature Flags&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;And search for the WebGPU checkbox. Enable it and you should be good to go!&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;deno&quot;&gt;Deno&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;If you are running Deno 1.39 or newer you can either:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Run your script with the &lt;code dir=&quot;auto&quot;&gt;--unstable-webgpu&lt;/code&gt; flag&lt;/li&gt;
&lt;li&gt;Add the following line to your &lt;code dir=&quot;auto&quot;&gt;deno.json&lt;/code&gt; file:&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;unstable&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;: [&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;webgpu&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h2 id=&quot;chrome-for-android-and-desktop&quot;&gt;Chrome for Android and desktop&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;WebGPU for Google Chrome should work by default on Android and desktop devices,
just make sure you run the newest available version of the app. If however it
does not work, you might need to try enabling some experimental flags listed in
the official
&lt;a href=&quot;https://developer.chrome.com/docs/web-platform/webgpu/troubleshooting-tips&quot;&gt;Chrome developer documentation&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>Safari</category><category>iPhone</category><category>Chrome</category><category>Troubleshooting</category><category>macOS</category><category>WebGPU support</category><category>Deno</category></item></channel></rss>