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).