Graphics, Games and Multimedia

34.1 Canvas and Pixel Manipulation

// Rust: render into linear memory, then blit to a canvas via ImageData
#[wasm_bindgen]
pub fn render(width: u32, height: u32, t: f64) -> Vec<u8> {
    let mut buf = vec![0u8; (width * height * 4) as usize];
    for y in 0..height {
        for x in 0..width {
            let i = ((y * width + x) * 4) as usize;
            buf[i] = ((x as f64 + t).sin() * 127.0 + 128.0) as u8;
            buf[i + 1] = ((y as f64 * 0.05 + t).cos() * 127.0 + 128.0) as u8;
            buf[i + 2] = 200;
            buf[i + 3] = 255;
        }
    }
    buf
}
const pixels = render(w, h, performance.now() / 1000);
ctx.putImageData(new ImageData(new Uint8ClampedArray(pixels.buffer), w, h), 0, 0);
// Faster: keep a persistent buffer in Wasm memory and view it without copying.

34.2 WebGL and WebGPU

Emscripten: OpenGL ES 2/3 → WebGL 1/2 (-sUSE_WEBGL2, -sFULL_ES3). WebGPU via emdawnwebgpu/Dawn (webgpu.h).

Rust: wgpu (WebGPU API; runs on WebGPU/WebGL in browsers and Vulkan/Metal/DX12 natively), glow, web-sys WebGL bindings.

Game engines and frameworks:

Unity (WebGL/WebGPU build targets compile IL2CPP → Wasm) Godot 4 web export Bevy (Rust ECS, wasm32 target)

macroquad, raylib (via Emscripten), SDL2/3 Defold, Unreal (the HTML5 export is community-maintained)

34.3 Audio and Video

AudioWorklet + Wasm DSP for low-latency audio (synths, effects), with SharedArrayBuffer ring buffers between threads.

Codecs: ffmpeg.wasm (transcoding in the browser), libvpx/libaom/dav1d ports, image codecs (Squoosh: MozJPEG, WebP, AVIF, OxiPNG, JPEG XL), WebCodecs (native browser codecs, combined with Wasm for processing).

Emulators: DOSBox (js-dos), MAME, RetroArch, v86 (an x86 emulator running Linux in the browser).