Sign in

Tomek Czajecki

@tchayen.com
940 followers 213 following 110 posts

EM @expo.dev working on EAS product infrastructure I blog about my hobbies – a mix of graphics programming and gamedev – see tchayen.com

PostsRepliesMedia
Tomek Czajecki @tchayen.com · 05/05/2025
And this is all it took on the JS side.
/// <reference types="vite/client" />
  
let wasm: {
  exports: {
    version: () => number;
  };
  memory: WebAssembly.Memory;
};

async function loadWasm() {
  const init = (await import("./bin/lib.wasm?init")).default;
  wasm = (await init()) as typeof wasm;
  console.log(wasm.exports.version());
}

loadWasm();

if (import.meta.hot) {
  import.meta.hot.accept("./bin/lib.wasm?init", () => {
    console.log("🔄 WASM rebuilt, re-loading…");
    loadWasm();
  });
}

console.log(new Date());
120
Tomek Czajecki @tchayen.com · 05/05/2025
I have a 'wasm' command declared in package.json which compiles the binary and places it in web/bin. Plugin is listening for changes in zig/ and runs that command. Finally handleHotUpdate() notices that a *.wasm file changed and sends HMR to the browser.
function zigWasmPlugin() {
  const zigDir = path.resolve(__dirname, "zig");

  return {
    name: "zig-wasm-watch",
    configureServer(server) {
      server.watcher.add(zigDir);
      server.watcher.on("change", (file) => {
        console.log(file, "changed");
        if (file.startsWith(zigDir)) {
          exec("npm run wasm", (_err, _stdout, stderr) => {
            console.error(stderr);
          });
        }
      });
    },

    handleHotUpdate({ file, server }) {
      if (file.endsWith(".wasm")) {
        const mods = server.moduleGraph.getModulesByFile(file);
        if (mods && mods.size) {
          return [...mods];
        }
      }
    },
  };
}
110
Tomek Czajecki @tchayen.com · 05/05/2025
I don't know how I survived this long recompiling WASM binary after every change but I finally wrote a mini Vite plugin for HMR. Now when I change anything and save the file, WASM module is automatically compiled and reloaded.
Screenshot of the browser demonstrating HMR reload of the WASM module.
270
Tomek Czajecki @tchayen.com · 21/02/2025
I was working on a WebGPU demo and decided to try how fast I can make it. Zig in WASM generates a buffer with command stream sorted to minimize GPU state changes. This is 10k individual draw calls, unoptimized, no instancing, no render bundles. Every object is controlled separately.
1121
Tomek Czajecki @tchayen.com · 11/02/2025
Asked gemini for WebGPU setup with several cylinder models and orbiting camera. Got interstellar scene (unfortunately had to first spend 15 minutes to fix it).
070
Tomek Czajecki @tchayen.com · 30/12/2024
Small weekend (I lost track of time anyway) project: mesh picking in WebGPU. There's a render pass which draws scene to a r32_unit texture where color of mesh is its ID. Then a compute shader given mouse coordinates writes which color it was to a tiny buffer which is mapped and read back CPU side.
Screenshot of an app showing very simple 3D scene with debug text showing which object is being hovered.Screenshot from RenderDoc showing color picking texture where each mesh is drawn using color corresponding to its ID.
160
Tomek Czajecki @tchayen.com · 13/11/2024
How it feels here after the last month on twitter
Cute young can't with closed eyes and a tail up with a blue butterfly sitting on its nose.
2150
Tomek Czajecki @tchayen.com · 07/11/2024
Accidentally loaded tonemapping LUT as RGBA8 instead of RGB9E5 and made this scene way more artsy than it was supposed to be
The scene is several default blender monkey models on a plane. Bug causes it to have psychodelic/surreal look, dominated by pink, turquoise and mint.
081
Tomek Czajecki @tchayen.com · 11/05/2023
App.js conf starting now
090